ETH Price: $3,257.34 (+2.26%)
Gas: 1 Gwei

Token

Drewbearbear (drewbearbear)
 

Overview

Max Total Supply

4,779 drewbearbear

Holders

256

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 drewbearbear
0x3a4002a31d3cb8a9b08cf6a930bb89aba93a69d0
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Drewbearbear

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-06-15
*/

// File: operator-filter-registry/src/lib/Constants.sol


pragma solidity ^0.8.13;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

// File: operator-filter-registry/src/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

// File: operator-filter-registry/src/OperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 *         Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract OperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);

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

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if an operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File: operator-filter-registry/src/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 * @dev    Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {}
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.9.0) (access/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() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

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

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

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

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

// File: @openzeppelin/contracts/utils/math/SignedMath.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;



/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

// File: contracts/IERC721A.sol


// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

pragma solidity ^0.8.13;

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

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

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

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

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

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

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

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

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

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

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

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

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

    // ==============================
    //            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);

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

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

pragma solidity ^0.8.13;


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

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Mask of an entry in packed address data.
    uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

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

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

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

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

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

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant BITMASK_BURNED = 1 << 224;
    
    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITPOS_NEXT_INITIALIZED = 225;

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

    // The tokenId of the next token to be minted.
    uint256 private _currentIndex;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes of the XOR of
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (_addressToUint256(owner) == 0) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
    }

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

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

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

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

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

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
        ownership.burned = packed & BITMASK_BURNED != 0;
    }

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @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) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

    /**
     * @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 Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = address(uint160(_packedOwnershipOf(tokenId)));
        if (to == owner) revert ApprovalToCurrentOwner();

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

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

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), 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 {
        _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 {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @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`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

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

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

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

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

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

        address approvedAddress = _tokenApprovals[tokenId];

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            approvedAddress == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (_addressToUint256(to) == 0) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

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

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));
        address approvedAddress = _tokenApprovals[tokenId];

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                approvedAddress == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

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

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED | 
                BITMASK_NEXT_INITIALIZED;

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

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

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

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

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

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function _toString(uint256 value) internal pure returns (string memory ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), 
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length, 
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

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

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for { 
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp { 
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } { // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }
            
            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}
// File: contracts/Drewbearbear.sol


pragma solidity ^0.8.20;





contract Drewbearbear is ERC721A, Ownable, DefaultOperatorFilterer {
    using Strings for uint256;

    uint256 public constant MAX_SUPPLY = 8888;
    uint256 public constant MAX_MINT_AMOUNT = 25;

    string public baseURI;
    uint256 public price;
    bool public isMintStart;

    event PublicMint(address indexed owner, uint256 amount);

    constructor(
        string memory _baseUri
    ) ERC721A("Drewbearbear", "drewbearbear") {
        setBaseURI(_baseUri);
        setPrice(0.006 ether);
    }

    /**
     * @notice token start from id 1
     */
    function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }

    /**
     * @notice public mint
     */
    function publicMint(uint quantity) external payable {
        require(msg.sender == tx.origin, "Contract minting is not allowed");
        require(isMintStart, "Mint is not active");
        require(quantity <= MAX_MINT_AMOUNT, "Mint would exceed max amount per mint");
        require((_totalMinted() + quantity) <= MAX_SUPPLY, "Mint would exceed max supply");
        require(msg.value >= (quantity * price), "ETH value sent is not correct");

        _mint(_msgSender(), quantity);

        emit PublicMint(_msgSender(), quantity);
    }

    /**
     * @notice set mint start
     */
    function setMintStart(bool _isStart) public onlyOwner {
        isMintStart = _isStart;
    }

    /**
     * @notice set base uri
     */
    function setBaseURI(string memory _uri) public onlyOwner {
        baseURI = _uri;
    }

    /**
     * @notice set price
     */
    function setPrice(uint256 _price) public onlyOwner {
        price = _price;
    }

     /**
     * @notice token URI
     */
    function tokenURI(uint256 _tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");

        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _tokenId.toString())) : '';
    }

    /**
     * @notice transfer funds
     */
    function withdrawal() external onlyOwner {
        uint256 balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_baseUri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PublicMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_MINT_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintStart","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","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":"_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isStart","type":"bool"}],"name":"setMintStart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","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":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801562000010575f80fd5b5060405162003b3e38038062003b3e833981810160405281019062000036919062000679565b733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600c81526020017f44726577626561726265617200000000000000000000000000000000000000008152506040518060400160405280600c81526020017f64726577626561726265617200000000000000000000000000000000000000008152508160029081620000ca9190620008ff565b508060039081620000dc9190620008ff565b50620000ed6200032a60201b60201c565b5f81905550505062000114620001086200033260201b60201c565b6200033960201b60201c565b5f6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620002f8578015620001c9576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200019492919062000a26565b5f604051808303815f87803b158015620001ac575f80fd5b505af1158015620001bf573d5f803e3d5ffd5b50505050620002f7565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200027d576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200024892919062000a26565b5f604051808303815f87803b15801562000260575f80fd5b505af115801562000273573d5f803e3d5ffd5b50505050620002f6565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002c6919062000a51565b5f604051808303815f87803b158015620002de575f80fd5b505af1158015620002f1573d5f803e3d5ffd5b505050505b5b5b50506200030b81620003fc60201b60201c565b62000323661550f7dca700006200042160201b60201c565b5062000aea565b5f6001905090565b5f33905090565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6200040c6200043b60201b60201c565b80600990816200041d9190620008ff565b5050565b620004316200043b60201b60201c565b80600a8190555050565b6200044b6200033260201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1662000471620004cc60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620004ca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004c19062000aca565b60405180910390fd5b565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b62000555826200050d565b810181811067ffffffffffffffff821117156200057757620005766200051d565b5b80604052505050565b5f6200058b620004f4565b90506200059982826200054a565b919050565b5f67ffffffffffffffff821115620005bb57620005ba6200051d565b5b620005c6826200050d565b9050602081019050919050565b5f5b83811015620005f2578082015181840152602081019050620005d5565b5f8484015250505050565b5f620006136200060d846200059e565b62000580565b90508281526020810184848401111562000632576200063162000509565b5b6200063f848285620005d3565b509392505050565b5f82601f8301126200065e576200065d62000505565b5b815162000670848260208601620005fd565b91505092915050565b5f60208284031215620006915762000690620004fd565b5b5f82015167ffffffffffffffff811115620006b157620006b062000501565b5b620006bf8482850162000647565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200071757607f821691505b6020821081036200072d576200072c620006d2565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620007917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000754565b6200079d868362000754565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620007e7620007e1620007db84620007b5565b620007be565b620007b5565b9050919050565b5f819050919050565b6200080283620007c7565b6200081a6200081182620007ee565b84845462000760565b825550505050565b5f90565b6200083062000822565b6200083d818484620007f7565b505050565b5b818110156200086457620008585f8262000826565b60018101905062000843565b5050565b601f821115620008b3576200087d8162000733565b620008888462000745565b8101602085101562000898578190505b620008b0620008a78562000745565b83018262000842565b50505b505050565b5f82821c905092915050565b5f620008d55f1984600802620008b8565b1980831691505092915050565b5f620008ef8383620008c4565b9150826002028217905092915050565b6200090a82620006c8565b67ffffffffffffffff8111156200092657620009256200051d565b5b620009328254620006ff565b6200093f82828562000868565b5f60209050601f83116001811462000975575f841562000960578287015190505b6200096c8582620008e2565b865550620009db565b601f198416620009858662000733565b5f5b82811015620009ae5784890151825560018201915060208501945060208101905062000987565b86831015620009ce5784890151620009ca601f891682620008c4565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62000a0e82620009e3565b9050919050565b62000a208162000a02565b82525050565b5f60408201905062000a3b5f83018562000a15565b62000a4a602083018462000a15565b9392505050565b5f60208201905062000a665f83018462000a15565b92915050565b5f82825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f62000ab260208362000a6c565b915062000abf8262000a7c565b602082019050919050565b5f6020820190508181035f83015262000ae38162000aa4565b9050919050565b6130468062000af85f395ff3fe6080604052600436106101b6575f3560e01c806370a08231116100eb578063b03def6911610089578063d4e9329211610063578063d4e93292146105d2578063e985e9c5146105e8578063f2fde38b14610624578063fa9b70181461064c576101b6565b8063b03def6914610544578063b88d4fde1461056e578063c87b56dd14610596576101b6565b806391b7f5ed116100c557806391b7f5ed146104a057806395d89b41146104c8578063a035b1fe146104f2578063a22cb4651461051c576101b6565b806370a0823114610424578063715018a6146104605780638da5cb5b14610476576101b6565b80632db115441161015857806342842e0e1161013257806342842e0e1461036e57806355f804b3146103965780636352211e146103be5780636c0360eb146103fa576101b6565b80632db11544146102fe57806332cb6b0c1461031a57806341f4343414610344576101b6565b8063081812fc11610194578063081812fc14610248578063095ea7b31461028457806318160ddd146102ac57806323b872dd146102d6576101b6565b806301ffc9a7146101ba57806306fdde03146101f65780630715d70414610220575b5f80fd5b3480156101c5575f80fd5b506101e060048036038101906101db9190612013565b610676565b6040516101ed9190612058565b60405180910390f35b348015610201575f80fd5b5061020a610707565b60405161021791906120fb565b60405180910390f35b34801561022b575f80fd5b5061024660048036038101906102419190612145565b610797565b005b348015610253575f80fd5b5061026e600480360381019061026991906121a3565b6107bb565b60405161027b919061220d565b60405180910390f35b34801561028f575f80fd5b506102aa60048036038101906102a59190612250565b610833565b005b3480156102b7575f80fd5b506102c06109d5565b6040516102cd919061229d565b60405180910390f35b3480156102e1575f80fd5b506102fc60048036038101906102f791906122b6565b6109ea565b005b610318600480360381019061031391906121a3565b610a39565b005b348015610325575f80fd5b5061032e610c49565b60405161033b919061229d565b60405180910390f35b34801561034f575f80fd5b50610358610c4f565b6040516103659190612361565b60405180910390f35b348015610379575f80fd5b50610394600480360381019061038f91906122b6565b610c61565b005b3480156103a1575f80fd5b506103bc60048036038101906103b791906124a6565b610cb0565b005b3480156103c9575f80fd5b506103e460048036038101906103df91906121a3565b610ccb565b6040516103f1919061220d565b60405180910390f35b348015610405575f80fd5b5061040e610cdc565b60405161041b91906120fb565b60405180910390f35b34801561042f575f80fd5b5061044a600480360381019061044591906124ed565b610d68565b604051610457919061229d565b60405180910390f35b34801561046b575f80fd5b50610474610df9565b005b348015610481575f80fd5b5061048a610e0c565b604051610497919061220d565b60405180910390f35b3480156104ab575f80fd5b506104c660048036038101906104c191906121a3565b610e34565b005b3480156104d3575f80fd5b506104dc610e46565b6040516104e991906120fb565b60405180910390f35b3480156104fd575f80fd5b50610506610ed6565b604051610513919061229d565b60405180910390f35b348015610527575f80fd5b50610542600480360381019061053d9190612518565b610edc565b005b34801561054f575f80fd5b5061055861104e565b6040516105659190612058565b60405180910390f35b348015610579575f80fd5b50610594600480360381019061058f91906125f4565b611060565b005b3480156105a1575f80fd5b506105bc60048036038101906105b791906121a3565b6110b1565b6040516105c991906120fb565b60405180910390f35b3480156105dd575f80fd5b506105e6611157565b005b3480156105f3575f80fd5b5061060e60048036038101906106099190612674565b6111aa565b60405161061b9190612058565b60405180910390f35b34801561062f575f80fd5b5061064a600480360381019061064591906124ed565b611238565b005b348015610657575f80fd5b506106606112ba565b60405161066d919061229d565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106d057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107005750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610716906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610742906126df565b801561078d5780601f106107645761010080835404028352916020019161078d565b820191905f5260205f20905b81548152906001019060200180831161077057829003601f168201915b5050505050905090565b61079f6112bf565b80600b5f6101000a81548160ff02191690831515021790555050565b5f6107c58261133d565b6107fb576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f61083d82611397565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108a4576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108c361145a565b73ffffffffffffffffffffffffffffffffffffffff1614610926576108ef816108ea61145a565b6111aa565b610925576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b8260065f8481526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b5f6109de611461565b6001545f540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a2857610a2733611469565b5b610a33848484611563565b50505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aa7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9e90612759565b60405180910390fd5b600b5f9054906101000a900460ff16610af5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aec906127c1565b60405180910390fd5b6019811115610b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b309061284f565b60405180910390fd5b6122b881610b45611573565b610b4f919061289a565b1115610b90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8790612917565b60405180910390fd5b600a5481610b9e9190612935565b341015610be0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd7906129c0565b60405180910390fd5b610bf1610beb611584565b8261158b565b610bf9611584565b73ffffffffffffffffffffffffffffffffffffffff167f748a2986091c2034d6e93b6f44f771a79f0e1d6acd8a60c68c17d4e1e2feaed282604051610c3e919061229d565b60405180910390a250565b6122b881565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c9f57610c9e33611469565b5b610caa84848461172b565b50505050565b610cb86112bf565b8060099081610cc79190612b72565b5050565b5f610cd582611397565b9050919050565b60098054610ce9906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610d15906126df565b8015610d605780601f10610d3757610100808354040283529160200191610d60565b820191905f5260205f20905b815481529060010190602001808311610d4357829003601f168201915b505050505081565b5f80610d738361174a565b03610daa576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610e016112bf565b610e0a5f611753565b565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610e3c6112bf565b80600a8190555050565b606060038054610e55906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610e81906126df565b8015610ecc5780601f10610ea357610100808354040283529160200191610ecc565b820191905f5260205f20905b815481529060010190602001808311610eaf57829003601f168201915b5050505050905090565b600a5481565b610ee461145a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f48576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060075f610f5461145a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610ffd61145a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110429190612058565b60405180910390a35050565b600b5f9054906101000a900460ff1681565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461109e5761109d33611469565b5b6110aa85858585611816565b5050505050565b60606110bc8261133d565b6110fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f290612cb1565b60405180910390fd5b5f60098054611109906126df565b9050036111245760405180602001604052805f815250611150565b600961112f83611888565b604051602001611140929190612d89565b6040516020818303038152906040525b9050919050565b61115f6112bf565b5f4790503373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156111a6573d5f803e3d5ffd5b5050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6112406112bf565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a590612e1c565b60405180910390fd5b6112b781611753565b50565b601981565b6112c7611584565b73ffffffffffffffffffffffffffffffffffffffff166112e5610e0c565b73ffffffffffffffffffffffffffffffffffffffff161461133b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133290612e84565b60405180910390fd5b565b5f81611347611461565b1115801561135557505f5482105b801561139057505f7c010000000000000000000000000000000000000000000000000000000060045f8581526020019081526020015f205416145b9050919050565b5f80829050806113a5611461565b11611423575f54811015611422575f60045f8381526020019081526020015f205490505f7c0100000000000000000000000000000000000000000000000000000000821603611420575b5f81036114165760045f836001900393508381526020019081526020015f205490506113ef565b8092505050611455565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f33905090565b5f6001905090565b5f6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611560576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016114df929190612ea2565b602060405180830381865afa1580156114fa573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061151e9190612edd565b61155f57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611556919061220d565b60405180910390fd5b5b50565b61156e838383611952565b505050565b5f61157c611461565b5f5403905090565b5f33905090565b5f805490505f61159a8461174a565b036115d1576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f820361160a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116165f848385611cfc565b600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254019250508190555060e161167860018414611d02565b901b60a042901b6116888561174a565b171760045f8381526020019081526020015f20819055505f8190505f83820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106116aa57815f8190555050506117265f848385611d0b565b505050565b61174583838360405180602001604052805f815250611060565b505050565b5f819050919050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611821848484611952565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146118825761184b84848484611d11565b611881576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60605f600161189684611e5c565b0190505f8167ffffffffffffffff8111156118b4576118b3612382565b5b6040519080825280601f01601f1916602001820160405280156118e65781602001600182028036833780820191505090505b5090505f82602001820190505b600115611947578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161193c5761193b612f08565b5b0494505f85036118f3575b819350505050919050565b5f61195c82611397565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146119c3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60065f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f8573ffffffffffffffffffffffffffffffffffffffff16611a1761145a565b73ffffffffffffffffffffffffffffffffffffffff161480611a465750611a4586611a4061145a565b6111aa565b5b80611a835750611a5461145a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080611abc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611ac68661174a565b03611afd576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b0a8686866001611cfc565b5f611b148361174a565b14611b4d5760065f8581526020019081526020015f205f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b611c0e8761174a565b171760045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603611c8c575f6001850190505f60045f8381526020019081526020015f205403611c8a575f548114611c89578360045f8381526020019081526020015f20819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611cf48686866001611d0b565b505050505050565b50505050565b5f819050919050565b50505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611d3661145a565b8786866040518563ffffffff1660e01b8152600401611d589493929190612f87565b6020604051808303815f875af1925050508015611d9357506040513d601f19601f82011682018060405250810190611d909190612fe5565b60015b611e09573d805f8114611dc1576040519150601f19603f3d011682016040523d82523d5f602084013e611dc6565b606091505b505f815103611e01576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611eb8577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611eae57611ead612f08565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611ef5576d04ee2d6d415b85acef81000000008381611eeb57611eea612f08565b5b0492506020810190505b662386f26fc100008310611f2457662386f26fc100008381611f1a57611f19612f08565b5b0492506010810190505b6305f5e1008310611f4d576305f5e1008381611f4357611f42612f08565b5b0492506008810190505b6127108310611f72576127108381611f6857611f67612f08565b5b0492506004810190505b60648310611f955760648381611f8b57611f8a612f08565b5b0492506002810190505b600a8310611fa4576001810190505b80915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611ff281611fbe565b8114611ffc575f80fd5b50565b5f8135905061200d81611fe9565b92915050565b5f6020828403121561202857612027611fb6565b5b5f61203584828501611fff565b91505092915050565b5f8115159050919050565b6120528161203e565b82525050565b5f60208201905061206b5f830184612049565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156120a857808201518184015260208101905061208d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6120cd82612071565b6120d7818561207b565b93506120e781856020860161208b565b6120f0816120b3565b840191505092915050565b5f6020820190508181035f83015261211381846120c3565b905092915050565b6121248161203e565b811461212e575f80fd5b50565b5f8135905061213f8161211b565b92915050565b5f6020828403121561215a57612159611fb6565b5b5f61216784828501612131565b91505092915050565b5f819050919050565b61218281612170565b811461218c575f80fd5b50565b5f8135905061219d81612179565b92915050565b5f602082840312156121b8576121b7611fb6565b5b5f6121c58482850161218f565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6121f7826121ce565b9050919050565b612207816121ed565b82525050565b5f6020820190506122205f8301846121fe565b92915050565b61222f816121ed565b8114612239575f80fd5b50565b5f8135905061224a81612226565b92915050565b5f806040838503121561226657612265611fb6565b5b5f6122738582860161223c565b92505060206122848582860161218f565b9150509250929050565b61229781612170565b82525050565b5f6020820190506122b05f83018461228e565b92915050565b5f805f606084860312156122cd576122cc611fb6565b5b5f6122da8682870161223c565b93505060206122eb8682870161223c565b92505060406122fc8682870161218f565b9150509250925092565b5f819050919050565b5f61232961232461231f846121ce565b612306565b6121ce565b9050919050565b5f61233a8261230f565b9050919050565b5f61234b82612330565b9050919050565b61235b81612341565b82525050565b5f6020820190506123745f830184612352565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6123b8826120b3565b810181811067ffffffffffffffff821117156123d7576123d6612382565b5b80604052505050565b5f6123e9611fad565b90506123f582826123af565b919050565b5f67ffffffffffffffff82111561241457612413612382565b5b61241d826120b3565b9050602081019050919050565b828183375f83830152505050565b5f61244a612445846123fa565b6123e0565b9050828152602081018484840111156124665761246561237e565b5b61247184828561242a565b509392505050565b5f82601f83011261248d5761248c61237a565b5b813561249d848260208601612438565b91505092915050565b5f602082840312156124bb576124ba611fb6565b5b5f82013567ffffffffffffffff8111156124d8576124d7611fba565b5b6124e484828501612479565b91505092915050565b5f6020828403121561250257612501611fb6565b5b5f61250f8482850161223c565b91505092915050565b5f806040838503121561252e5761252d611fb6565b5b5f61253b8582860161223c565b925050602061254c85828601612131565b9150509250929050565b5f67ffffffffffffffff8211156125705761256f612382565b5b612579826120b3565b9050602081019050919050565b5f61259861259384612556565b6123e0565b9050828152602081018484840111156125b4576125b361237e565b5b6125bf84828561242a565b509392505050565b5f82601f8301126125db576125da61237a565b5b81356125eb848260208601612586565b91505092915050565b5f805f806080858703121561260c5761260b611fb6565b5b5f6126198782880161223c565b945050602061262a8782880161223c565b935050604061263b8782880161218f565b925050606085013567ffffffffffffffff81111561265c5761265b611fba565b5b612668878288016125c7565b91505092959194509250565b5f806040838503121561268a57612689611fb6565b5b5f6126978582860161223c565b92505060206126a88582860161223c565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806126f657607f821691505b602082108103612709576127086126b2565b5b50919050565b7f436f6e7472616374206d696e74696e67206973206e6f7420616c6c6f776564005f82015250565b5f612743601f8361207b565b915061274e8261270f565b602082019050919050565b5f6020820190508181035f83015261277081612737565b9050919050565b7f4d696e74206973206e6f742061637469766500000000000000000000000000005f82015250565b5f6127ab60128361207b565b91506127b682612777565b602082019050919050565b5f6020820190508181035f8301526127d88161279f565b9050919050565b7f4d696e7420776f756c6420657863656564206d617820616d6f756e74207065725f8201527f206d696e74000000000000000000000000000000000000000000000000000000602082015250565b5f61283960258361207b565b9150612844826127df565b604082019050919050565b5f6020820190508181035f8301526128668161282d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6128a482612170565b91506128af83612170565b92508282019050808211156128c7576128c661286d565b5b92915050565b7f4d696e7420776f756c6420657863656564206d617820737570706c79000000005f82015250565b5f612901601c8361207b565b915061290c826128cd565b602082019050919050565b5f6020820190508181035f83015261292e816128f5565b9050919050565b5f61293f82612170565b915061294a83612170565b925082820261295881612170565b9150828204841483151761296f5761296e61286d565b5b5092915050565b7f4554482076616c75652073656e74206973206e6f7420636f72726563740000005f82015250565b5f6129aa601d8361207b565b91506129b582612976565b602082019050919050565b5f6020820190508181035f8301526129d78161299e565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612a3a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826129ff565b612a4486836129ff565b95508019841693508086168417925050509392505050565b5f612a76612a71612a6c84612170565b612306565b612170565b9050919050565b5f819050919050565b612a8f83612a5c565b612aa3612a9b82612a7d565b848454612a0b565b825550505050565b5f90565b612ab7612aab565b612ac2818484612a86565b505050565b5b81811015612ae557612ada5f82612aaf565b600181019050612ac8565b5050565b601f821115612b2a57612afb816129de565b612b04846129f0565b81016020851015612b13578190505b612b27612b1f856129f0565b830182612ac7565b50505b505050565b5f82821c905092915050565b5f612b4a5f1984600802612b2f565b1980831691505092915050565b5f612b628383612b3b565b9150826002028217905092915050565b612b7b82612071565b67ffffffffffffffff811115612b9457612b93612382565b5b612b9e82546126df565b612ba9828285612ae9565b5f60209050601f831160018114612bda575f8415612bc8578287015190505b612bd28582612b57565b865550612c39565b601f198416612be8866129de565b5f5b82811015612c0f57848901518255600182019150602085019450602081019050612bea565b86831015612c2c5784890151612c28601f891682612b3b565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f612c9b602f8361207b565b9150612ca682612c41565b604082019050919050565b5f6020820190508181035f830152612cc881612c8f565b9050919050565b5f81905092915050565b5f8154612ce5816126df565b612cef8186612ccf565b9450600182165f8114612d095760018114612d1e57612d50565b60ff1983168652811515820286019350612d50565b612d27856129de565b5f5b83811015612d4857815481890152600182019150602081019050612d29565b838801955050505b50505092915050565b5f612d6382612071565b612d6d8185612ccf565b9350612d7d81856020860161208b565b80840191505092915050565b5f612d948285612cd9565b9150612da08284612d59565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f612e0660268361207b565b9150612e1182612dac565b604082019050919050565b5f6020820190508181035f830152612e3381612dfa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f612e6e60208361207b565b9150612e7982612e3a565b602082019050919050565b5f6020820190508181035f830152612e9b81612e62565b9050919050565b5f604082019050612eb55f8301856121fe565b612ec260208301846121fe565b9392505050565b5f81519050612ed78161211b565b92915050565b5f60208284031215612ef257612ef1611fb6565b5b5f612eff84828501612ec9565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f612f5982612f35565b612f638185612f3f565b9350612f7381856020860161208b565b612f7c816120b3565b840191505092915050565b5f608082019050612f9a5f8301876121fe565b612fa760208301866121fe565b612fb4604083018561228e565b8181036060830152612fc68184612f4f565b905095945050505050565b5f81519050612fdf81611fe9565b92915050565b5f60208284031215612ffa57612ff9611fb6565b5b5f61300784828501612fd1565b9150509291505056fea26469706673582212201fbd68dc8438b7d387eca7b260c49644a1745cdd0ff51f1cc5960018b60e1e7364736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106101b6575f3560e01c806370a08231116100eb578063b03def6911610089578063d4e9329211610063578063d4e93292146105d2578063e985e9c5146105e8578063f2fde38b14610624578063fa9b70181461064c576101b6565b8063b03def6914610544578063b88d4fde1461056e578063c87b56dd14610596576101b6565b806391b7f5ed116100c557806391b7f5ed146104a057806395d89b41146104c8578063a035b1fe146104f2578063a22cb4651461051c576101b6565b806370a0823114610424578063715018a6146104605780638da5cb5b14610476576101b6565b80632db115441161015857806342842e0e1161013257806342842e0e1461036e57806355f804b3146103965780636352211e146103be5780636c0360eb146103fa576101b6565b80632db11544146102fe57806332cb6b0c1461031a57806341f4343414610344576101b6565b8063081812fc11610194578063081812fc14610248578063095ea7b31461028457806318160ddd146102ac57806323b872dd146102d6576101b6565b806301ffc9a7146101ba57806306fdde03146101f65780630715d70414610220575b5f80fd5b3480156101c5575f80fd5b506101e060048036038101906101db9190612013565b610676565b6040516101ed9190612058565b60405180910390f35b348015610201575f80fd5b5061020a610707565b60405161021791906120fb565b60405180910390f35b34801561022b575f80fd5b5061024660048036038101906102419190612145565b610797565b005b348015610253575f80fd5b5061026e600480360381019061026991906121a3565b6107bb565b60405161027b919061220d565b60405180910390f35b34801561028f575f80fd5b506102aa60048036038101906102a59190612250565b610833565b005b3480156102b7575f80fd5b506102c06109d5565b6040516102cd919061229d565b60405180910390f35b3480156102e1575f80fd5b506102fc60048036038101906102f791906122b6565b6109ea565b005b610318600480360381019061031391906121a3565b610a39565b005b348015610325575f80fd5b5061032e610c49565b60405161033b919061229d565b60405180910390f35b34801561034f575f80fd5b50610358610c4f565b6040516103659190612361565b60405180910390f35b348015610379575f80fd5b50610394600480360381019061038f91906122b6565b610c61565b005b3480156103a1575f80fd5b506103bc60048036038101906103b791906124a6565b610cb0565b005b3480156103c9575f80fd5b506103e460048036038101906103df91906121a3565b610ccb565b6040516103f1919061220d565b60405180910390f35b348015610405575f80fd5b5061040e610cdc565b60405161041b91906120fb565b60405180910390f35b34801561042f575f80fd5b5061044a600480360381019061044591906124ed565b610d68565b604051610457919061229d565b60405180910390f35b34801561046b575f80fd5b50610474610df9565b005b348015610481575f80fd5b5061048a610e0c565b604051610497919061220d565b60405180910390f35b3480156104ab575f80fd5b506104c660048036038101906104c191906121a3565b610e34565b005b3480156104d3575f80fd5b506104dc610e46565b6040516104e991906120fb565b60405180910390f35b3480156104fd575f80fd5b50610506610ed6565b604051610513919061229d565b60405180910390f35b348015610527575f80fd5b50610542600480360381019061053d9190612518565b610edc565b005b34801561054f575f80fd5b5061055861104e565b6040516105659190612058565b60405180910390f35b348015610579575f80fd5b50610594600480360381019061058f91906125f4565b611060565b005b3480156105a1575f80fd5b506105bc60048036038101906105b791906121a3565b6110b1565b6040516105c991906120fb565b60405180910390f35b3480156105dd575f80fd5b506105e6611157565b005b3480156105f3575f80fd5b5061060e60048036038101906106099190612674565b6111aa565b60405161061b9190612058565b60405180910390f35b34801561062f575f80fd5b5061064a600480360381019061064591906124ed565b611238565b005b348015610657575f80fd5b506106606112ba565b60405161066d919061229d565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106d057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107005750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610716906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610742906126df565b801561078d5780601f106107645761010080835404028352916020019161078d565b820191905f5260205f20905b81548152906001019060200180831161077057829003601f168201915b5050505050905090565b61079f6112bf565b80600b5f6101000a81548160ff02191690831515021790555050565b5f6107c58261133d565b6107fb576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f61083d82611397565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108a4576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108c361145a565b73ffffffffffffffffffffffffffffffffffffffff1614610926576108ef816108ea61145a565b6111aa565b610925576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b8260065f8481526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b5f6109de611461565b6001545f540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a2857610a2733611469565b5b610a33848484611563565b50505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aa7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9e90612759565b60405180910390fd5b600b5f9054906101000a900460ff16610af5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aec906127c1565b60405180910390fd5b6019811115610b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b309061284f565b60405180910390fd5b6122b881610b45611573565b610b4f919061289a565b1115610b90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8790612917565b60405180910390fd5b600a5481610b9e9190612935565b341015610be0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd7906129c0565b60405180910390fd5b610bf1610beb611584565b8261158b565b610bf9611584565b73ffffffffffffffffffffffffffffffffffffffff167f748a2986091c2034d6e93b6f44f771a79f0e1d6acd8a60c68c17d4e1e2feaed282604051610c3e919061229d565b60405180910390a250565b6122b881565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c9f57610c9e33611469565b5b610caa84848461172b565b50505050565b610cb86112bf565b8060099081610cc79190612b72565b5050565b5f610cd582611397565b9050919050565b60098054610ce9906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610d15906126df565b8015610d605780601f10610d3757610100808354040283529160200191610d60565b820191905f5260205f20905b815481529060010190602001808311610d4357829003601f168201915b505050505081565b5f80610d738361174a565b03610daa576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610e016112bf565b610e0a5f611753565b565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610e3c6112bf565b80600a8190555050565b606060038054610e55906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610e81906126df565b8015610ecc5780601f10610ea357610100808354040283529160200191610ecc565b820191905f5260205f20905b815481529060010190602001808311610eaf57829003601f168201915b5050505050905090565b600a5481565b610ee461145a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f48576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060075f610f5461145a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610ffd61145a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110429190612058565b60405180910390a35050565b600b5f9054906101000a900460ff1681565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461109e5761109d33611469565b5b6110aa85858585611816565b5050505050565b60606110bc8261133d565b6110fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f290612cb1565b60405180910390fd5b5f60098054611109906126df565b9050036111245760405180602001604052805f815250611150565b600961112f83611888565b604051602001611140929190612d89565b6040516020818303038152906040525b9050919050565b61115f6112bf565b5f4790503373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156111a6573d5f803e3d5ffd5b5050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6112406112bf565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a590612e1c565b60405180910390fd5b6112b781611753565b50565b601981565b6112c7611584565b73ffffffffffffffffffffffffffffffffffffffff166112e5610e0c565b73ffffffffffffffffffffffffffffffffffffffff161461133b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133290612e84565b60405180910390fd5b565b5f81611347611461565b1115801561135557505f5482105b801561139057505f7c010000000000000000000000000000000000000000000000000000000060045f8581526020019081526020015f205416145b9050919050565b5f80829050806113a5611461565b11611423575f54811015611422575f60045f8381526020019081526020015f205490505f7c0100000000000000000000000000000000000000000000000000000000821603611420575b5f81036114165760045f836001900393508381526020019081526020015f205490506113ef565b8092505050611455565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f33905090565b5f6001905090565b5f6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611560576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016114df929190612ea2565b602060405180830381865afa1580156114fa573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061151e9190612edd565b61155f57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611556919061220d565b60405180910390fd5b5b50565b61156e838383611952565b505050565b5f61157c611461565b5f5403905090565b5f33905090565b5f805490505f61159a8461174a565b036115d1576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f820361160a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116165f848385611cfc565b600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254019250508190555060e161167860018414611d02565b901b60a042901b6116888561174a565b171760045f8381526020019081526020015f20819055505f8190505f83820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106116aa57815f8190555050506117265f848385611d0b565b505050565b61174583838360405180602001604052805f815250611060565b505050565b5f819050919050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611821848484611952565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146118825761184b84848484611d11565b611881576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60605f600161189684611e5c565b0190505f8167ffffffffffffffff8111156118b4576118b3612382565b5b6040519080825280601f01601f1916602001820160405280156118e65781602001600182028036833780820191505090505b5090505f82602001820190505b600115611947578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161193c5761193b612f08565b5b0494505f85036118f3575b819350505050919050565b5f61195c82611397565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146119c3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60065f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f8573ffffffffffffffffffffffffffffffffffffffff16611a1761145a565b73ffffffffffffffffffffffffffffffffffffffff161480611a465750611a4586611a4061145a565b6111aa565b5b80611a835750611a5461145a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080611abc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611ac68661174a565b03611afd576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b0a8686866001611cfc565b5f611b148361174a565b14611b4d5760065f8581526020019081526020015f205f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b611c0e8761174a565b171760045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603611c8c575f6001850190505f60045f8381526020019081526020015f205403611c8a575f548114611c89578360045f8381526020019081526020015f20819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611cf48686866001611d0b565b505050505050565b50505050565b5f819050919050565b50505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611d3661145a565b8786866040518563ffffffff1660e01b8152600401611d589493929190612f87565b6020604051808303815f875af1925050508015611d9357506040513d601f19601f82011682018060405250810190611d909190612fe5565b60015b611e09573d805f8114611dc1576040519150601f19603f3d011682016040523d82523d5f602084013e611dc6565b606091505b505f815103611e01576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611eb8577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611eae57611ead612f08565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611ef5576d04ee2d6d415b85acef81000000008381611eeb57611eea612f08565b5b0492506020810190505b662386f26fc100008310611f2457662386f26fc100008381611f1a57611f19612f08565b5b0492506010810190505b6305f5e1008310611f4d576305f5e1008381611f4357611f42612f08565b5b0492506008810190505b6127108310611f72576127108381611f6857611f67612f08565b5b0492506004810190505b60648310611f955760648381611f8b57611f8a612f08565b5b0492506002810190505b600a8310611fa4576001810190505b80915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611ff281611fbe565b8114611ffc575f80fd5b50565b5f8135905061200d81611fe9565b92915050565b5f6020828403121561202857612027611fb6565b5b5f61203584828501611fff565b91505092915050565b5f8115159050919050565b6120528161203e565b82525050565b5f60208201905061206b5f830184612049565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156120a857808201518184015260208101905061208d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6120cd82612071565b6120d7818561207b565b93506120e781856020860161208b565b6120f0816120b3565b840191505092915050565b5f6020820190508181035f83015261211381846120c3565b905092915050565b6121248161203e565b811461212e575f80fd5b50565b5f8135905061213f8161211b565b92915050565b5f6020828403121561215a57612159611fb6565b5b5f61216784828501612131565b91505092915050565b5f819050919050565b61218281612170565b811461218c575f80fd5b50565b5f8135905061219d81612179565b92915050565b5f602082840312156121b8576121b7611fb6565b5b5f6121c58482850161218f565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6121f7826121ce565b9050919050565b612207816121ed565b82525050565b5f6020820190506122205f8301846121fe565b92915050565b61222f816121ed565b8114612239575f80fd5b50565b5f8135905061224a81612226565b92915050565b5f806040838503121561226657612265611fb6565b5b5f6122738582860161223c565b92505060206122848582860161218f565b9150509250929050565b61229781612170565b82525050565b5f6020820190506122b05f83018461228e565b92915050565b5f805f606084860312156122cd576122cc611fb6565b5b5f6122da8682870161223c565b93505060206122eb8682870161223c565b92505060406122fc8682870161218f565b9150509250925092565b5f819050919050565b5f61232961232461231f846121ce565b612306565b6121ce565b9050919050565b5f61233a8261230f565b9050919050565b5f61234b82612330565b9050919050565b61235b81612341565b82525050565b5f6020820190506123745f830184612352565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6123b8826120b3565b810181811067ffffffffffffffff821117156123d7576123d6612382565b5b80604052505050565b5f6123e9611fad565b90506123f582826123af565b919050565b5f67ffffffffffffffff82111561241457612413612382565b5b61241d826120b3565b9050602081019050919050565b828183375f83830152505050565b5f61244a612445846123fa565b6123e0565b9050828152602081018484840111156124665761246561237e565b5b61247184828561242a565b509392505050565b5f82601f83011261248d5761248c61237a565b5b813561249d848260208601612438565b91505092915050565b5f602082840312156124bb576124ba611fb6565b5b5f82013567ffffffffffffffff8111156124d8576124d7611fba565b5b6124e484828501612479565b91505092915050565b5f6020828403121561250257612501611fb6565b5b5f61250f8482850161223c565b91505092915050565b5f806040838503121561252e5761252d611fb6565b5b5f61253b8582860161223c565b925050602061254c85828601612131565b9150509250929050565b5f67ffffffffffffffff8211156125705761256f612382565b5b612579826120b3565b9050602081019050919050565b5f61259861259384612556565b6123e0565b9050828152602081018484840111156125b4576125b361237e565b5b6125bf84828561242a565b509392505050565b5f82601f8301126125db576125da61237a565b5b81356125eb848260208601612586565b91505092915050565b5f805f806080858703121561260c5761260b611fb6565b5b5f6126198782880161223c565b945050602061262a8782880161223c565b935050604061263b8782880161218f565b925050606085013567ffffffffffffffff81111561265c5761265b611fba565b5b612668878288016125c7565b91505092959194509250565b5f806040838503121561268a57612689611fb6565b5b5f6126978582860161223c565b92505060206126a88582860161223c565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806126f657607f821691505b602082108103612709576127086126b2565b5b50919050565b7f436f6e7472616374206d696e74696e67206973206e6f7420616c6c6f776564005f82015250565b5f612743601f8361207b565b915061274e8261270f565b602082019050919050565b5f6020820190508181035f83015261277081612737565b9050919050565b7f4d696e74206973206e6f742061637469766500000000000000000000000000005f82015250565b5f6127ab60128361207b565b91506127b682612777565b602082019050919050565b5f6020820190508181035f8301526127d88161279f565b9050919050565b7f4d696e7420776f756c6420657863656564206d617820616d6f756e74207065725f8201527f206d696e74000000000000000000000000000000000000000000000000000000602082015250565b5f61283960258361207b565b9150612844826127df565b604082019050919050565b5f6020820190508181035f8301526128668161282d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6128a482612170565b91506128af83612170565b92508282019050808211156128c7576128c661286d565b5b92915050565b7f4d696e7420776f756c6420657863656564206d617820737570706c79000000005f82015250565b5f612901601c8361207b565b915061290c826128cd565b602082019050919050565b5f6020820190508181035f83015261292e816128f5565b9050919050565b5f61293f82612170565b915061294a83612170565b925082820261295881612170565b9150828204841483151761296f5761296e61286d565b5b5092915050565b7f4554482076616c75652073656e74206973206e6f7420636f72726563740000005f82015250565b5f6129aa601d8361207b565b91506129b582612976565b602082019050919050565b5f6020820190508181035f8301526129d78161299e565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612a3a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826129ff565b612a4486836129ff565b95508019841693508086168417925050509392505050565b5f612a76612a71612a6c84612170565b612306565b612170565b9050919050565b5f819050919050565b612a8f83612a5c565b612aa3612a9b82612a7d565b848454612a0b565b825550505050565b5f90565b612ab7612aab565b612ac2818484612a86565b505050565b5b81811015612ae557612ada5f82612aaf565b600181019050612ac8565b5050565b601f821115612b2a57612afb816129de565b612b04846129f0565b81016020851015612b13578190505b612b27612b1f856129f0565b830182612ac7565b50505b505050565b5f82821c905092915050565b5f612b4a5f1984600802612b2f565b1980831691505092915050565b5f612b628383612b3b565b9150826002028217905092915050565b612b7b82612071565b67ffffffffffffffff811115612b9457612b93612382565b5b612b9e82546126df565b612ba9828285612ae9565b5f60209050601f831160018114612bda575f8415612bc8578287015190505b612bd28582612b57565b865550612c39565b601f198416612be8866129de565b5f5b82811015612c0f57848901518255600182019150602085019450602081019050612bea565b86831015612c2c5784890151612c28601f891682612b3b565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f612c9b602f8361207b565b9150612ca682612c41565b604082019050919050565b5f6020820190508181035f830152612cc881612c8f565b9050919050565b5f81905092915050565b5f8154612ce5816126df565b612cef8186612ccf565b9450600182165f8114612d095760018114612d1e57612d50565b60ff1983168652811515820286019350612d50565b612d27856129de565b5f5b83811015612d4857815481890152600182019150602081019050612d29565b838801955050505b50505092915050565b5f612d6382612071565b612d6d8185612ccf565b9350612d7d81856020860161208b565b80840191505092915050565b5f612d948285612cd9565b9150612da08284612d59565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f612e0660268361207b565b9150612e1182612dac565b604082019050919050565b5f6020820190508181035f830152612e3381612dfa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f612e6e60208361207b565b9150612e7982612e3a565b602082019050919050565b5f6020820190508181035f830152612e9b81612e62565b9050919050565b5f604082019050612eb55f8301856121fe565b612ec260208301846121fe565b9392505050565b5f81519050612ed78161211b565b92915050565b5f60208284031215612ef257612ef1611fb6565b5b5f612eff84828501612ec9565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f612f5982612f35565b612f638185612f3f565b9350612f7381856020860161208b565b612f7c816120b3565b840191505092915050565b5f608082019050612f9a5f8301876121fe565b612fa760208301866121fe565b612fb4604083018561228e565b8181036060830152612fc68184612f4f565b905095945050505050565b5f81519050612fdf81611fe9565b92915050565b5f60208284031215612ffa57612ff9611fb6565b5b5f61300784828501612fd1565b9150509291505056fea26469706673582212201fbd68dc8438b7d387eca7b260c49644a1745cdd0ff51f1cc5960018b60e1e7364736f6c63430008140033

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

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _baseUri (string):

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

70698:2882:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45053:615;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50076:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72047:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52144:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51604:474;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44107:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73031:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71440:550;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70806:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7735:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73202:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72197:90;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49865:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70907:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45732:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13857:103;;;;;;;;;;;;;:::i;:::-;;13216:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72339:84;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50245:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70935:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52420:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70962:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73381:196;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72476:343;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72876:147;;;;;;;;;;;;;:::i;:::-;;52799:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14115:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70854:44;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45053:615;45138:4;45453:10;45438:25;;:11;:25;;;;:102;;;;45530:10;45515:25;;:11;:25;;;;45438:102;:179;;;;45607:10;45592:25;;:11;:25;;;;45438:179;45418:199;;45053:615;;;:::o;50076:100::-;50130:13;50163:5;50156:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50076:100;:::o;72047:95::-;13102:13;:11;:13::i;:::-;72126:8:::1;72112:11;;:22;;;;;;;;;;;;;;;;;;72047:95:::0;:::o;52144:204::-;52212:7;52237:16;52245:7;52237;:16::i;:::-;52232:64;;52262:34;;;;;;;;;;;;;;52232:64;52316:15;:24;52332:7;52316:24;;;;;;;;;;;;;;;;;;;;;52309:31;;52144:204;;;:::o;51604:474::-;51677:13;51709:27;51728:7;51709:18;:27::i;:::-;51677:61;;51759:5;51753:11;;:2;:11;;;51749:48;;51773:24;;;;;;;;;;;;;;51749:48;51837:5;51814:28;;:19;:17;:19::i;:::-;:28;;;51810:175;;51862:44;51879:5;51886:19;:17;:19::i;:::-;51862:16;:44::i;:::-;51857:128;;51934:35;;;;;;;;;;;;;;51857:128;51810:175;52024:2;51997:15;:24;52013:7;51997:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;52062:7;52058:2;52042:28;;52051:5;52042:28;;;;;;;;;;;;51666:412;51604:474;;:::o;44107:315::-;44160:7;44388:15;:13;:15::i;:::-;44373:12;;44357:13;;:28;:46;44350:53;;44107:315;:::o;73031:163::-;73132:4;9251:10;9243:18;;:4;:18;;;9239:83;;9278:32;9299:10;9278:20;:32::i;:::-;9239:83;73149:37:::1;73168:4;73174:2;73178:7;73149:18;:37::i;:::-;73031:163:::0;;;;:::o;71440:550::-;71525:9;71511:23;;:10;:23;;;71503:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;71589:11;;;;;;;;;;;71581:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;70896:2;71642:8;:27;;71634:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;70843:4;71748:8;71731:14;:12;:14::i;:::-;:25;;;;:::i;:::-;71730:41;;71722:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;71848:5;;71837:8;:16;;;;:::i;:::-;71823:9;:31;;71815:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;71901:29;71907:12;:10;:12::i;:::-;71921:8;71901:5;:29::i;:::-;71959:12;:10;:12::i;:::-;71948:34;;;71973:8;71948:34;;;;;;:::i;:::-;;;;;;;;71440:550;:::o;70806:41::-;70843:4;70806:41;:::o;7735:143::-;151:42;7735:143;:::o;73202:171::-;73307:4;9251:10;9243:18;;:4;:18;;;9239:83;;9278:32;9299:10;9278:20;:32::i;:::-;9239:83;73324:41:::1;73347:4;73353:2;73357:7;73324:22;:41::i;:::-;73202:171:::0;;;;:::o;72197:90::-;13102:13;:11;:13::i;:::-;72275:4:::1;72265:7;:14;;;;;;:::i;:::-;;72197:90:::0;:::o;49865:144::-;49929:7;49972:27;49991:7;49972:18;:27::i;:::-;49949:52;;49865:144;;;:::o;70907:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;45732:234::-;45796:7;45848:1;45820:24;45838:5;45820:17;:24::i;:::-;:29;45816:70;;45858:28;;;;;;;;;;;;;;45816:70;41071:13;45904:18;:25;45923:5;45904:25;;;;;;;;;;;;;;;;:54;45897:61;;45732:234;;;:::o;13857:103::-;13102:13;:11;:13::i;:::-;13922:30:::1;13949:1;13922:18;:30::i;:::-;13857:103::o:0;13216:87::-;13262:7;13289:6;;;;;;;;;;;13282:13;;13216:87;:::o;72339:84::-;13102:13;:11;:13::i;:::-;72409:6:::1;72401:5;:14;;;;72339:84:::0;:::o;50245:104::-;50301:13;50334:7;50327:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50245:104;:::o;70935:20::-;;;;:::o;52420:308::-;52531:19;:17;:19::i;:::-;52519:31;;:8;:31;;;52515:61;;52559:17;;;;;;;;;;;;;;52515:61;52641:8;52589:18;:39;52608:19;:17;:19::i;:::-;52589:39;;;;;;;;;;;;;;;:49;52629:8;52589:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;52701:8;52665:55;;52680:19;:17;:19::i;:::-;52665:55;;;52711:8;52665:55;;;;;;:::i;:::-;;;;;;;;52420:308;;:::o;70962:23::-;;;;;;;;;;;;;:::o;73381:196::-;73505:4;9251:10;9243:18;;:4;:18;;;9239:83;;9278:32;9299:10;9278:20;:32::i;:::-;9239:83;73522:47:::1;73545:4;73551:2;73555:7;73564:4;73522:22;:47::i;:::-;73381:196:::0;;;;;:::o;72476:343::-;72595:13;72634:17;72642:8;72634:7;:17::i;:::-;72626:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;72748:1;72729:7;72723:21;;;;;:::i;:::-;;;:26;:88;;;;;;;;;;;;;;;;;72776:7;72785:19;:8;:17;:19::i;:::-;72759:46;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72723:88;72716:95;;72476:343;;;:::o;72876:147::-;13102:13;:11;:13::i;:::-;72928:15:::1;72946:21;72928:39;;72986:10;72978:28;;:37;73007:7;72978:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;72917:106;72876:147::o:0;52799:164::-;52896:4;52920:18;:25;52939:5;52920:25;;;;;;;;;;;;;;;:35;52946:8;52920:35;;;;;;;;;;;;;;;;;;;;;;;;;52913:42;;52799:164;;;;:::o;14115:201::-;13102:13;:11;:13::i;:::-;14224:1:::1;14204:22;;:8;:22;;::::0;14196:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;14280:28;14299:8;14280:18;:28::i;:::-;14115:201:::0;:::o;70854:44::-;70896:2;70854:44;:::o;13381:132::-;13456:12;:10;:12::i;:::-;13445:23;;:7;:5;:7::i;:::-;:23;;;13437:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;13381:132::o;54178:273::-;54235:4;54291:7;54272:15;:13;:15::i;:::-;:26;;:66;;;;;54325:13;;54315:7;:23;54272:66;:152;;;;;54423:1;41841:8;54376:17;:26;54394:7;54376:26;;;;;;;;;;;;:43;:48;54272:152;54252:172;;54178:273;;;:::o;47380:1129::-;47447:7;47467:12;47482:7;47467:22;;47550:4;47531:15;:13;:15::i;:::-;:23;47527:915;;47584:13;;47577:4;:20;47573:869;;;47622:14;47639:17;:23;47657:4;47639:23;;;;;;;;;;;;47622:40;;47755:1;41841:8;47728:6;:23;:28;47724:699;;48247:113;48264:1;48254:6;:11;48247:113;;48307:17;:25;48325:6;;;;;;;48307:25;;;;;;;;;;;;48298:34;;48247:113;;;48393:6;48386:13;;;;;;47724:699;47599:843;47573:869;47527:915;48470:31;;;;;;;;;;;;;;47380:1129;;;;:::o;68446:105::-;68506:7;68533:10;68526:17;;68446:105;:::o;71285:101::-;71350:7;71377:1;71370:8;;71285:101;:::o;9660:647::-;9899:1;151:42;9851:45;;;:49;9847:453;;;151:42;10150;;;10201:4;10208:8;10150:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10145:144;;10264:8;10245:28;;;;;;;;;;;:::i;:::-;;;;;;;;10145:144;9847:453;9660:647;:::o;53030:170::-;53164:28;53174:4;53180:2;53184:7;53164:9;:28::i;:::-;53030:170;;;:::o;44520:285::-;44567:7;44771:15;:13;:15::i;:::-;44755:13;;:31;44748:38;;44520:285;:::o;11767:98::-;11820:7;11847:10;11840:17;;11767:98;:::o;57517:1666::-;57582:20;57605:13;;57582:36;;57658:1;57633:21;57651:2;57633:17;:21::i;:::-;:26;57629:58;;57668:19;;;;;;;;;;;;;;57629:58;57714:1;57702:8;:13;57698:44;;57724:18;;;;;;;;;;;;;;57698:44;57755:61;57785:1;57789:2;57793:12;57807:8;57755:21;:61::i;:::-;58359:1;41208:2;58330:1;:25;;58329:31;58317:8;:44;58291:18;:22;58310:2;58291:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;41988:3;58760:29;58787:1;58775:8;:13;58760:14;:29::i;:::-;:56;;41725:3;58697:15;:41;;58655:21;58673:2;58655:17;:21::i;:::-;:84;:162;58604:17;:31;58622:12;58604:31;;;;;;;;;;;:213;;;;58834:20;58857:12;58834:35;;58884:11;58913:8;58898:12;:23;58884:37;;58938:111;58990:14;;;;;;58986:2;58965:40;;58982:1;58965:40;;;;;;;;;;;;59044:3;59029:12;:18;58938:111;;59081:12;59065:13;:28;;;;58068:1037;;59115:60;59144:1;59148:2;59152:12;59166:8;59115:20;:60::i;:::-;57571:1612;57517:1666;;:::o;53271:185::-;53409:39;53426:4;53432:2;53436:7;53409:39;;;;;;;;;;;;:16;:39::i;:::-;53271:185;;;:::o;51165:148::-;51229:14;51290:5;51280:15;;51165:148;;;:::o;14476:191::-;14550:16;14569:6;;;;;;;;;;;14550:25;;14595:8;14586:6;;:17;;;;;;;;;;;;;;;;;;14650:8;14619:40;;14640:8;14619:40;;;;;;;;;;;;14539:128;14476:191;:::o;53527:396::-;53694:28;53704:4;53710:2;53714:7;53694:9;:28::i;:::-;53755:1;53737:2;:14;;;:19;53733:183;;53776:56;53807:4;53813:2;53817:7;53826:5;53776:30;:56::i;:::-;53771:145;;53860:40;;;;;;;;;;;;;;53771:145;53733:183;53527:396;;;;:::o;29594:716::-;29650:13;29701:14;29738:1;29718:17;29729:5;29718:10;:17::i;:::-;:21;29701:38;;29754:20;29788:6;29777:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29754:41;;29810:11;29939:6;29935:2;29931:15;29923:6;29919:28;29912:35;;29976:288;29983:4;29976:288;;;30008:5;;;;;;;;30150:8;30145:2;30138:5;30134:14;30129:30;30124:3;30116:44;30206:2;30197:11;;;;;;:::i;:::-;;;;;30240:1;30231:5;:10;29976:288;30227:21;29976:288;30285:6;30278:13;;;;;29594:716;;;:::o;59437:2654::-;59552:27;59582;59601:7;59582:18;:27::i;:::-;59552:57;;59667:4;59626:45;;59642:19;59626:45;;;59622:86;;59680:28;;;;;;;;;;;;;;59622:86;59721:23;59747:15;:24;59763:7;59747:24;;;;;;;;;;;;;;;;;;;;;59721:50;;59784:22;59833:4;59810:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;59854:43;59871:4;59877:19;:17;:19::i;:::-;59854:16;:43::i;:::-;59810:87;:142;;;;59933:19;:17;:19::i;:::-;59914:38;;:15;:38;;;59810:142;59784:169;;59971:17;59966:66;;59997:35;;;;;;;;;;;;;;59966:66;60072:1;60047:21;60065:2;60047:17;:21::i;:::-;:26;60043:62;;60082:23;;;;;;;;;;;;;;60043:62;60118:43;60140:4;60146:2;60150:7;60159:1;60118:21;:43::i;:::-;60269:1;60231:34;60249:15;60231:17;:34::i;:::-;:39;60227:103;;60294:15;:24;60310:7;60294:24;;;;;;;;;;;;60287:31;;;;;;;;;;;60227:103;60697:18;:24;60716:4;60697:24;;;;;;;;;;;;;;;;60695:26;;;;;;;;;;;;60766:18;:22;60785:2;60766:22;;;;;;;;;;;;;;;;60764:24;;;;;;;;;;;42123:8;41725:3;61147:15;:41;;61105:21;61123:2;61105:17;:21::i;:::-;:84;:128;61059:17;:26;61077:7;61059:26;;;;;;;;;;;:174;;;;61403:1;42123:8;61353:19;:46;:51;61349:626;;61425:19;61457:1;61447:7;:11;61425:33;;61614:1;61580:17;:30;61598:11;61580:30;;;;;;;;;;;;:35;61576:384;;61718:13;;61703:11;:28;61699:242;;61898:19;61865:17;:30;61883:11;61865:30;;;;;;;;;;;:52;;;;61699:242;61576:384;61406:569;61349:626;62022:7;62018:2;62003:27;;62012:4;62003:27;;;;;;;;;;;;62041:42;62062:4;62068:2;62072:7;62081:1;62041:20;:42::i;:::-;59541:2550;;;59437:2654;;;:::o;67279:159::-;;;;;:::o;51400:142::-;51458:14;51519:5;51509:15;;51400:142;;;:::o;68097:158::-;;;;;:::o;65915:716::-;66078:4;66124:2;66099:45;;;66145:19;:17;:19::i;:::-;66166:4;66172:7;66181:5;66099:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;66095:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66399:1;66382:6;:13;:18;66378:235;;66428:40;;;;;;;;;;;;;;66378:235;66571:6;66565:13;66556:6;66552:2;66548:15;66541:38;66095:529;66268:54;;;66258:64;;;:6;:64;;;;66251:71;;;65915:716;;;;;;:::o;26428:948::-;26481:7;26501:14;26518:1;26501:18;;26568:8;26559:5;:17;26555:106;;26606:8;26597:17;;;;;;:::i;:::-;;;;;26643:2;26633:12;;;;26555:106;26688:8;26679:5;:17;26675:106;;26726:8;26717:17;;;;;;:::i;:::-;;;;;26763:2;26753:12;;;;26675:106;26808:8;26799:5;:17;26795:106;;26846:8;26837:17;;;;;;:::i;:::-;;;;;26883:2;26873:12;;;;26795:106;26928:7;26919:5;:16;26915:103;;26965:7;26956:16;;;;;;:::i;:::-;;;;;27001:1;26991:11;;;;26915:103;27045:7;27036:5;:16;27032:103;;27082:7;27073:16;;;;;;:::i;:::-;;;;;27118:1;27108:11;;;;27032:103;27162:7;27153:5;:16;27149:103;;27199:7;27190:16;;;;;;:::i;:::-;;;;;27235:1;27225:11;;;;27149:103;27279:7;27270:5;:16;27266:68;;27317:1;27307:11;;;;27266:68;27362:6;27355:13;;;26428:948;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:116::-;2930:21;2945:5;2930:21;:::i;:::-;2923:5;2920:32;2910:60;;2966:1;2963;2956:12;2910:60;2860:116;:::o;2982:133::-;3025:5;3063:6;3050:20;3041:29;;3079:30;3103:5;3079:30;:::i;:::-;2982:133;;;;:::o;3121:323::-;3177:6;3226:2;3214:9;3205:7;3201:23;3197:32;3194:119;;;3232:79;;:::i;:::-;3194:119;3352:1;3377:50;3419:7;3410:6;3399:9;3395:22;3377:50;:::i;:::-;3367:60;;3323:114;3121:323;;;;:::o;3450:77::-;3487:7;3516:5;3505:16;;3450:77;;;:::o;3533:122::-;3606:24;3624:5;3606:24;:::i;:::-;3599:5;3596:35;3586:63;;3645:1;3642;3635:12;3586:63;3533:122;:::o;3661:139::-;3707:5;3745:6;3732:20;3723:29;;3761:33;3788:5;3761:33;:::i;:::-;3661:139;;;;:::o;3806:329::-;3865:6;3914:2;3902:9;3893:7;3889:23;3885:32;3882:119;;;3920:79;;:::i;:::-;3882:119;4040:1;4065:53;4110:7;4101:6;4090:9;4086:22;4065:53;:::i;:::-;4055:63;;4011:117;3806:329;;;;:::o;4141:126::-;4178:7;4218:42;4211:5;4207:54;4196:65;;4141:126;;;:::o;4273:96::-;4310:7;4339:24;4357:5;4339:24;:::i;:::-;4328:35;;4273:96;;;:::o;4375:118::-;4462:24;4480:5;4462:24;:::i;:::-;4457:3;4450:37;4375:118;;:::o;4499:222::-;4592:4;4630:2;4619:9;4615:18;4607:26;;4643:71;4711:1;4700:9;4696:17;4687:6;4643:71;:::i;:::-;4499:222;;;;:::o;4727:122::-;4800:24;4818:5;4800:24;:::i;:::-;4793:5;4790:35;4780:63;;4839:1;4836;4829:12;4780:63;4727:122;:::o;4855:139::-;4901:5;4939:6;4926:20;4917:29;;4955:33;4982:5;4955:33;:::i;:::-;4855:139;;;;:::o;5000:474::-;5068:6;5076;5125:2;5113:9;5104:7;5100:23;5096:32;5093:119;;;5131:79;;:::i;:::-;5093:119;5251:1;5276:53;5321:7;5312:6;5301:9;5297:22;5276:53;:::i;:::-;5266:63;;5222:117;5378:2;5404:53;5449:7;5440:6;5429:9;5425:22;5404:53;:::i;:::-;5394:63;;5349:118;5000:474;;;;;:::o;5480:118::-;5567:24;5585:5;5567:24;:::i;:::-;5562:3;5555:37;5480:118;;:::o;5604:222::-;5697:4;5735:2;5724:9;5720:18;5712:26;;5748:71;5816:1;5805:9;5801:17;5792:6;5748:71;:::i;:::-;5604:222;;;;:::o;5832:619::-;5909:6;5917;5925;5974:2;5962:9;5953:7;5949:23;5945:32;5942:119;;;5980:79;;:::i;:::-;5942:119;6100:1;6125:53;6170:7;6161:6;6150:9;6146:22;6125:53;:::i;:::-;6115:63;;6071:117;6227:2;6253:53;6298:7;6289:6;6278:9;6274:22;6253:53;:::i;:::-;6243:63;;6198:118;6355:2;6381:53;6426:7;6417:6;6406:9;6402:22;6381:53;:::i;:::-;6371:63;;6326:118;5832:619;;;;;:::o;6457:60::-;6485:3;6506:5;6499:12;;6457:60;;;:::o;6523:142::-;6573:9;6606:53;6624:34;6633:24;6651:5;6633:24;:::i;:::-;6624:34;:::i;:::-;6606:53;:::i;:::-;6593:66;;6523:142;;;:::o;6671:126::-;6721:9;6754:37;6785:5;6754:37;:::i;:::-;6741:50;;6671:126;;;:::o;6803:157::-;6884:9;6917:37;6948:5;6917:37;:::i;:::-;6904:50;;6803:157;;;:::o;6966:193::-;7084:68;7146:5;7084:68;:::i;:::-;7079:3;7072:81;6966:193;;:::o;7165:284::-;7289:4;7327:2;7316:9;7312:18;7304:26;;7340:102;7439:1;7428:9;7424:17;7415:6;7340:102;:::i;:::-;7165:284;;;;:::o;7455:117::-;7564:1;7561;7554:12;7578:117;7687:1;7684;7677:12;7701:180;7749:77;7746:1;7739:88;7846:4;7843:1;7836:15;7870:4;7867:1;7860:15;7887:281;7970:27;7992:4;7970:27;:::i;:::-;7962:6;7958:40;8100:6;8088:10;8085:22;8064:18;8052:10;8049:34;8046:62;8043:88;;;8111:18;;:::i;:::-;8043:88;8151:10;8147:2;8140:22;7930:238;7887:281;;:::o;8174:129::-;8208:6;8235:20;;:::i;:::-;8225:30;;8264:33;8292:4;8284:6;8264:33;:::i;:::-;8174:129;;;:::o;8309:308::-;8371:4;8461:18;8453:6;8450:30;8447:56;;;8483:18;;:::i;:::-;8447:56;8521:29;8543:6;8521:29;:::i;:::-;8513:37;;8605:4;8599;8595:15;8587:23;;8309:308;;;:::o;8623:146::-;8720:6;8715:3;8710;8697:30;8761:1;8752:6;8747:3;8743:16;8736:27;8623:146;;;:::o;8775:425::-;8853:5;8878:66;8894:49;8936:6;8894:49;:::i;:::-;8878:66;:::i;:::-;8869:75;;8967:6;8960:5;8953:21;9005:4;8998:5;8994:16;9043:3;9034:6;9029:3;9025:16;9022:25;9019:112;;;9050:79;;:::i;:::-;9019:112;9140:54;9187:6;9182:3;9177;9140:54;:::i;:::-;8859:341;8775:425;;;;;:::o;9220:340::-;9276:5;9325:3;9318:4;9310:6;9306:17;9302:27;9292:122;;9333:79;;:::i;:::-;9292:122;9450:6;9437:20;9475:79;9550:3;9542:6;9535:4;9527:6;9523:17;9475:79;:::i;:::-;9466:88;;9282:278;9220:340;;;;:::o;9566:509::-;9635:6;9684:2;9672:9;9663:7;9659:23;9655:32;9652:119;;;9690:79;;:::i;:::-;9652:119;9838:1;9827:9;9823:17;9810:31;9868:18;9860:6;9857:30;9854:117;;;9890:79;;:::i;:::-;9854:117;9995:63;10050:7;10041:6;10030:9;10026:22;9995:63;:::i;:::-;9985:73;;9781:287;9566:509;;;;:::o;10081:329::-;10140:6;10189:2;10177:9;10168:7;10164:23;10160:32;10157:119;;;10195:79;;:::i;:::-;10157:119;10315:1;10340:53;10385:7;10376:6;10365:9;10361:22;10340:53;:::i;:::-;10330:63;;10286:117;10081:329;;;;:::o;10416:468::-;10481:6;10489;10538:2;10526:9;10517:7;10513:23;10509:32;10506:119;;;10544:79;;:::i;:::-;10506:119;10664:1;10689:53;10734:7;10725:6;10714:9;10710:22;10689:53;:::i;:::-;10679:63;;10635:117;10791:2;10817:50;10859:7;10850:6;10839:9;10835:22;10817:50;:::i;:::-;10807:60;;10762:115;10416:468;;;;;:::o;10890:307::-;10951:4;11041:18;11033:6;11030:30;11027:56;;;11063:18;;:::i;:::-;11027:56;11101:29;11123:6;11101:29;:::i;:::-;11093:37;;11185:4;11179;11175:15;11167:23;;10890:307;;;:::o;11203:423::-;11280:5;11305:65;11321:48;11362:6;11321:48;:::i;:::-;11305:65;:::i;:::-;11296:74;;11393:6;11386:5;11379:21;11431:4;11424:5;11420:16;11469:3;11460:6;11455:3;11451:16;11448:25;11445:112;;;11476:79;;:::i;:::-;11445:112;11566:54;11613:6;11608:3;11603;11566:54;:::i;:::-;11286:340;11203:423;;;;;:::o;11645:338::-;11700:5;11749:3;11742:4;11734:6;11730:17;11726:27;11716:122;;11757:79;;:::i;:::-;11716:122;11874:6;11861:20;11899:78;11973:3;11965:6;11958:4;11950:6;11946:17;11899:78;:::i;:::-;11890:87;;11706:277;11645:338;;;;:::o;11989:943::-;12084:6;12092;12100;12108;12157:3;12145:9;12136:7;12132:23;12128:33;12125:120;;;12164:79;;:::i;:::-;12125:120;12284:1;12309:53;12354:7;12345:6;12334:9;12330:22;12309:53;:::i;:::-;12299:63;;12255:117;12411:2;12437:53;12482:7;12473:6;12462:9;12458:22;12437:53;:::i;:::-;12427:63;;12382:118;12539:2;12565:53;12610:7;12601:6;12590:9;12586:22;12565:53;:::i;:::-;12555:63;;12510:118;12695:2;12684:9;12680:18;12667:32;12726:18;12718:6;12715:30;12712:117;;;12748:79;;:::i;:::-;12712:117;12853:62;12907:7;12898:6;12887:9;12883:22;12853:62;:::i;:::-;12843:72;;12638:287;11989:943;;;;;;;:::o;12938:474::-;13006:6;13014;13063:2;13051:9;13042:7;13038:23;13034:32;13031:119;;;13069:79;;:::i;:::-;13031:119;13189:1;13214:53;13259:7;13250:6;13239:9;13235:22;13214:53;:::i;:::-;13204:63;;13160:117;13316:2;13342:53;13387:7;13378:6;13367:9;13363:22;13342:53;:::i;:::-;13332:63;;13287:118;12938:474;;;;;:::o;13418:180::-;13466:77;13463:1;13456:88;13563:4;13560:1;13553:15;13587:4;13584:1;13577:15;13604:320;13648:6;13685:1;13679:4;13675:12;13665:22;;13732:1;13726:4;13722:12;13753:18;13743:81;;13809:4;13801:6;13797:17;13787:27;;13743:81;13871:2;13863:6;13860:14;13840:18;13837:38;13834:84;;13890:18;;:::i;:::-;13834:84;13655:269;13604:320;;;:::o;13930:181::-;14070:33;14066:1;14058:6;14054:14;14047:57;13930:181;:::o;14117:366::-;14259:3;14280:67;14344:2;14339:3;14280:67;:::i;:::-;14273:74;;14356:93;14445:3;14356:93;:::i;:::-;14474:2;14469:3;14465:12;14458:19;;14117:366;;;:::o;14489:419::-;14655:4;14693:2;14682:9;14678:18;14670:26;;14742:9;14736:4;14732:20;14728:1;14717:9;14713:17;14706:47;14770:131;14896:4;14770:131;:::i;:::-;14762:139;;14489:419;;;:::o;14914:168::-;15054:20;15050:1;15042:6;15038:14;15031:44;14914:168;:::o;15088:366::-;15230:3;15251:67;15315:2;15310:3;15251:67;:::i;:::-;15244:74;;15327:93;15416:3;15327:93;:::i;:::-;15445:2;15440:3;15436:12;15429:19;;15088:366;;;:::o;15460:419::-;15626:4;15664:2;15653:9;15649:18;15641:26;;15713:9;15707:4;15703:20;15699:1;15688:9;15684:17;15677:47;15741:131;15867:4;15741:131;:::i;:::-;15733:139;;15460:419;;;:::o;15885:224::-;16025:34;16021:1;16013:6;16009:14;16002:58;16094:7;16089:2;16081:6;16077:15;16070:32;15885:224;:::o;16115:366::-;16257:3;16278:67;16342:2;16337:3;16278:67;:::i;:::-;16271:74;;16354:93;16443:3;16354:93;:::i;:::-;16472:2;16467:3;16463:12;16456:19;;16115:366;;;:::o;16487:419::-;16653:4;16691:2;16680:9;16676:18;16668:26;;16740:9;16734:4;16730:20;16726:1;16715:9;16711:17;16704:47;16768:131;16894:4;16768:131;:::i;:::-;16760:139;;16487:419;;;:::o;16912:180::-;16960:77;16957:1;16950:88;17057:4;17054:1;17047:15;17081:4;17078:1;17071:15;17098:191;17138:3;17157:20;17175:1;17157:20;:::i;:::-;17152:25;;17191:20;17209:1;17191:20;:::i;:::-;17186:25;;17234:1;17231;17227:9;17220:16;;17255:3;17252:1;17249:10;17246:36;;;17262:18;;:::i;:::-;17246:36;17098:191;;;;:::o;17295:178::-;17435:30;17431:1;17423:6;17419:14;17412:54;17295:178;:::o;17479:366::-;17621:3;17642:67;17706:2;17701:3;17642:67;:::i;:::-;17635:74;;17718:93;17807:3;17718:93;:::i;:::-;17836:2;17831:3;17827:12;17820:19;;17479:366;;;:::o;17851:419::-;18017:4;18055:2;18044:9;18040:18;18032:26;;18104:9;18098:4;18094:20;18090:1;18079:9;18075:17;18068:47;18132:131;18258:4;18132:131;:::i;:::-;18124:139;;17851:419;;;:::o;18276:410::-;18316:7;18339:20;18357:1;18339:20;:::i;:::-;18334:25;;18373:20;18391:1;18373:20;:::i;:::-;18368:25;;18428:1;18425;18421:9;18450:30;18468:11;18450:30;:::i;:::-;18439:41;;18629:1;18620:7;18616:15;18613:1;18610:22;18590:1;18583:9;18563:83;18540:139;;18659:18;;:::i;:::-;18540:139;18324:362;18276:410;;;;:::o;18692:179::-;18832:31;18828:1;18820:6;18816:14;18809:55;18692:179;:::o;18877:366::-;19019:3;19040:67;19104:2;19099:3;19040:67;:::i;:::-;19033:74;;19116:93;19205:3;19116:93;:::i;:::-;19234:2;19229:3;19225:12;19218:19;;18877:366;;;:::o;19249:419::-;19415:4;19453:2;19442:9;19438:18;19430:26;;19502:9;19496:4;19492:20;19488:1;19477:9;19473:17;19466:47;19530:131;19656:4;19530:131;:::i;:::-;19522:139;;19249:419;;;:::o;19674:141::-;19723:4;19746:3;19738:11;;19769:3;19766:1;19759:14;19803:4;19800:1;19790:18;19782:26;;19674:141;;;:::o;19821:93::-;19858:6;19905:2;19900;19893:5;19889:14;19885:23;19875:33;;19821:93;;;:::o;19920:107::-;19964:8;20014:5;20008:4;20004:16;19983:37;;19920:107;;;;:::o;20033:393::-;20102:6;20152:1;20140:10;20136:18;20175:97;20205:66;20194:9;20175:97;:::i;:::-;20293:39;20323:8;20312:9;20293:39;:::i;:::-;20281:51;;20365:4;20361:9;20354:5;20350:21;20341:30;;20414:4;20404:8;20400:19;20393:5;20390:30;20380:40;;20109:317;;20033:393;;;;;:::o;20432:142::-;20482:9;20515:53;20533:34;20542:24;20560:5;20542:24;:::i;:::-;20533:34;:::i;:::-;20515:53;:::i;:::-;20502:66;;20432:142;;;:::o;20580:75::-;20623:3;20644:5;20637:12;;20580:75;;;:::o;20661:269::-;20771:39;20802:7;20771:39;:::i;:::-;20832:91;20881:41;20905:16;20881:41;:::i;:::-;20873:6;20866:4;20860:11;20832:91;:::i;:::-;20826:4;20819:105;20737:193;20661:269;;;:::o;20936:73::-;20981:3;20936:73;:::o;21015:189::-;21092:32;;:::i;:::-;21133:65;21191:6;21183;21177:4;21133:65;:::i;:::-;21068:136;21015:189;;:::o;21210:186::-;21270:120;21287:3;21280:5;21277:14;21270:120;;;21341:39;21378:1;21371:5;21341:39;:::i;:::-;21314:1;21307:5;21303:13;21294:22;;21270:120;;;21210:186;;:::o;21402:543::-;21503:2;21498:3;21495:11;21492:446;;;21537:38;21569:5;21537:38;:::i;:::-;21621:29;21639:10;21621:29;:::i;:::-;21611:8;21607:44;21804:2;21792:10;21789:18;21786:49;;;21825:8;21810:23;;21786:49;21848:80;21904:22;21922:3;21904:22;:::i;:::-;21894:8;21890:37;21877:11;21848:80;:::i;:::-;21507:431;;21492:446;21402:543;;;:::o;21951:117::-;22005:8;22055:5;22049:4;22045:16;22024:37;;21951:117;;;;:::o;22074:169::-;22118:6;22151:51;22199:1;22195:6;22187:5;22184:1;22180:13;22151:51;:::i;:::-;22147:56;22232:4;22226;22222:15;22212:25;;22125:118;22074:169;;;;:::o;22248:295::-;22324:4;22470:29;22495:3;22489:4;22470:29;:::i;:::-;22462:37;;22532:3;22529:1;22525:11;22519:4;22516:21;22508:29;;22248:295;;;;:::o;22548:1395::-;22665:37;22698:3;22665:37;:::i;:::-;22767:18;22759:6;22756:30;22753:56;;;22789:18;;:::i;:::-;22753:56;22833:38;22865:4;22859:11;22833:38;:::i;:::-;22918:67;22978:6;22970;22964:4;22918:67;:::i;:::-;23012:1;23036:4;23023:17;;23068:2;23060:6;23057:14;23085:1;23080:618;;;;23742:1;23759:6;23756:77;;;23808:9;23803:3;23799:19;23793:26;23784:35;;23756:77;23859:67;23919:6;23912:5;23859:67;:::i;:::-;23853:4;23846:81;23715:222;23050:887;;23080:618;23132:4;23128:9;23120:6;23116:22;23166:37;23198:4;23166:37;:::i;:::-;23225:1;23239:208;23253:7;23250:1;23247:14;23239:208;;;23332:9;23327:3;23323:19;23317:26;23309:6;23302:42;23383:1;23375:6;23371:14;23361:24;;23430:2;23419:9;23415:18;23402:31;;23276:4;23273:1;23269:12;23264:17;;23239:208;;;23475:6;23466:7;23463:19;23460:179;;;23533:9;23528:3;23524:19;23518:26;23576:48;23618:4;23610:6;23606:17;23595:9;23576:48;:::i;:::-;23568:6;23561:64;23483:156;23460:179;23685:1;23681;23673:6;23669:14;23665:22;23659:4;23652:36;23087:611;;;23050:887;;22640:1303;;;22548:1395;;:::o;23949:234::-;24089:34;24085:1;24077:6;24073:14;24066:58;24158:17;24153:2;24145:6;24141:15;24134:42;23949:234;:::o;24189:366::-;24331:3;24352:67;24416:2;24411:3;24352:67;:::i;:::-;24345:74;;24428:93;24517:3;24428:93;:::i;:::-;24546:2;24541:3;24537:12;24530:19;;24189:366;;;:::o;24561:419::-;24727:4;24765:2;24754:9;24750:18;24742:26;;24814:9;24808:4;24804:20;24800:1;24789:9;24785:17;24778:47;24842:131;24968:4;24842:131;:::i;:::-;24834:139;;24561:419;;;:::o;24986:148::-;25088:11;25125:3;25110:18;;24986:148;;;;:::o;25164:874::-;25267:3;25304:5;25298:12;25333:36;25359:9;25333:36;:::i;:::-;25385:89;25467:6;25462:3;25385:89;:::i;:::-;25378:96;;25505:1;25494:9;25490:17;25521:1;25516:166;;;;25696:1;25691:341;;;;25483:549;;25516:166;25600:4;25596:9;25585;25581:25;25576:3;25569:38;25662:6;25655:14;25648:22;25640:6;25636:35;25631:3;25627:45;25620:52;;25516:166;;25691:341;25758:38;25790:5;25758:38;:::i;:::-;25818:1;25832:154;25846:6;25843:1;25840:13;25832:154;;;25920:7;25914:14;25910:1;25905:3;25901:11;25894:35;25970:1;25961:7;25957:15;25946:26;;25868:4;25865:1;25861:12;25856:17;;25832:154;;;26015:6;26010:3;26006:16;25999:23;;25698:334;;25483:549;;25271:767;;25164:874;;;;:::o;26044:390::-;26150:3;26178:39;26211:5;26178:39;:::i;:::-;26233:89;26315:6;26310:3;26233:89;:::i;:::-;26226:96;;26331:65;26389:6;26384:3;26377:4;26370:5;26366:16;26331:65;:::i;:::-;26421:6;26416:3;26412:16;26405:23;;26154:280;26044:390;;;;:::o;26440:429::-;26617:3;26639:92;26727:3;26718:6;26639:92;:::i;:::-;26632:99;;26748:95;26839:3;26830:6;26748:95;:::i;:::-;26741:102;;26860:3;26853:10;;26440:429;;;;;:::o;26875:225::-;27015:34;27011:1;27003:6;26999:14;26992:58;27084:8;27079:2;27071:6;27067:15;27060:33;26875:225;:::o;27106:366::-;27248:3;27269:67;27333:2;27328:3;27269:67;:::i;:::-;27262:74;;27345:93;27434:3;27345:93;:::i;:::-;27463:2;27458:3;27454:12;27447:19;;27106:366;;;:::o;27478:419::-;27644:4;27682:2;27671:9;27667:18;27659:26;;27731:9;27725:4;27721:20;27717:1;27706:9;27702:17;27695:47;27759:131;27885:4;27759:131;:::i;:::-;27751:139;;27478:419;;;:::o;27903:182::-;28043:34;28039:1;28031:6;28027:14;28020:58;27903:182;:::o;28091:366::-;28233:3;28254:67;28318:2;28313:3;28254:67;:::i;:::-;28247:74;;28330:93;28419:3;28330:93;:::i;:::-;28448:2;28443:3;28439:12;28432:19;;28091:366;;;:::o;28463:419::-;28629:4;28667:2;28656:9;28652:18;28644:26;;28716:9;28710:4;28706:20;28702:1;28691:9;28687:17;28680:47;28744:131;28870:4;28744:131;:::i;:::-;28736:139;;28463:419;;;:::o;28888:332::-;29009:4;29047:2;29036:9;29032:18;29024:26;;29060:71;29128:1;29117:9;29113:17;29104:6;29060:71;:::i;:::-;29141:72;29209:2;29198:9;29194:18;29185:6;29141:72;:::i;:::-;28888:332;;;;;:::o;29226:137::-;29280:5;29311:6;29305:13;29296:22;;29327:30;29351:5;29327:30;:::i;:::-;29226:137;;;;:::o;29369:345::-;29436:6;29485:2;29473:9;29464:7;29460:23;29456:32;29453:119;;;29491:79;;:::i;:::-;29453:119;29611:1;29636:61;29689:7;29680:6;29669:9;29665:22;29636:61;:::i;:::-;29626:71;;29582:125;29369:345;;;;:::o;29720:180::-;29768:77;29765:1;29758:88;29865:4;29862:1;29855:15;29889:4;29886:1;29879:15;29906:98;29957:6;29991:5;29985:12;29975:22;;29906:98;;;:::o;30010:168::-;30093:11;30127:6;30122:3;30115:19;30167:4;30162:3;30158:14;30143:29;;30010:168;;;;:::o;30184:373::-;30270:3;30298:38;30330:5;30298:38;:::i;:::-;30352:70;30415:6;30410:3;30352:70;:::i;:::-;30345:77;;30431:65;30489:6;30484:3;30477:4;30470:5;30466:16;30431:65;:::i;:::-;30521:29;30543:6;30521:29;:::i;:::-;30516:3;30512:39;30505:46;;30274:283;30184:373;;;;:::o;30563:640::-;30758:4;30796:3;30785:9;30781:19;30773:27;;30810:71;30878:1;30867:9;30863:17;30854:6;30810:71;:::i;:::-;30891:72;30959:2;30948:9;30944:18;30935:6;30891:72;:::i;:::-;30973;31041:2;31030:9;31026:18;31017:6;30973:72;:::i;:::-;31092:9;31086:4;31082:20;31077:2;31066:9;31062:18;31055:48;31120:76;31191:4;31182:6;31120:76;:::i;:::-;31112:84;;30563:640;;;;;;;:::o;31209:141::-;31265:5;31296:6;31290:13;31281:22;;31312:32;31338:5;31312:32;:::i;:::-;31209:141;;;;:::o;31356:349::-;31425:6;31474:2;31462:9;31453:7;31449:23;31445:32;31442:119;;;31480:79;;:::i;:::-;31442:119;31600:1;31625:63;31680:7;31671:6;31660:9;31656:22;31625:63;:::i;:::-;31615:73;;31571:127;31356:349;;;;:::o

Swarm Source

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