ETH Price: $3,301.40 (-3.02%)
 

Overview

Max Total Supply

129 Tutankhamun's Iron Dagger

Holders

70

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 Tutankhamun's Iron Dagger
0x8E2B98581cA8Ef517dE8E443322d9aF89a1aF380
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:
Tutankhamuns_Iron_Dagger

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-10-19
*/

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.20;

/**
 * @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 v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

    /**
     * @dev Returns the 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 towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (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 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                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.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 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.

            uint256 twos = denominator & (0 - denominator);
            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 (unsignedRoundsUp(rounding) && 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
     * towards zero.
     *
     * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)

pragma solidity ^0.8.20;



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

    /**
     * @dev The `value` string doesn't fit in the specified `length`.
     */
    error StringsInsufficientHexLength(uint256 value, uint256 length);

    /**
     * @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), HEX_DIGITS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toStringSigned(int256 value) internal pure returns (string memory) {
        return string.concat(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) {
        uint256 localValue = value;
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = HEX_DIGITS[localValue & 0xf];
            localValue >>= 4;
        }
        if (localValue != 0) {
            revert StringsInsufficientHexLength(value, length);
        }
        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 bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.20;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS
    }

    /**
     * @dev The signature derives the `address(0)`.
     */
    error ECDSAInvalidSignature();

    /**
     * @dev The signature has an invalid length.
     */
    error ECDSAInvalidSignatureLength(uint256 length);

    /**
     * @dev The signature has an S value that is in the upper half order.
     */
    error ECDSAInvalidSignatureS(bytes32 s);

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
     * return address(0) without also returning an error description. Errors are documented using an enum (error type)
     * and a bytes32 providing additional information about the error.
     *
     * If no error is returned, then the address can be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
        unchecked {
            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
            // We do not check for an overflow here since the shift operation results in 0 or 1.
            uint8 v = uint8((uint256(vs) >> 255) + 27);
            return tryRecover(hash, v, r, s);
        }
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError, bytes32) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS, s);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature, bytes32(0));
        }

        return (signer, RecoverError.NoError, bytes32(0));
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
     */
    function _throwError(RecoverError error, bytes32 errorArg) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert ECDSAInvalidSignature();
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert ECDSAInvalidSignatureLength(uint256(errorArg));
        } else if (error == RecoverError.InvalidSignatureS) {
            revert ECDSAInvalidSignatureS(errorArg);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/access/OwnablePermissions.sol


pragma solidity ^0.8.4;


abstract contract OwnablePermissions is Context {
    function _requireCallerIsContractOwner() internal view virtual;
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _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: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/access/OwnableBasic.sol



pragma solidity ^0.8.4;



abstract contract OwnableBasic is OwnablePermissions, Ownable {
    function _requireCallerIsContractOwner() internal view virtual override {
        _checkOwner();
    }
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

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

// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/IEOARegistry.sol


pragma solidity ^0.8.4;


interface IEOARegistry is IERC165 {
    function isVerifiedEOA(address account) external view returns (bool);
}
// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/utils/TransferPolicy.sol


pragma solidity ^0.8.4;

enum AllowlistTypes {
    Operators,
    PermittedContractReceivers
}

enum ReceiverConstraints {
    None,
    NoCode,
    EOA
}

enum CallerConstraints {
    None,
    OperatorWhitelistEnableOTC,
    OperatorWhitelistDisableOTC
}

enum StakerConstraints {
    None,
    CallerIsTxOrigin,
    EOA
}

enum TransferSecurityLevels {
    Zero,
    One,
    Two,
    Three,
    Four,
    Five,
    Six
}

struct TransferSecurityPolicy {
    CallerConstraints callerConstraints;
    ReceiverConstraints receiverConstraints;
}

struct CollectionSecurityPolicy {
    TransferSecurityLevels transferSecurityLevel;
    uint120 operatorWhitelistId;
    uint120 permittedContractReceiversId;
}

// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ITransferSecurityRegistry.sol


pragma solidity ^0.8.4;


interface ITransferSecurityRegistry {
    event AddedToAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account);
    event CreatedAllowlist(AllowlistTypes indexed kind, uint256 indexed id, string indexed name);
    event ReassignedAllowlistOwnership(AllowlistTypes indexed kind, uint256 indexed id, address indexed newOwner);
    event RemovedFromAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account);
    event SetAllowlist(AllowlistTypes indexed kind, address indexed collection, uint120 indexed id);
    event SetTransferSecurityLevel(address indexed collection, TransferSecurityLevels level);

    function createOperatorWhitelist(string calldata name) external returns (uint120);
    function createPermittedContractReceiverAllowlist(string calldata name) external returns (uint120);
    function reassignOwnershipOfOperatorWhitelist(uint120 id, address newOwner) external;
    function reassignOwnershipOfPermittedContractReceiverAllowlist(uint120 id, address newOwner) external;
    function renounceOwnershipOfOperatorWhitelist(uint120 id) external;
    function renounceOwnershipOfPermittedContractReceiverAllowlist(uint120 id) external;
    function setTransferSecurityLevelOfCollection(address collection, TransferSecurityLevels level) external;
    function setOperatorWhitelistOfCollection(address collection, uint120 id) external;
    function setPermittedContractReceiverAllowlistOfCollection(address collection, uint120 id) external;
    function addOperatorToWhitelist(uint120 id, address operator) external;
    function addPermittedContractReceiverToAllowlist(uint120 id, address receiver) external;
    function removeOperatorFromWhitelist(uint120 id, address operator) external;
    function removePermittedContractReceiverFromAllowlist(uint120 id, address receiver) external;
    function getCollectionSecurityPolicy(address collection) external view returns (CollectionSecurityPolicy memory);
    function getWhitelistedOperators(uint120 id) external view returns (address[] memory);
    function getPermittedContractReceivers(uint120 id) external view returns (address[] memory);
    function isOperatorWhitelisted(uint120 id, address operator) external view returns (bool);
    function isContractReceiverPermitted(uint120 id, address receiver) external view returns (bool);
}
// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ITransferValidator.sol


pragma solidity ^0.8.4;


interface ITransferValidator {
    function applyCollectionTransferPolicy(address caller, address from, address to) external view;
}
// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ICreatorTokenTransferValidator.sol


pragma solidity ^0.8.4;




interface ICreatorTokenTransferValidator is ITransferSecurityRegistry, ITransferValidator, IEOARegistry {}
// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ICreatorToken.sol


pragma solidity ^0.8.4;


interface ICreatorToken {
    event TransferValidatorUpdated(address oldValidator, address newValidator);

    function getTransferValidator() external view returns (ICreatorTokenTransferValidator);
    function getSecurityPolicy() external view returns (CollectionSecurityPolicy memory);
    function getWhitelistedOperators() external view returns (address[] memory);
    function getPermittedContractReceivers() external view returns (address[] memory);
    function isOperatorWhitelisted(address operator) external view returns (bool);
    function isContractReceiverPermitted(address receiver) external view returns (bool);
    function isTransferAllowed(address caller, address from, address to) external view returns (bool);
}

// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/utils/TransferValidation.sol


pragma solidity ^0.8.4;


/**
 * @title TransferValidation
 * @author Limit Break, Inc.
 * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks.
 * Openzeppelin's ERC721 contract only provides hooks for before and after transfer.  This allows
 * developers to validate or customize transfers within the context of a mint, a burn, or a transfer.
 */
abstract contract TransferValidation is Context {
    
    error ShouldNotMintToBurnAddress();

    /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks.
    function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _preValidateMint(_msgSender(), to, tokenId, msg.value);
        } else if(toZeroAddress) {
            _preValidateBurn(_msgSender(), from, tokenId, msg.value);
        } else {
            _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
        }
    }

    /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks.
    function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _postValidateMint(_msgSender(), to, tokenId, msg.value);
        } else if(toZeroAddress) {
            _postValidateBurn(_msgSender(), from, tokenId, msg.value);
        } else {
            _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
        }
    }

    /// @dev Optional validation hook that fires before a mint
    function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a mint
    function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a burn
    function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a burn
    function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a transfer
    function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a transfer
    function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}
}

// File: @openzeppelin/contracts/interfaces/IERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)

pragma solidity ^0.8.20;


// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/utils/CreatorTokenBase.sol


pragma solidity ^0.8.4;






/**
 * @title CreatorTokenBase
 * @author Limit Break, Inc.
 * @notice CreatorTokenBase is an abstract contract that provides basic functionality for managing token 
 * transfer policies through an implementation of ICreatorTokenTransferValidator. This contract is intended to be used
 * as a base for creator-specific token contracts, enabling customizable transfer restrictions and security policies.
 *
 * <h4>Features:</h4>
 * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul>
 * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul>
 * <ul>ICreatorToken: Implements the interface for creator tokens, providing view functions for token security policies.</ul>
 *
 * <h4>Benefits:</h4>
 * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul>
 * <ul>Allows creators to enforce policies such as whitelisted operators and permitted contract receivers.</ul>
 * <ul>Can be easily integrated into other token contracts as a base contract.</ul>
 *
 * <h4>Intended Usage:</h4>
 * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and 
 *   security policies.</ul>
 * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the 
 *   creator token.</ul>
 */
abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken {
    
    error CreatorTokenBase__InvalidTransferValidatorContract();
    error CreatorTokenBase__SetTransferValidatorFirst();

    address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x0000721C310194CcfC01E523fc93C9cCcFa2A0Ac);
    TransferSecurityLevels public constant DEFAULT_TRANSFER_SECURITY_LEVEL = TransferSecurityLevels.One;
    uint120 public constant DEFAULT_OPERATOR_WHITELIST_ID = uint120(1);

    ICreatorTokenTransferValidator private transferValidator;

    /**
     * @notice Allows the contract owner to set the transfer validator to the official validator contract
     *         and set the security policy to the recommended default settings.
     * @dev    May be overridden to change the default behavior of an individual collection.
     */
    function setToDefaultSecurityPolicy() public virtual {
        _requireCallerIsContractOwner();
        setTransferValidator(DEFAULT_TRANSFER_VALIDATOR);
        ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setTransferSecurityLevelOfCollection(address(this), DEFAULT_TRANSFER_SECURITY_LEVEL);
        ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setOperatorWhitelistOfCollection(address(this), DEFAULT_OPERATOR_WHITELIST_ID);
    }

    /**
     * @notice Allows the contract owner to set the transfer validator to a custom validator contract
     *         and set the security policy to their own custom settings.
     */
    function setToCustomValidatorAndSecurityPolicy(
        address validator, 
        TransferSecurityLevels level, 
        uint120 operatorWhitelistId, 
        uint120 permittedContractReceiversAllowlistId) public {
        _requireCallerIsContractOwner();

        setTransferValidator(validator);

        ICreatorTokenTransferValidator(validator).
            setTransferSecurityLevelOfCollection(address(this), level);

        ICreatorTokenTransferValidator(validator).
            setOperatorWhitelistOfCollection(address(this), operatorWhitelistId);

        ICreatorTokenTransferValidator(validator).
            setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId);
    }

    /**
     * @notice Allows the contract owner to set the security policy to their own custom settings.
     * @dev    Reverts if the transfer validator has not been set.
     */
    function setToCustomSecurityPolicy(
        TransferSecurityLevels level, 
        uint120 operatorWhitelistId, 
        uint120 permittedContractReceiversAllowlistId) public {
        _requireCallerIsContractOwner();

        ICreatorTokenTransferValidator validator = getTransferValidator();
        if (address(validator) == address(0)) {
            revert CreatorTokenBase__SetTransferValidatorFirst();
        }

        validator.setTransferSecurityLevelOfCollection(address(this), level);
        validator.setOperatorWhitelistOfCollection(address(this), operatorWhitelistId);
        validator.setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId);
    }

    /**
     * @notice Sets the transfer validator for the token contract.
     *
     * @dev    Throws when provided validator contract is not the zero address and doesn't support 
     *         the ICreatorTokenTransferValidator interface. 
     * @dev    Throws when the caller is not the contract owner.
     *
     * @dev    <h4>Postconditions:</h4>
     *         1. The transferValidator address is updated.
     *         2. The `TransferValidatorUpdated` event is emitted.
     *
     * @param transferValidator_ The address of the transfer validator contract.
     */
    function setTransferValidator(address transferValidator_) public {
        _requireCallerIsContractOwner();

        bool isValidTransferValidator = false;

        if(transferValidator_.code.length > 0) {
            try IERC165(transferValidator_).supportsInterface(type(ICreatorTokenTransferValidator).interfaceId) 
                returns (bool supportsInterface) {
                isValidTransferValidator = supportsInterface;
            } catch {}
        }

        if(transferValidator_ != address(0) && !isValidTransferValidator) {
            revert CreatorTokenBase__InvalidTransferValidatorContract();
        }

        emit TransferValidatorUpdated(address(transferValidator), transferValidator_);

        transferValidator = ICreatorTokenTransferValidator(transferValidator_);
    }

    /**
     * @notice Returns the transfer validator contract address for this token contract.
     */
    function getTransferValidator() public view override returns (ICreatorTokenTransferValidator) {
        return transferValidator;
    }

    /**
     * @notice Returns the security policy for this token contract, which includes:
     *         Transfer security level, operator whitelist id, permitted contract receiver allowlist id.
     */
    function getSecurityPolicy() public view override returns (CollectionSecurityPolicy memory) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.getCollectionSecurityPolicy(address(this));
        }

        return CollectionSecurityPolicy({
            transferSecurityLevel: TransferSecurityLevels.Zero,
            operatorWhitelistId: 0,
            permittedContractReceiversId: 0
        });
    }

    /**
     * @notice Returns the list of all whitelisted operators for this token contract.
     * @dev    This can be an expensive call and should only be used in view-only functions.
     */
    function getWhitelistedOperators() public view override returns (address[] memory) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.getWhitelistedOperators(
                transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId);
        }

        return new address[](0);
    }

    /**
     * @notice Returns the list of permitted contract receivers for this token contract.
     * @dev    This can be an expensive call and should only be used in view-only functions.
     */
    function getPermittedContractReceivers() public view override returns (address[] memory) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.getPermittedContractReceivers(
                transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId);
        }

        return new address[](0);
    }

    /**
     * @notice Checks if an operator is whitelisted for this token contract.
     * @param operator The address of the operator to check.
     */
    function isOperatorWhitelisted(address operator) public view override returns (bool) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.isOperatorWhitelisted(
                transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId, operator);
        }

        return false;
    }

    /**
     * @notice Checks if a contract receiver is permitted for this token contract.
     * @param receiver The address of the receiver to check.
     */
    function isContractReceiverPermitted(address receiver) public view override returns (bool) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.isContractReceiverPermitted(
                transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId, receiver);
        }

        return false;
    }

    /**
     * @notice Determines if a transfer is allowed based on the token contract's security policy.  Use this function
     *         to simulate whether or not a transfer made by the specified `caller` from the `from` address to the `to`
     *         address would be allowed by this token's security policy.
     *
     * @notice This function only checks the security policy restrictions and does not check whether token ownership
     *         or approvals are in place. 
     *
     * @param caller The address of the simulated caller.
     * @param from   The address of the sender.
     * @param to     The address of the receiver.
     * @return       True if the transfer is allowed, false otherwise.
     */
    function isTransferAllowed(address caller, address from, address to) public view override returns (bool) {
        if (address(transferValidator) != address(0)) {
            try transferValidator.applyCollectionTransferPolicy(caller, from, to) {
                return true;
            } catch {
                return false;
            }
        }
        return true;
    }

    /**
     * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy.
     *      Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent
     *      and calling _validateBeforeTransfer so that checks can be properly applied during token transfers.
     *
     * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is
     *      set to a non-zero address.
     *
     * @param caller  The address of the caller.
     * @param from    The address of the sender.
     * @param to      The address of the receiver.
     */
    function _preValidateTransfer(
        address caller, 
        address from, 
        address to, 
        uint256 /*tokenId*/, 
        uint256 /*value*/) internal virtual override {
        if (address(transferValidator) != address(0)) {
            transferValidator.applyCollectionTransferPolicy(caller, from, to);
        }
    }
}

// File: erc721a/contracts/IERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * `_sequentialUpTo()` must be greater than `_startTokenId()`.
     */
    error SequentialUpToTooSmall();

    /**
     * The `tokenId` of a sequential mint exceeds `_sequentialUpTo()`.
     */
    error SequentialMintExceedsLimit();

    /**
     * Spot minting requires a `tokenId` greater than `_sequentialUpTo()`.
     */
    error SpotMintTokenIdTooSmall();

    /**
     * Cannot mint over a token that already exists.
     */
    error TokenAlreadyExists();

    /**
     * The feature is not compatible with spot mints.
     */
    error NotCompatibleWithSpotMints();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/ERC721A.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

    // The amount of tokens minted above `_sequentialUpTo()`.
    // We call these spot mints (i.e. non-sequential mints).
    uint256 private _spotMinted;

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

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

        if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector);
    }

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

    /**
     * @dev Returns the starting token ID for sequential mints.
     *
     * Override this function to change the starting token ID for sequential mints.
     *
     * Note: The value returned must never change after any tokens have been minted.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 1;
    }

    /**
     * @dev Returns the maximum token ID (inclusive) for sequential mints.
     *
     * Override this function to return a value less than 2**256 - 1,
     * but greater than `_startTokenId()`, to enable spot (non-sequential) mints.
     *
     * Note: The value returned must never change after any tokens have been minted.
     */
    function _sequentialUpTo() internal view virtual returns (uint256) {
        return type(uint256).max;
    }

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

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256 result) {
        // Counter underflow is impossible as `_burnCounter` cannot be incremented
        // more than `_currentIndex + _spotMinted - _startTokenId()` times.
        unchecked {
            // With spot minting, the intermediate `result` can be temporarily negative,
            // and the computation must be unchecked.
            result = _currentIndex - _burnCounter - _startTokenId();
            if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;
        }
    }

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

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

    /**
     * @dev Returns the total number of tokens that are spot-minted.
     */
    function _totalSpotMinted() internal view virtual returns (uint256) {
        return _spotMinted;
    }

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

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

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

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

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

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

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

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

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

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

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

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

        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, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

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

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

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

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

    /**
     * @dev Returns whether the ownership slot at `index` is initialized.
     * An uninitialized slot does not necessarily mean that the slot has no owner.
     */
    function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) {
        return _packedOwnerships[index] != 0;
    }

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

    /**
     * @dev Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {
        if (_startTokenId() <= tokenId) {
            packed = _packedOwnerships[tokenId];

            if (tokenId > _sequentialUpTo()) {
                if (_packedOwnershipExists(packed)) return packed;
                _revert(OwnerQueryForNonexistentToken.selector);
            }

            // If the data at the starting slot does not exist, start the scan.
            if (packed == 0) {
                if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector);
                // Invariant:
                // There will always be an initialized ownership slot
                // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                // before an unintialized ownership slot
                // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                // Hence, `tokenId` will not underflow.
                //
                // We can directly compare the packed value.
                // If the address is zero, packed will be zero.
                for (;;) {
                    unchecked {
                        packed = _packedOwnerships[--tokenId];
                    }
                    if (packed == 0) continue;
                    if (packed & _BITMASK_BURNED == 0) return packed;
                    // Otherwise, the token is burned, and we must revert.
                    // This handles the case of batch burned tokens, where only the burned bit
                    // of the starting slot is set, and remaining slots are left uninitialized.
                    _revert(OwnerQueryForNonexistentToken.selector);
                }
            }
            // Otherwise, the data exists and we can skip the scan.
            // This is possible because we have already achieved the target condition.
            // This saves 2143 gas on transfers of initialized tokens.
            // If the token is not burned, return `packed`. Otherwise, revert.
            if (packed & _BITMASK_BURNED == 0) return packed;
        }
        _revert(OwnerQueryForNonexistentToken.selector);
    }

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

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

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

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

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     */
    function approve(address to, uint256 tokenId) public payable virtual override {
        _approve(to, tokenId, true);
    }

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

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool result) {
        if (_startTokenId() <= tokenId) {
            if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]);

            if (tokenId < _currentIndex) {
                uint256 packed;
                while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId;
                result = packed & _BITMASK_BURNED == 0;
            }
        }
    }

    /**
     * @dev Returns whether `packed` represents a token that exists.
     */
    function _packedOwnershipExists(uint256 packed) private pure returns (bool result) {
        assembly {
            // The following is equivalent to `owner != address(0) && burned == false`.
            // Symbolically tested.
            result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_BURNED))
        }
    }

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

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

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
        from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));

        if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector);

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

        // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
        uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
        assembly {
            // Emit the `Transfer` event.
            log4(
                0, // Start of data (0, since no data).
                0, // End of data (0, since no data).
                _TRANSFER_EVENT_SIGNATURE, // Signature.
                from, // `from`.
                toMasked, // `to`.
                tokenId // `tokenId`.
            )
        }
        if (toMasked == 0) _revert(TransferToZeroAddress.selector);

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                _revert(TransferToNonERC721ReceiverImplementer.selector);
            }
    }

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

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

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

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

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

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

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
            uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;

            if (toMasked == 0) _revert(MintToZeroAddress.selector);

            uint256 end = startTokenId + quantity;
            uint256 tokenId = startTokenId;

            if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);

            do {
                assembly {
                    // Emit the `Transfer` event.
                    log4(
                        0, // Start of data (0, since no data).
                        0, // End of data (0, since no data).
                        _TRANSFER_EVENT_SIGNATURE, // Signature.
                        0, // `address(0)`.
                        toMasked, // `to`.
                        tokenId // `tokenId`.
                    )
                }
                // The `!=` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
            } while (++tokenId != end);

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

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

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

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

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

            if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);

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

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

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

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        _revert(TransferToNonERC721ReceiverImplementer.selector);
                    }
                } while (index < end);
                // This prevents reentrancy to `_safeMint`.
                // It does not prevent reentrancy to `_safeMintSpot`.
                if (_currentIndex != end) revert();
            }
        }
    }

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

    /**
     * @dev Mints a single token at `tokenId`.
     *
     * Note: A spot-minted `tokenId` that has been burned can be re-minted again.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` must be greater than `_sequentialUpTo()`.
     * - `tokenId` must not exist.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mintSpot(address to, uint256 tokenId) internal virtual {
        if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector);
        uint256 prevOwnershipPacked = _packedOwnerships[tokenId];
        if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector);

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

        // Overflows are incredibly unrealistic.
        // The `numberMinted` for `to` is incremented by 1, and has a max limit of 2**64 - 1.
        // `_spotMinted` is incremented by 1, and has a max limit of 2**256 - 1.
        unchecked {
            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `true` (as `quantity == 1`).
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked)
            );

            // Updates:
            // - `balance += 1`.
            // - `numberMinted += 1`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1;

            // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
            uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;

            if (toMasked == 0) _revert(MintToZeroAddress.selector);

            assembly {
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    tokenId // `tokenId`.
                )
            }

            ++_spotMinted;
        }

        _afterTokenTransfers(address(0), to, tokenId, 1);
    }

    /**
     * @dev Safely mints a single token at `tokenId`.
     *
     * Note: A spot-minted `tokenId` that has been burned can be re-minted again.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}.
     * - `tokenId` must be greater than `_sequentialUpTo()`.
     * - `tokenId` must not exist.
     *
     * See {_mintSpot}.
     *
     * Emits a {Transfer} event.
     */
    function _safeMintSpot(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mintSpot(to, tokenId);

        unchecked {
            if (to.code.length != 0) {
                uint256 currentSpotMinted = _spotMinted;
                if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) {
                    _revert(TransferToNonERC721ReceiverImplementer.selector);
                }
                // This prevents reentrancy to `_safeMintSpot`.
                // It does not prevent reentrancy to `_safeMint`.
                if (_spotMinted != currentSpotMinted) revert();
            }
        }
    }

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

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

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

    /**
     * @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:
     *
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        bool approvalCheck
    ) internal virtual {
        address owner = ownerOf(tokenId);

        if (approvalCheck && _msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                _revert(ApprovalCallerNotOwnerNorApproved.selector);
            }

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev For more efficient reverts.
     */
    function _revert(bytes4 errorSelector) internal pure {
        assembly {
            mstore(0x00, errorSelector)
            revert(0x00, 0x04)
        }
    }
}

// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/erc721c/ERC721AC.sol


pragma solidity ^0.8.4;



/**
 * @title ERC721AC
 * @author Limit Break, Inc.
 * @notice Extends Azuki's ERC721-A implementation with Creator Token functionality, which
 *         allows the contract owner to update the transfer validation logic by managing a security policy in
 *         an external transfer validation security policy registry.  See {CreatorTokenTransferValidator}.
 */
abstract contract ERC721AC is ERC721A, CreatorTokenBase {

    constructor(string memory name_, string memory symbol_) CreatorTokenBase() ERC721A(name_, symbol_) {}

    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(ICreatorToken).interfaceId || super.supportsInterface(interfaceId);
    }

    /// @dev Ties the erc721a _beforeTokenTransfers hook to more granular transfer validation logic
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual override {
        for (uint256 i = 0; i < quantity;) {
            _validateBeforeTransfer(from, to, startTokenId + i);
            unchecked {
                ++i;
            }
        }
    }

    /// @dev Ties the erc721a _afterTokenTransfer hook to more granular transfer validation logic
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual override {
        for (uint256 i = 0; i < quantity;) {
            _validateAfterTransfer(from, to, startTokenId + i);
            unchecked {
                ++i;
            }
        }
    }

    function _msgSenderERC721A() internal view virtual override returns (address) {
        return _msgSender();
    }
}

// File: @openzeppelin/contracts/interfaces/IERC2981.sol


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.20;


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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;


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

// File: @openzeppelin/contracts/token/common/ERC2981.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.20;



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

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

    /**
     * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1).
     */
    error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);

    /**
     * @dev The default royalty receiver is invalid.
     */
    error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);

    /**
     * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).
     */
    error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);

    /**
     * @dev The royalty receiver for `tokenId` is invalid.
     */
    error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);

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

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

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

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

        return (royalty.receiver, royaltyAmount);
    }

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

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        uint256 denominator = _feeDenominator();
        if (feeNumerator > denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));
        }

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

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

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
        uint256 denominator = _feeDenominator();
        if (feeNumerator > denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));
        }

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

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

// File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/programmable-royalties/BasicRoyalties.sol


pragma solidity ^0.8.4;


/**
 * @title BasicRoyaltiesBase
 * @author Limit Break, Inc.
 * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties.
 */
abstract contract BasicRoyaltiesBase is ERC2981 {

    event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator);
    event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator);

    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override {
        super._setDefaultRoyalty(receiver, feeNumerator);
        emit DefaultRoyaltySet(receiver, feeNumerator);
    }

    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override {
        super._setTokenRoyalty(tokenId, receiver, feeNumerator);
        emit TokenRoyaltySet(tokenId, receiver, feeNumerator);
    }
}

/**
 * @title BasicRoyalties
 * @author Limit Break, Inc.
 * @notice Constructable BasicRoyalties Contract implementation.
 */
abstract contract BasicRoyalties is BasicRoyaltiesBase {
    constructor(address receiver, uint96 feeNumerator) {
        _setDefaultRoyalty(receiver, feeNumerator);
    }
}

/**
 * @title BasicRoyaltiesInitializable
 * @author Limit Break, Inc.
 * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. 
 */
abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {}
// File: tutdagger.sol


/**
 *Submitted for verification at Etherscan.io on 2024-04-03
*/

// File: @openzeppelin/contracts/cryptography/MerkleProof.sol



pragma solidity ^0.8.25;
// File: @openzeppelin/contracts/utils/math/SignedMath.sol







error AlreadyReservedTokens();
error CallerNotOffsetter();
error FunctionLocked();
error InsufficientValue();
error InsufficientMints();
error InsufficientSupply();
error InvalidSignature();
error NoContractMinting();
error ProvenanceHashAlreadySet();
error ProvenanceHashNotSet();
error TokenOffsetAlreadySet();
error TokenOffsetNotSet();
error WithdrawFailed();

interface Offsetable {
    function setOffset(uint256 randomness) external;
}

contract Tutankhamuns_Iron_Dagger is ERC721AC, BasicRoyalties, Ownable, OwnableBasic{
    using ECDSA for bytes32;

    string private _baseTokenURI;
    string public provenanceHash;
    bool public operatorFilteringEnabled;
    string public baseExtension = ".json";
    uint256 public mintPrice = 0.016 ether;
    uint256 public constant RESERVED = 35;
    uint256 startTime;
    bool minting;
    mapping(bytes4 => bool) public functionLocked;
    mapping(address => bool) public minter;



    constructor(address initialOwner, address royaltyReceiver_, uint96 royaltyFeeNumerator_, address _minter) ERC721AC("Tutankhamun's Iron Dagger", "Tutankhamun's Iron Dagger") 
        BasicRoyalties(royaltyReceiver_, royaltyFeeNumerator_) Ownable(initialOwner){

            minter[_minter] = true;
    }

    /**
     * @notice Modifier applied to functions that will be disabled when they're no longer needed
     */
    modifier lockable() {
        if (functionLocked[msg.sig]) revert FunctionLocked();
        _;
    }

    modifier onlyMinter() {
        require(minter[msg.sender] == true, "You're not a minter");
        _;
    }
    

    /**
     * @notice Mint `RESERVED` amount of tokens to an address
     * @param to Address to send the reserved tokens
     */
        function reserve(address to) external lockable onlyOwner {
        if (_totalMinted() >= RESERVED) revert AlreadyReservedTokens();
        _mint(to, RESERVED);
    }

        function secondaryReserve(address to, uint256 quan)  external onlyMinter {
        require(minting == true,"Minting is not started yet");
        require(block.timestamp <= startTime + 24 hours, "Minting Times up");
        _mint(to, quan);
    }

    function publicMint(address to, uint256 quantity) external payable {
        require(minting == true,"Minting is not started yet");
        require(block.timestamp <= startTime + 24 hours, "Minting Times up");
        uint256 totalCost = quantity * mintPrice;
        require(msg.value >= totalCost, "Ether sent is not correct.");
        _mint(to, quantity);
        if (msg.value > totalCost) {
            payable(msg.sender).transfer(msg.value - totalCost);
        }
    }

    function setDefaultRoyalty(address receiver, uint96 feeNumerator) public onlyOwner{
        _requireCallerIsContractOwner();
        _setDefaultRoyalty(receiver, feeNumerator);
    }

    function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) public onlyOwner{
        _requireCallerIsContractOwner();
        _setTokenRoyalty(tokenId, receiver, feeNumerator);
    }

    function enableMint(bool _enable) external onlyOwner{
        minting = _enable;
        startTime = block.timestamp;
    }


    /**
     * @inheritdoc ERC721AC
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721AC, ERC2981)
        returns (bool)
    {
        return
            ERC721AC.supportsInterface(interfaceId);
    }

    /**
     * @notice Override ERC721AC _baseURI function to use base URI pattern
     */
    function _baseURI() internal view virtual override returns (string memory) {
        return _baseTokenURI;
    }

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

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

    /**
     * @notice Return the number of tokens an address has minted
     * @param account Address to return the number of tokens minted for
     */
    function numberMinted(address account) external view returns (uint256) {
        return _numberMinted(account);
    }

    /**
     * @notice Lock a function so that it can no longer be called
     * @dev WARNING: THIS CANNOT BE UNDONE
     * @param id Function signature
     */
    function lockFunction(bytes4 id) external onlyOwner {
        functionLocked[id] = true;
    }

    /**
     * @notice Set the state of the OpenSea operator filter
     * @param value Flag indicating if the operator filter should be applied to transfers and approvals
     */
    function setOperatorFilteringEnabled(bool value)
        external
        lockable
        onlyOwner
    {
        operatorFilteringEnabled = value;
    }
    /**
     * @notice Set token metadata base URI
     * @param _newBaseURI New base URI
     */
    function setBaseURI(string calldata _newBaseURI)
        external
        lockable
    {
        _baseTokenURI = _newBaseURI;
    }

    /**
     * @notice Set provenance hash for the collection
     * @param _provenanceHash New hash of the metadata
     */
    function setProvenanceHash(string calldata _provenanceHash)
        external
        lockable
        onlyOwner
    {
        if (bytes(provenanceHash).length != 0)
            revert ProvenanceHashAlreadySet();

        provenanceHash = _provenanceHash;
    }

    function setMintPrice(uint256 _price) external onlyOwner{
        mintPrice = _price;
    }

    /**
     * @notice Withdraw all ETH sent to the contract
     */
    function withdraw() external onlyOwner {
        (bool success, ) = payable(msg.sender).call{
            value: address(this).balance
        }("");
        if (!success) revert WithdrawFailed();
    }


    function setApprovalForAll(address operator, bool approved)
        public
        override
    {
        super.setApprovalForAll(operator, approved);
    }


    function approve(address operator, uint256 tokenId)
        public
        payable
        override
    {
        super.approve(operator, tokenId);
    }


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


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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"address","name":"royaltyReceiver_","type":"address"},{"internalType":"uint96","name":"royaltyFeeNumerator_","type":"uint96"},{"internalType":"address","name":"_minter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyReservedTokens","type":"error"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CreatorTokenBase__InvalidTransferValidatorContract","type":"error"},{"inputs":[],"name":"CreatorTokenBase__SetTransferValidatorFirst","type":"error"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[],"name":"FunctionLocked","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"ProvenanceHashAlreadySet","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"ShouldNotMintToBurnAddress","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","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"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"DefaultRoyaltySet","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":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"TokenRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_OPERATOR_WHITELIST_ID","outputs":[{"internalType":"uint120","name":"","type":"uint120"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_TRANSFER_SECURITY_LEVEL","outputs":[{"internalType":"enum TransferSecurityLevels","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_TRANSFER_VALIDATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESERVED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_enable","type":"bool"}],"name":"enableMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"functionLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPermittedContractReceivers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSecurityPolicy","outputs":[{"components":[{"internalType":"enum TransferSecurityLevels","name":"transferSecurityLevel","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversId","type":"uint120"}],"internalType":"struct CollectionSecurityPolicy","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"contract ICreatorTokenTransferValidator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistedOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"isContractReceiverPermitted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"isOperatorWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"isTransferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"id","type":"bytes4"}],"name":"lockFunction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"provenanceHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"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":"to","type":"address"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quan","type":"uint256"}],"name":"secondaryReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenanceHash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversAllowlistId","type":"uint120"}],"name":"setToCustomSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversAllowlistId","type":"uint120"}],"name":"setToCustomValidatorAndSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setToDefaultSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferValidator_","type":"address"}],"name":"setTransferValidator","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":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250601090816100489190610792565b506638d7ea4c68000060115534801561005f575f80fd5b5060405161652838038061652883398181016040528101906100819190610900565b8383836040518060400160405280601981526020017f547574616e6b68616d756e27732049726f6e20446167676572000000000000008152506040518060400160405280601981526020017f547574616e6b68616d756e27732049726f6e2044616767657200000000000000815250818181600290816101019190610792565b5080600390816101119190610792565b5061012061025260201b60201c565b5f8190555061013361025260201b60201c565b61014161025a60201b60201c565b101561015e5761015d63fed8210f60e01b61028160201b60201c565b5b50505050610172828261028960201b60201c565b50505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101e4575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016101db9190610973565b60405180910390fd5b6101f3816102eb60201b60201c565b50600160155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050505050610a1a565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b805f5260045ffd5b61029982826103ae60201b60201c565b8173ffffffffffffffffffffffffffffffffffffffff167f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef826040516102df919061099b565b60405180910390a25050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f6103bd61054f60201b60201c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156104225781816040517f6f483d090000000000000000000000000000000000000000000000000000000081526004016104199291906109f3565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610492575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016104899190610973565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600a5f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f612710905090565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806105d357607f821691505b6020821081036105e6576105e561058f565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026106487fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261060d565b610652868361060d565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61069661069161068c8461066a565b610673565b61066a565b9050919050565b5f819050919050565b6106af8361067c565b6106c36106bb8261069d565b848454610619565b825550505050565b5f90565b6106d76106cb565b6106e28184846106a6565b505050565b5b81811015610705576106fa5f826106cf565b6001810190506106e8565b5050565b601f82111561074a5761071b816105ec565b610724846105fe565b81016020851015610733578190505b61074761073f856105fe565b8301826106e7565b50505b505050565b5f82821c905092915050565b5f61076a5f198460080261074f565b1980831691505092915050565b5f610782838361075b565b9150826002028217905092915050565b61079b82610558565b67ffffffffffffffff8111156107b4576107b3610562565b5b6107be82546105bc565b6107c9828285610709565b5f60209050601f8311600181146107fa575f84156107e8578287015190505b6107f28582610777565b865550610859565b601f198416610808866105ec565b5f5b8281101561082f5784890151825560018201915060208501945060208101905061080a565b8683101561084c5784890151610848601f89168261075b565b8355505b6001600288020188555050505b505050505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61088e82610865565b9050919050565b61089e81610884565b81146108a8575f80fd5b50565b5f815190506108b981610895565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b6108df816108bf565b81146108e9575f80fd5b50565b5f815190506108fa816108d6565b92915050565b5f805f806080858703121561091857610917610861565b5b5f610925878288016108ab565b9450506020610936878288016108ab565b9350506040610947878288016108ec565b9250506060610958878288016108ab565b91505092959194509250565b61096d81610884565b82525050565b5f6020820190506109865f830184610964565b92915050565b610995816108bf565b82525050565b5f6020820190506109ae5f83018461098c565b92915050565b5f6109ce6109c96109c4846108bf565b610673565b61066a565b9050919050565b6109de816109b4565b82525050565b6109ed8161066a565b82525050565b5f604082019050610a065f8301856109d5565b610a1360208301846109e4565b9392505050565b615b0180610a275f395ff3fe6080604052600436106102fe575f3560e01c806370a082311161018f578063c6682862116100db578063dc33e68111610094578063f2fde38b1161006e578063f2fde38b14610b33578063f4a0a52814610b5b578063fb796e6c14610b83578063fd762d9214610bad576102fe565b8063dc33e68114610a93578063e75179a414610acf578063e985e9c514610af7576102fe565b8063c668286214610995578063c68b3305146109bf578063c6ab67a3146109e7578063c87b56dd14610a11578063ce6df2b914610a4d578063d007af5c14610a69576102fe565b8063a22cb46511610148578063b7c0b8e811610122578063b7c0b8e8146108eb578063b88d4fde14610913578063bbadfe761461092f578063be537f431461096b576102fe565b8063a22cb46514610871578063a9fc664e14610899578063aa592f25146108c1576102fe565b806370a0823114610767578063715018a6146107a357806374d0101d146107b95780638da5cb5b146107e157806395d89b411461080b5780639d645a4414610835576102fe565b80632e8da8291161024e57806355f804b31161020757806361347162116101e157806361347162146106c35780636352211e146106eb5780636817c76c146107275780636c3b869914610751576102fe565b806355f804b3146106495780635944c753146106715780635d4c1d4614610699576102fe565b80632e8da8291461054d57806334531828146105895780633ccfd60b146105b15780633dd08c38146105c757806342842e0e14610603578063495c8bf91461061f576102fe565b8063098144d4116102bb5780631b25b077116102955780631b25b0771461048e5780631c33b328146104ca57806323b872dd146104f45780632a55205a14610510576102fe565b8063098144d414610412578063109695231461043c57806318160ddd14610464576102fe565b8063014635461461030257806301ffc9a71461032c57806304634d8d1461036857806306fdde0314610390578063081812fc146103ba578063095ea7b3146103f6575b5f80fd5b34801561030d575f80fd5b50610316610bd5565b604051610323919061440e565b60405180910390f35b348015610337575f80fd5b50610352600480360381019061034d919061448d565b610beb565b60405161035f91906144d2565b60405180910390f35b348015610373575f80fd5b5061038e60048036038101906103899190614556565b610bfc565b005b34801561039b575f80fd5b506103a4610c1a565b6040516103b19190614604565b60405180910390f35b3480156103c5575f80fd5b506103e060048036038101906103db9190614657565b610caa565b6040516103ed919061440e565b60405180910390f35b610410600480360381019061040b9190614682565b610d03565b005b34801561041d575f80fd5b50610426610d11565b604051610433919061471b565b60405180910390f35b348015610447575f80fd5b50610462600480360381019061045d9190614795565b610d39565b005b34801561046f575f80fd5b50610478610e54565b60405161048591906147ef565b60405180910390f35b348015610499575f80fd5b506104b460048036038101906104af9190614808565b610e9f565b6040516104c191906144d2565b60405180910390f35b3480156104d5575f80fd5b506104de610f9a565b6040516104eb91906148cb565b60405180910390f35b61050e600480360381019061050991906148e4565b610f9f565b005b34801561051b575f80fd5b5061053660048036038101906105319190614934565b610faf565b604051610544929190614972565b60405180910390f35b348015610558575f80fd5b50610573600480360381019061056e9190614999565b61118b565b60405161058091906144d2565b60405180910390f35b348015610594575f80fd5b506105af60048036038101906105aa919061448d565b611327565b005b3480156105bc575f80fd5b506105c5611399565b005b3480156105d2575f80fd5b506105ed60048036038101906105e89190614999565b611443565b6040516105fa91906144d2565b60405180910390f35b61061d600480360381019061061891906148e4565b611460565b005b34801561062a575f80fd5b50610633611470565b6040516106409190614a7b565b60405180910390f35b348015610654575f80fd5b5061066f600480360381019061066a9190614795565b611654565b005b34801561067c575f80fd5b5061069760048036038101906106929190614a9b565b611720565b005b3480156106a4575f80fd5b506106ad611740565b6040516106ba9190614b14565b60405180910390f35b3480156106ce575f80fd5b506106e960048036038101906106e49190614b7a565b611745565b005b3480156106f6575f80fd5b50610711600480360381019061070c9190614657565b6118fb565b60405161071e919061440e565b60405180910390f35b348015610732575f80fd5b5061073b61190c565b60405161074891906147ef565b60405180910390f35b34801561075c575f80fd5b50610765611912565b005b348015610772575f80fd5b5061078d60048036038101906107889190614999565b611a2d565b60405161079a91906147ef565b60405180910390f35b3480156107ae575f80fd5b506107b7611ac1565b005b3480156107c4575f80fd5b506107df60048036038101906107da9190614682565b611ad4565b005b3480156107ec575f80fd5b506107f5611c1a565b604051610802919061440e565b60405180910390f35b348015610816575f80fd5b5061081f611c42565b60405161082c9190614604565b60405180910390f35b348015610840575f80fd5b5061085b60048036038101906108569190614999565b611cd2565b60405161086891906144d2565b60405180910390f35b34801561087c575f80fd5b5061089760048036038101906108929190614bf4565b611e6e565b005b3480156108a4575f80fd5b506108bf60048036038101906108ba9190614999565b611e7c565b005b3480156108cc575f80fd5b506108d5612031565b6040516108e291906147ef565b60405180910390f35b3480156108f6575f80fd5b50610911600480360381019061090c9190614c32565b612036565b005b61092d60048036038101906109289190614d85565b612110565b005b34801561093a575f80fd5b506109556004803603810190610950919061448d565b612122565b60405161096291906144d2565b60405180910390f35b348015610976575f80fd5b5061097f61213f565b60405161098c9190614e63565b60405180910390f35b3480156109a0575f80fd5b506109a9612290565b6040516109b69190614604565b60405180910390f35b3480156109ca575f80fd5b506109e560048036038101906109e09190614c32565b61231c565b005b3480156109f2575f80fd5b506109fb612347565b604051610a089190614604565b60405180910390f35b348015610a1c575f80fd5b50610a376004803603810190610a329190614657565b6123d3565b604051610a449190614604565b60405180910390f35b610a676004803603810190610a629190614682565b612477565b005b348015610a74575f80fd5b50610a7d6125da565b604051610a8a9190614a7b565b60405180910390f35b348015610a9e575f80fd5b50610ab96004803603810190610ab49190614999565b6127be565b604051610ac691906147ef565b60405180910390f35b348015610ada575f80fd5b50610af56004803603810190610af09190614999565b6127cf565b005b348015610b02575f80fd5b50610b1d6004803603810190610b189190614e7c565b6128dc565b604051610b2a91906144d2565b60405180910390f35b348015610b3e575f80fd5b50610b596004803603810190610b549190614999565b61296a565b005b348015610b66575f80fd5b50610b816004803603810190610b7c9190614657565b6129ee565b005b348015610b8e575f80fd5b50610b97612a00565b604051610ba491906144d2565b60405180910390f35b348015610bb8575f80fd5b50610bd36004803603810190610bce9190614eba565b612a12565b005b71721c310194ccfc01e523fc93c9cccfa2a0ac81565b5f610bf582612b61565b9050919050565b610c04612bda565b610c0c612c61565b610c168282612c6b565b5050565b606060028054610c2990614f4b565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5590614f4b565b8015610ca05780601f10610c7757610100808354040283529160200191610ca0565b820191905f5260205f20905b815481529060010190602001808311610c8357829003601f168201915b5050505050905090565b5f610cb482612cc7565b610cc957610cc863cf4700e460e01b612d6a565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d0d8282612d72565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615610def576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610df7612bda565b5f600e8054610e0590614f4b565b905014610e3e576040517f19e24c1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181600e9182610e4f929190615119565b505050565b5f610e5d612d82565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e8f612d8a565b14610e9c57600854810190505b90565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f8e5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88585856040518463ffffffff1660e01b8152600401610f52939291906151e6565b5f6040518083038186803b158015610f68575f80fd5b505afa925050508015610f79575060015b610f85575f9050610f93565b60019050610f93565b600190505b9392505050565b600181565b610faa838383612db1565b505050565b5f805f600b5f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff160361113857600a6040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f61114161305c565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff168661116d9190615248565b61117791906152b6565b9050815f0151819350935050509250929050565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461131e5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d72dde5e60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611277919061440e565b606060405180830381865afa158015611292573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112b69190615373565b60200151846040518363ffffffff1660e01b81526004016112d892919061539e565b602060405180830381865afa1580156112f3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131791906153d9565b9050611322565b5f90505b919050565b61132f612bda565b600160145f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b6113a1612bda565b5f3373ffffffffffffffffffffffffffffffffffffffff16476040516113c690615431565b5f6040518083038185875af1925050503d805f8114611400576040519150601f19603f3d011682016040523d82523d5f602084013e611405565b606091505b5050905080611440576040517f750b219c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6015602052805f5260405f205f915054906101000a900460ff1681565b61146b838383613065565b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116055760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633fe5df9960095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161155d919061440e565b606060405180830381865afa158015611578573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061159c9190615373565b602001516040518263ffffffff1660e01b81526004016115bc9190614b14565b5f60405180830381865afa1580156115d6573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906115fe9190615519565b9050611651565b5f67ffffffffffffffff81111561161f5761161e614c61565b5b60405190808252806020026020018201604052801561164d5781602001602082028036833780820191505090505b5090505b90565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff161561170a576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181600d918261171b929190615119565b505050565b611728612bda565b611730612c61565b61173b838383613084565b505050565b600181565b61174d612c61565b5f611756610d11565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036117bd576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663da0194c030866040518363ffffffff1660e01b81526004016117f8929190615560565b5f604051808303815f87803b15801561180f575f80fd5b505af1158015611821573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632304aa0230856040518363ffffffff1660e01b8152600401611860929190615587565b5f604051808303815f87803b158015611877575f80fd5b505af1158015611889573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638d74431430846040518363ffffffff1660e01b81526004016118c8929190615587565b5f604051808303815f87803b1580156118df575f80fd5b505af11580156118f1573d5f803e3d5ffd5b5050505050505050565b5f611905826130e3565b9050919050565b60115481565b61191a612c61565b61193571721c310194ccfc01e523fc93c9cccfa2a0ac611e7c565b71721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff1663da0194c03060016040518363ffffffff1660e01b8152600401611983929190615560565b5f604051808303815f87803b15801561199a575f80fd5b505af11580156119ac573d5f803e3d5ffd5b5050505071721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff16632304aa023060016040518363ffffffff1660e01b81526004016119fe929190615587565b5f604051808303815f87803b158015611a15575f80fd5b505af1158015611a27573d5f803e3d5ffd5b50505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a7257611a71638f4eb60460e01b612d6a565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611ac9612bda565b611ad25f6131f2565b565b6001151560155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16151514611b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b5b906155f8565b60405180910390fd5b6001151560135f9054906101000a900460ff16151514611bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb090615660565b60405180910390fd5b62015180601254611bca919061567e565b421115611c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c03906156fb565b60405180910390fd5b611c1682826132b5565b5050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611c5190614f4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611c7d90614f4b565b8015611cc85780601f10611c9f57610100808354040283529160200191611cc8565b820191905f5260205f20905b815481529060010190602001808311611cab57829003601f168201915b5050505050905090565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611e655760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639445f53060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611dbe919061440e565b606060405180830381865afa158015611dd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dfd9190615373565b60400151846040518363ffffffff1660e01b8152600401611e1f92919061539e565b602060405180830381865afa158015611e3a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e5e91906153d9565b9050611e69565b5f90505b919050565b611e788282613429565b5050565b611e84612c61565b5f808273ffffffffffffffffffffffffffffffffffffffff163b1115611f22578173ffffffffffffffffffffffffffffffffffffffff166301ffc9a75f6040518263ffffffff1660e01b8152600401611edd9190615728565b602060405180830381865afa925050508015611f1757506040513d601f19601f82011682018060405250810190611f1491906153d9565b60015b15611f2157809150505b5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611f5c575080155b15611f93576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051611fe5929190615741565b60405180910390a18160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b602381565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156120ec576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120f4612bda565b80600f5f6101000a81548160ff02191690831515021790555050565b61211c8484848461352f565b50505050565b6014602052805f5260405f205f915054906101000a900460ff1681565b61214761437d565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461223b5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016121f5919061440e565b606060405180830381865afa158015612210573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122349190615373565b905061228d565b60405180606001604052805f600681111561225957612258614858565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090505b90565b6010805461229d90614f4b565b80601f01602080910402602001604051908101604052809291908181526020018280546122c990614f4b565b80156123145780601f106122eb57610100808354040283529160200191612314565b820191905f5260205f20905b8154815290600101906020018083116122f757829003601f168201915b505050505081565b612324612bda565b8060135f6101000a81548160ff0219169083151502179055504260128190555050565b600e805461235490614f4b565b80601f016020809104026020016040519081016040528092919081815260200182805461238090614f4b565b80156123cb5780601f106123a2576101008083540402835291602001916123cb565b820191905f5260205f20905b8154815290600101906020018083116123ae57829003601f168201915b505050505081565b60606123de82612cc7565b61241d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612414906157d8565b60405180910390fd5b5f612426613580565b90505f8151116124445760405180602001604052805f81525061246f565b8061244e84613610565b60405160200161245f929190615830565b6040516020818303038152906040525b915050919050565b6001151560135f9054906101000a900460ff161515146124cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c390615660565b60405180910390fd5b620151806012546124dd919061567e565b42111561251f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612516906156fb565b60405180910390fd5b5f6011548261252e9190615248565b905080341015612573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256a9061589d565b60405180910390fd5b61257d83836132b5565b803411156125d5573373ffffffffffffffffffffffffffffffffffffffff166108fc82346125ab91906158bb565b90811502906040515f60405180830381858888f193505050501580156125d3573d5f803e3d5ffd5b505b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461276f5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317e94a6c60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016126c7919061440e565b606060405180830381865afa1580156126e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127069190615373565b604001516040518263ffffffff1660e01b81526004016127269190614b14565b5f60405180830381865afa158015612740573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906127689190615519565b90506127bb565b5f67ffffffffffffffff81111561278957612788614c61565b5b6040519080825280602002602001820160405280156127b75781602001602082028036833780820191505090505b5090505b90565b5f6127c8826136da565b9050919050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615612885576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61288d612bda565b602361289761372e565b106128ce576040517f1f0f14ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128d98160236132b5565b50565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b612972612bda565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036129e2575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016129d9919061440e565b60405180910390fd5b6129eb816131f2565b50565b6129f6612bda565b8060118190555050565b600f5f9054906101000a900460ff1681565b612a1a612c61565b612a2384611e7c565b8373ffffffffffffffffffffffffffffffffffffffff1663da0194c030856040518363ffffffff1660e01b8152600401612a5e929190615560565b5f604051808303815f87803b158015612a75575f80fd5b505af1158015612a87573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16632304aa0230846040518363ffffffff1660e01b8152600401612ac6929190615587565b5f604051808303815f87803b158015612add575f80fd5b505af1158015612aef573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16638d74431430836040518363ffffffff1660e01b8152600401612b2e929190615587565b5f604051808303815f87803b158015612b45575f80fd5b505af1158015612b57573d5f803e3d5ffd5b5050505050505050565b5f7f86455d28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612bd35750612bd282613775565b5b9050919050565b612be2613806565b73ffffffffffffffffffffffffffffffffffffffff16612c00611c1a565b73ffffffffffffffffffffffffffffffffffffffff1614612c5f57612c23613806565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612c56919061440e565b60405180910390fd5b565b612c69612bda565b565b612c75828261380d565b8173ffffffffffffffffffffffffffffffffffffffff167f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef82604051612cbb91906158fd565b60405180910390a25050565b5f81612cd1612d82565b11612d6457612cde612d8a565b821115612d0657612cff60045f8481526020019081526020015f20546139a8565b9050612d65565b5f54821015612d63575f5b5f60045f8581526020019081526020015f205491508103612d3d5782612d3690615916565b9250612d11565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b612d7e828260016139e8565b5050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f612dbb826130e3565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612e3057612e2f63a114810060e01b612d6a565b5b5f80612e3b84613b12565b91509150612e518187612e4c613b35565b613b43565b612e7c57612e6686612e61613b35565b6128dc565b612e7b57612e7a6359c896be60e01b612d6a565b5b5b612e898686866001613b86565b8015612e93575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815460010191905081905550612f5b85612f37888887613bb8565b7c020000000000000000000000000000000000000000000000000000000017613bdf565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603612fd7575f6001850190505f60045f8381526020019081526020015f205403612fd5575f548114612fd4578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036130465761304563ea553b3460e01b612d6a565b5b6130538787876001613c09565b50505050505050565b5f612710905090565b61307f83838360405180602001604052805f815250612110565b505050565b61308f838383613c3b565b8173ffffffffffffffffffffffffffffffffffffffff16837f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c836040516130d691906158fd565b60405180910390a3505050565b5f816130ed612d82565b116131dc5760045f8381526020019081526020015f2054905061310e612d8a565b8211156131335761311e816139a8565b6131ed5761313263df2d9b4260e01b612d6a565b5b5f81036131b4575f5482106131535761315263df2d9b4260e01b612d6a565b5b5b60045f836001900393508381526020019081526020015f205490505f8103156131af575f7c0100000000000000000000000000000000000000000000000000000000821603156131ed576131ae63df2d9b4260e01b612d6a565b5b613154565b5f7c0100000000000000000000000000000000000000000000000000000000821603156131ed575b6131ec63df2d9b4260e01b612d6a565b5b919050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f805490505f82036132d2576132d163b562e8dd60e01b612d6a565b5b6132de5f848385613b86565b6132fc836132ed5f865f613bb8565b6132f685613dea565b17613bdf565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f81036133ad576133ac632e07630060e01b612d6a565b5b5f83830190505f8390506133bf612d8a565b6001830311156133da576133d96381647e3a60e01b612d6a565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a48181600101915081036133db57815f819055505050506134245f848385613c09565b505050565b8060075f613435613b35565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166134de613b35565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161352391906144d2565b60405180910390a35050565b61353a848484610f9f565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1461357a5761356484848484613df9565b6135795761357863d1a57ed660e01b612d6a565b5b5b50505050565b6060600d805461358f90614f4b565b80601f01602080910402602001604051908101604052809291908181526020018280546135bb90614f4b565b80156136065780601f106135dd57610100808354040283529160200191613606565b820191905f5260205f20905b8154815290600101906020018083116135e957829003601f168201915b5050505050905090565b60605f600161361e84613f23565b0190505f8167ffffffffffffffff81111561363c5761363b614c61565b5b6040519080825280601f01601f19166020018201604052801561366e5781602001600182028036833780820191505090505b5090505f82602001820190505b6001156136cf578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816136c4576136c3615289565b5b0494505f850361367b575b819350505050919050565b5f67ffffffffffffffff604060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c169050919050565b5f613737612d82565b5f540390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613765612d8a565b1461377257600854810190505b90565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806137cf57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806137ff5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f33905090565b5f61381661305c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff16111561387b5781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161387292919061596d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036138eb575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016138e2919061440e565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600a5f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f6139f2836118fb565b9050818015613a3457508073ffffffffffffffffffffffffffffffffffffffff16613a1b613b35565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613a6057613a4a81613a45613b35565b6128dc565b613a5f57613a5e63cfb3b94260e01b612d6a565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f613b3e613806565b905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b5f5b81811015613bb157613ba685858386613ba1919061567e565b614074565b806001019050613b88565b5050505050565b5f8060e883901c905060e8613bce868684614172565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b5f5b81811015613c3457613c2985858386613c24919061567e565b61417a565b806001019050613c0b565b5050505050565b5f613c4461305c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff161115613cab578382826040517fdfd1fc1b000000000000000000000000000000000000000000000000000000008152600401613ca293929190615994565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613d1d57835f6040517f969f0852000000000000000000000000000000000000000000000000000000008152600401613d149291906159c9565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600b5f8681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555090505050505050565b5f6001821460e11b9050919050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613e1e613b35565b8786866040518563ffffffff1660e01b8152600401613e409493929190615a42565b6020604051808303815f875af1925050508015613e7b57506040513d601f19601f82011682018060405250810190613e789190615aa0565b60015b613ed0573d805f8114613ea9576040519150601f19603f3d011682016040523d82523d5f602084013e613eae565b606091505b505f815103613ec857613ec763d1a57ed660e01b612d6a565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613f7f577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613f7557613f74615289565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613fbc576d04ee2d6d415b85acef81000000008381613fb257613fb1615289565b5b0492506020810190505b662386f26fc100008310613feb57662386f26fc100008381613fe157613fe0615289565b5b0492506010810190505b6305f5e1008310614014576305f5e100838161400a57614009615289565b5b0492506008810190505b612710831061403957612710838161402f5761402e615289565b5b0492506004810190505b6064831061405c576064838161405257614051615289565b5b0492506002810190505b600a831061406b576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156140e25750805b15614119576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156141375761413261412a613806565b858534614278565b61416b565b801561415557614150614148613806565b86853461427e565b61416a565b614169614160613806565b86868634614284565b5b5b5050505050565b5f9392505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156141e85750805b1561421f576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811561423d57614238614230613806565b85853461436a565b614271565b801561425b5761425661424e613806565b868534614370565b614270565b61426f614266613806565b86868634614376565b5b5b5050505050565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143635760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88686866040518463ffffffff1660e01b8152600401614336939291906151e6565b5f6040518083038186803b15801561434c575f80fd5b505afa15801561435e573d5f803e3d5ffd5b505050505b5050505050565b50505050565b50505050565b5050505050565b60405180606001604052805f600681111561439b5761439a614858565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6143f8826143cf565b9050919050565b614408816143ee565b82525050565b5f6020820190506144215f8301846143ff565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61446c81614438565b8114614476575f80fd5b50565b5f8135905061448781614463565b92915050565b5f602082840312156144a2576144a1614430565b5b5f6144af84828501614479565b91505092915050565b5f8115159050919050565b6144cc816144b8565b82525050565b5f6020820190506144e55f8301846144c3565b92915050565b6144f4816143ee565b81146144fe575f80fd5b50565b5f8135905061450f816144eb565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b61453581614515565b811461453f575f80fd5b50565b5f813590506145508161452c565b92915050565b5f806040838503121561456c5761456b614430565b5b5f61457985828601614501565b925050602061458a85828601614542565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6145d682614594565b6145e0818561459e565b93506145f08185602086016145ae565b6145f9816145bc565b840191505092915050565b5f6020820190508181035f83015261461c81846145cc565b905092915050565b5f819050919050565b61463681614624565b8114614640575f80fd5b50565b5f813590506146518161462d565b92915050565b5f6020828403121561466c5761466b614430565b5b5f61467984828501614643565b91505092915050565b5f806040838503121561469857614697614430565b5b5f6146a585828601614501565b92505060206146b685828601614643565b9150509250929050565b5f819050919050565b5f6146e36146de6146d9846143cf565b6146c0565b6143cf565b9050919050565b5f6146f4826146c9565b9050919050565b5f614705826146ea565b9050919050565b614715816146fb565b82525050565b5f60208201905061472e5f83018461470c565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261475557614754614734565b5b8235905067ffffffffffffffff81111561477257614771614738565b5b60208301915083600182028301111561478e5761478d61473c565b5b9250929050565b5f80602083850312156147ab576147aa614430565b5b5f83013567ffffffffffffffff8111156147c8576147c7614434565b5b6147d485828601614740565b92509250509250929050565b6147e981614624565b82525050565b5f6020820190506148025f8301846147e0565b92915050565b5f805f6060848603121561481f5761481e614430565b5b5f61482c86828701614501565b935050602061483d86828701614501565b925050604061484e86828701614501565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6007811061489657614895614858565b5b50565b5f8190506148a682614885565b919050565b5f6148b582614899565b9050919050565b6148c5816148ab565b82525050565b5f6020820190506148de5f8301846148bc565b92915050565b5f805f606084860312156148fb576148fa614430565b5b5f61490886828701614501565b935050602061491986828701614501565b925050604061492a86828701614643565b9150509250925092565b5f806040838503121561494a57614949614430565b5b5f61495785828601614643565b925050602061496885828601614643565b9150509250929050565b5f6040820190506149855f8301856143ff565b61499260208301846147e0565b9392505050565b5f602082840312156149ae576149ad614430565b5b5f6149bb84828501614501565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6149f6816143ee565b82525050565b5f614a0783836149ed565b60208301905092915050565b5f602082019050919050565b5f614a29826149c4565b614a3381856149ce565b9350614a3e836149de565b805f5b83811015614a6e578151614a5588826149fc565b9750614a6083614a13565b925050600181019050614a41565b5085935050505092915050565b5f6020820190508181035f830152614a938184614a1f565b905092915050565b5f805f60608486031215614ab257614ab1614430565b5b5f614abf86828701614643565b9350506020614ad086828701614501565b9250506040614ae186828701614542565b9150509250925092565b5f6effffffffffffffffffffffffffffff82169050919050565b614b0e81614aeb565b82525050565b5f602082019050614b275f830184614b05565b92915050565b60078110614b39575f80fd5b50565b5f81359050614b4a81614b2d565b92915050565b614b5981614aeb565b8114614b63575f80fd5b50565b5f81359050614b7481614b50565b92915050565b5f805f60608486031215614b9157614b90614430565b5b5f614b9e86828701614b3c565b9350506020614baf86828701614b66565b9250506040614bc086828701614b66565b9150509250925092565b614bd3816144b8565b8114614bdd575f80fd5b50565b5f81359050614bee81614bca565b92915050565b5f8060408385031215614c0a57614c09614430565b5b5f614c1785828601614501565b9250506020614c2885828601614be0565b9150509250929050565b5f60208284031215614c4757614c46614430565b5b5f614c5484828501614be0565b91505092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614c97826145bc565b810181811067ffffffffffffffff82111715614cb657614cb5614c61565b5b80604052505050565b5f614cc8614427565b9050614cd48282614c8e565b919050565b5f67ffffffffffffffff821115614cf357614cf2614c61565b5b614cfc826145bc565b9050602081019050919050565b828183375f83830152505050565b5f614d29614d2484614cd9565b614cbf565b905082815260208101848484011115614d4557614d44614c5d565b5b614d50848285614d09565b509392505050565b5f82601f830112614d6c57614d6b614734565b5b8135614d7c848260208601614d17565b91505092915050565b5f805f8060808587031215614d9d57614d9c614430565b5b5f614daa87828801614501565b9450506020614dbb87828801614501565b9350506040614dcc87828801614643565b925050606085013567ffffffffffffffff811115614ded57614dec614434565b5b614df987828801614d58565b91505092959194509250565b614e0e816148ab565b82525050565b614e1d81614aeb565b82525050565b606082015f820151614e375f850182614e05565b506020820151614e4a6020850182614e14565b506040820151614e5d6040850182614e14565b50505050565b5f606082019050614e765f830184614e23565b92915050565b5f8060408385031215614e9257614e91614430565b5b5f614e9f85828601614501565b9250506020614eb085828601614501565b9150509250929050565b5f805f8060808587031215614ed257614ed1614430565b5b5f614edf87828801614501565b9450506020614ef087828801614b3c565b9350506040614f0187828801614b66565b9250506060614f1287828801614b66565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614f6257607f821691505b602082108103614f7557614f74614f1e565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614fe17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614fa6565b614feb8683614fa6565b95508019841693508086168417925050509392505050565b5f61501d61501861501384614624565b6146c0565b614624565b9050919050565b5f819050919050565b61503683615003565b61504a61504282615024565b848454614fb2565b825550505050565b5f90565b61505e615052565b61506981848461502d565b505050565b5b8181101561508c576150815f82615056565b60018101905061506f565b5050565b601f8211156150d1576150a281614f85565b6150ab84614f97565b810160208510156150ba578190505b6150ce6150c685614f97565b83018261506e565b50505b505050565b5f82821c905092915050565b5f6150f15f19846008026150d6565b1980831691505092915050565b5f61510983836150e2565b9150826002028217905092915050565b6151238383614f7b565b67ffffffffffffffff81111561513c5761513b614c61565b5b6151468254614f4b565b615151828285615090565b5f601f83116001811461517e575f841561516c578287013590505b61517685826150fe565b8655506151dd565b601f19841661518c86614f85565b5f5b828110156151b35784890135825560018201915060208501945060208101905061518e565b868310156151d057848901356151cc601f8916826150e2565b8355505b6001600288020188555050505b50505050505050565b5f6060820190506151f95f8301866143ff565b61520660208301856143ff565b61521360408301846143ff565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61525282614624565b915061525d83614624565b925082820261526b81614624565b915082820484148315176152825761528161521b565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6152c082614624565b91506152cb83614624565b9250826152db576152da615289565b5b828204905092915050565b5f80fd5b5f815190506152f881614b2d565b92915050565b5f8151905061530c81614b50565b92915050565b5f60608284031215615327576153266152e6565b5b6153316060614cbf565b90505f615340848285016152ea565b5f830152506020615353848285016152fe565b6020830152506040615367848285016152fe565b60408301525092915050565b5f6060828403121561538857615387614430565b5b5f61539584828501615312565b91505092915050565b5f6040820190506153b15f830185614b05565b6153be60208301846143ff565b9392505050565b5f815190506153d381614bca565b92915050565b5f602082840312156153ee576153ed614430565b5b5f6153fb848285016153c5565b91505092915050565b5f81905092915050565b50565b5f61541c5f83615404565b91506154278261540e565b5f82019050919050565b5f61543b82615411565b9150819050919050565b5f67ffffffffffffffff82111561545f5761545e614c61565b5b602082029050602081019050919050565b5f8151905061547e816144eb565b92915050565b5f61549661549184615445565b614cbf565b905080838252602082019050602084028301858111156154b9576154b861473c565b5b835b818110156154e257806154ce8882615470565b8452602084019350506020810190506154bb565b5050509392505050565b5f82601f830112615500576154ff614734565b5b8151615510848260208601615484565b91505092915050565b5f6020828403121561552e5761552d614430565b5b5f82015167ffffffffffffffff81111561554b5761554a614434565b5b615557848285016154ec565b91505092915050565b5f6040820190506155735f8301856143ff565b61558060208301846148bc565b9392505050565b5f60408201905061559a5f8301856143ff565b6155a76020830184614b05565b9392505050565b7f596f75277265206e6f742061206d696e746572000000000000000000000000005f82015250565b5f6155e260138361459e565b91506155ed826155ae565b602082019050919050565b5f6020820190508181035f83015261560f816155d6565b9050919050565b7f4d696e74696e67206973206e6f742073746172746564207965740000000000005f82015250565b5f61564a601a8361459e565b915061565582615616565b602082019050919050565b5f6020820190508181035f8301526156778161563e565b9050919050565b5f61568882614624565b915061569383614624565b92508282019050808211156156ab576156aa61521b565b5b92915050565b7f4d696e74696e672054696d6573207570000000000000000000000000000000005f82015250565b5f6156e560108361459e565b91506156f0826156b1565b602082019050919050565b5f6020820190508181035f830152615712816156d9565b9050919050565b61572281614438565b82525050565b5f60208201905061573b5f830184615719565b92915050565b5f6040820190506157545f8301856143ff565b61576160208301846143ff565b9392505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f6157c2602f8361459e565b91506157cd82615768565b604082019050919050565b5f6020820190508181035f8301526157ef816157b6565b9050919050565b5f81905092915050565b5f61580a82614594565b61581481856157f6565b93506158248185602086016145ae565b80840191505092915050565b5f61583b8285615800565b91506158478284615800565b91508190509392505050565b7f45746865722073656e74206973206e6f7420636f72726563742e0000000000005f82015250565b5f615887601a8361459e565b915061589282615853565b602082019050919050565b5f6020820190508181035f8301526158b48161587b565b9050919050565b5f6158c582614624565b91506158d083614624565b92508282039050818111156158e8576158e761521b565b5b92915050565b6158f781614515565b82525050565b5f6020820190506159105f8301846158ee565b92915050565b5f61592082614624565b91505f82036159325761593161521b565b5b600182039050919050565b5f61595761595261594d84614515565b6146c0565b614624565b9050919050565b6159678161593d565b82525050565b5f6040820190506159805f83018561595e565b61598d60208301846147e0565b9392505050565b5f6060820190506159a75f8301866147e0565b6159b4602083018561595e565b6159c160408301846147e0565b949350505050565b5f6040820190506159dc5f8301856147e0565b6159e960208301846143ff565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f615a14826159f0565b615a1e81856159fa565b9350615a2e8185602086016145ae565b615a37816145bc565b840191505092915050565b5f608082019050615a555f8301876143ff565b615a6260208301866143ff565b615a6f60408301856147e0565b8181036060830152615a818184615a0a565b905095945050505050565b5f81519050615a9a81614463565b92915050565b5f60208284031215615ab557615ab4614430565b5b5f615ac284828501615a8c565b9150509291505056fea26469706673582212209c037391f725b817460e13963593bc372f7c08c986f3066528cbac3d0def4b7e64736f6c634300081a003300000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318000000000000000000000000bb1d20b0250b298aa325219d56896fb6c1566c9c00000000000000000000000000000000000000000000000000000000000001f40000000000000000000000003bdc72443bd7fe4ab1ecbbfe04389e3b4197941b

Deployed Bytecode

0x6080604052600436106102fe575f3560e01c806370a082311161018f578063c6682862116100db578063dc33e68111610094578063f2fde38b1161006e578063f2fde38b14610b33578063f4a0a52814610b5b578063fb796e6c14610b83578063fd762d9214610bad576102fe565b8063dc33e68114610a93578063e75179a414610acf578063e985e9c514610af7576102fe565b8063c668286214610995578063c68b3305146109bf578063c6ab67a3146109e7578063c87b56dd14610a11578063ce6df2b914610a4d578063d007af5c14610a69576102fe565b8063a22cb46511610148578063b7c0b8e811610122578063b7c0b8e8146108eb578063b88d4fde14610913578063bbadfe761461092f578063be537f431461096b576102fe565b8063a22cb46514610871578063a9fc664e14610899578063aa592f25146108c1576102fe565b806370a0823114610767578063715018a6146107a357806374d0101d146107b95780638da5cb5b146107e157806395d89b411461080b5780639d645a4414610835576102fe565b80632e8da8291161024e57806355f804b31161020757806361347162116101e157806361347162146106c35780636352211e146106eb5780636817c76c146107275780636c3b869914610751576102fe565b806355f804b3146106495780635944c753146106715780635d4c1d4614610699576102fe565b80632e8da8291461054d57806334531828146105895780633ccfd60b146105b15780633dd08c38146105c757806342842e0e14610603578063495c8bf91461061f576102fe565b8063098144d4116102bb5780631b25b077116102955780631b25b0771461048e5780631c33b328146104ca57806323b872dd146104f45780632a55205a14610510576102fe565b8063098144d414610412578063109695231461043c57806318160ddd14610464576102fe565b8063014635461461030257806301ffc9a71461032c57806304634d8d1461036857806306fdde0314610390578063081812fc146103ba578063095ea7b3146103f6575b5f80fd5b34801561030d575f80fd5b50610316610bd5565b604051610323919061440e565b60405180910390f35b348015610337575f80fd5b50610352600480360381019061034d919061448d565b610beb565b60405161035f91906144d2565b60405180910390f35b348015610373575f80fd5b5061038e60048036038101906103899190614556565b610bfc565b005b34801561039b575f80fd5b506103a4610c1a565b6040516103b19190614604565b60405180910390f35b3480156103c5575f80fd5b506103e060048036038101906103db9190614657565b610caa565b6040516103ed919061440e565b60405180910390f35b610410600480360381019061040b9190614682565b610d03565b005b34801561041d575f80fd5b50610426610d11565b604051610433919061471b565b60405180910390f35b348015610447575f80fd5b50610462600480360381019061045d9190614795565b610d39565b005b34801561046f575f80fd5b50610478610e54565b60405161048591906147ef565b60405180910390f35b348015610499575f80fd5b506104b460048036038101906104af9190614808565b610e9f565b6040516104c191906144d2565b60405180910390f35b3480156104d5575f80fd5b506104de610f9a565b6040516104eb91906148cb565b60405180910390f35b61050e600480360381019061050991906148e4565b610f9f565b005b34801561051b575f80fd5b5061053660048036038101906105319190614934565b610faf565b604051610544929190614972565b60405180910390f35b348015610558575f80fd5b50610573600480360381019061056e9190614999565b61118b565b60405161058091906144d2565b60405180910390f35b348015610594575f80fd5b506105af60048036038101906105aa919061448d565b611327565b005b3480156105bc575f80fd5b506105c5611399565b005b3480156105d2575f80fd5b506105ed60048036038101906105e89190614999565b611443565b6040516105fa91906144d2565b60405180910390f35b61061d600480360381019061061891906148e4565b611460565b005b34801561062a575f80fd5b50610633611470565b6040516106409190614a7b565b60405180910390f35b348015610654575f80fd5b5061066f600480360381019061066a9190614795565b611654565b005b34801561067c575f80fd5b5061069760048036038101906106929190614a9b565b611720565b005b3480156106a4575f80fd5b506106ad611740565b6040516106ba9190614b14565b60405180910390f35b3480156106ce575f80fd5b506106e960048036038101906106e49190614b7a565b611745565b005b3480156106f6575f80fd5b50610711600480360381019061070c9190614657565b6118fb565b60405161071e919061440e565b60405180910390f35b348015610732575f80fd5b5061073b61190c565b60405161074891906147ef565b60405180910390f35b34801561075c575f80fd5b50610765611912565b005b348015610772575f80fd5b5061078d60048036038101906107889190614999565b611a2d565b60405161079a91906147ef565b60405180910390f35b3480156107ae575f80fd5b506107b7611ac1565b005b3480156107c4575f80fd5b506107df60048036038101906107da9190614682565b611ad4565b005b3480156107ec575f80fd5b506107f5611c1a565b604051610802919061440e565b60405180910390f35b348015610816575f80fd5b5061081f611c42565b60405161082c9190614604565b60405180910390f35b348015610840575f80fd5b5061085b60048036038101906108569190614999565b611cd2565b60405161086891906144d2565b60405180910390f35b34801561087c575f80fd5b5061089760048036038101906108929190614bf4565b611e6e565b005b3480156108a4575f80fd5b506108bf60048036038101906108ba9190614999565b611e7c565b005b3480156108cc575f80fd5b506108d5612031565b6040516108e291906147ef565b60405180910390f35b3480156108f6575f80fd5b50610911600480360381019061090c9190614c32565b612036565b005b61092d60048036038101906109289190614d85565b612110565b005b34801561093a575f80fd5b506109556004803603810190610950919061448d565b612122565b60405161096291906144d2565b60405180910390f35b348015610976575f80fd5b5061097f61213f565b60405161098c9190614e63565b60405180910390f35b3480156109a0575f80fd5b506109a9612290565b6040516109b69190614604565b60405180910390f35b3480156109ca575f80fd5b506109e560048036038101906109e09190614c32565b61231c565b005b3480156109f2575f80fd5b506109fb612347565b604051610a089190614604565b60405180910390f35b348015610a1c575f80fd5b50610a376004803603810190610a329190614657565b6123d3565b604051610a449190614604565b60405180910390f35b610a676004803603810190610a629190614682565b612477565b005b348015610a74575f80fd5b50610a7d6125da565b604051610a8a9190614a7b565b60405180910390f35b348015610a9e575f80fd5b50610ab96004803603810190610ab49190614999565b6127be565b604051610ac691906147ef565b60405180910390f35b348015610ada575f80fd5b50610af56004803603810190610af09190614999565b6127cf565b005b348015610b02575f80fd5b50610b1d6004803603810190610b189190614e7c565b6128dc565b604051610b2a91906144d2565b60405180910390f35b348015610b3e575f80fd5b50610b596004803603810190610b549190614999565b61296a565b005b348015610b66575f80fd5b50610b816004803603810190610b7c9190614657565b6129ee565b005b348015610b8e575f80fd5b50610b97612a00565b604051610ba491906144d2565b60405180910390f35b348015610bb8575f80fd5b50610bd36004803603810190610bce9190614eba565b612a12565b005b71721c310194ccfc01e523fc93c9cccfa2a0ac81565b5f610bf582612b61565b9050919050565b610c04612bda565b610c0c612c61565b610c168282612c6b565b5050565b606060028054610c2990614f4b565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5590614f4b565b8015610ca05780601f10610c7757610100808354040283529160200191610ca0565b820191905f5260205f20905b815481529060010190602001808311610c8357829003601f168201915b5050505050905090565b5f610cb482612cc7565b610cc957610cc863cf4700e460e01b612d6a565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d0d8282612d72565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615610def576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610df7612bda565b5f600e8054610e0590614f4b565b905014610e3e576040517f19e24c1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181600e9182610e4f929190615119565b505050565b5f610e5d612d82565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e8f612d8a565b14610e9c57600854810190505b90565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f8e5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88585856040518463ffffffff1660e01b8152600401610f52939291906151e6565b5f6040518083038186803b158015610f68575f80fd5b505afa925050508015610f79575060015b610f85575f9050610f93565b60019050610f93565b600190505b9392505050565b600181565b610faa838383612db1565b505050565b5f805f600b5f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff160361113857600a6040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f61114161305c565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff168661116d9190615248565b61117791906152b6565b9050815f0151819350935050509250929050565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461131e5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d72dde5e60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611277919061440e565b606060405180830381865afa158015611292573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112b69190615373565b60200151846040518363ffffffff1660e01b81526004016112d892919061539e565b602060405180830381865afa1580156112f3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131791906153d9565b9050611322565b5f90505b919050565b61132f612bda565b600160145f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b6113a1612bda565b5f3373ffffffffffffffffffffffffffffffffffffffff16476040516113c690615431565b5f6040518083038185875af1925050503d805f8114611400576040519150601f19603f3d011682016040523d82523d5f602084013e611405565b606091505b5050905080611440576040517f750b219c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6015602052805f5260405f205f915054906101000a900460ff1681565b61146b838383613065565b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116055760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633fe5df9960095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161155d919061440e565b606060405180830381865afa158015611578573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061159c9190615373565b602001516040518263ffffffff1660e01b81526004016115bc9190614b14565b5f60405180830381865afa1580156115d6573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906115fe9190615519565b9050611651565b5f67ffffffffffffffff81111561161f5761161e614c61565b5b60405190808252806020026020018201604052801561164d5781602001602082028036833780820191505090505b5090505b90565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff161561170a576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181600d918261171b929190615119565b505050565b611728612bda565b611730612c61565b61173b838383613084565b505050565b600181565b61174d612c61565b5f611756610d11565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036117bd576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663da0194c030866040518363ffffffff1660e01b81526004016117f8929190615560565b5f604051808303815f87803b15801561180f575f80fd5b505af1158015611821573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632304aa0230856040518363ffffffff1660e01b8152600401611860929190615587565b5f604051808303815f87803b158015611877575f80fd5b505af1158015611889573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638d74431430846040518363ffffffff1660e01b81526004016118c8929190615587565b5f604051808303815f87803b1580156118df575f80fd5b505af11580156118f1573d5f803e3d5ffd5b5050505050505050565b5f611905826130e3565b9050919050565b60115481565b61191a612c61565b61193571721c310194ccfc01e523fc93c9cccfa2a0ac611e7c565b71721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff1663da0194c03060016040518363ffffffff1660e01b8152600401611983929190615560565b5f604051808303815f87803b15801561199a575f80fd5b505af11580156119ac573d5f803e3d5ffd5b5050505071721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff16632304aa023060016040518363ffffffff1660e01b81526004016119fe929190615587565b5f604051808303815f87803b158015611a15575f80fd5b505af1158015611a27573d5f803e3d5ffd5b50505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a7257611a71638f4eb60460e01b612d6a565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611ac9612bda565b611ad25f6131f2565b565b6001151560155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16151514611b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b5b906155f8565b60405180910390fd5b6001151560135f9054906101000a900460ff16151514611bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb090615660565b60405180910390fd5b62015180601254611bca919061567e565b421115611c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c03906156fb565b60405180910390fd5b611c1682826132b5565b5050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611c5190614f4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611c7d90614f4b565b8015611cc85780601f10611c9f57610100808354040283529160200191611cc8565b820191905f5260205f20905b815481529060010190602001808311611cab57829003601f168201915b5050505050905090565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611e655760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639445f53060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611dbe919061440e565b606060405180830381865afa158015611dd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dfd9190615373565b60400151846040518363ffffffff1660e01b8152600401611e1f92919061539e565b602060405180830381865afa158015611e3a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e5e91906153d9565b9050611e69565b5f90505b919050565b611e788282613429565b5050565b611e84612c61565b5f808273ffffffffffffffffffffffffffffffffffffffff163b1115611f22578173ffffffffffffffffffffffffffffffffffffffff166301ffc9a75f6040518263ffffffff1660e01b8152600401611edd9190615728565b602060405180830381865afa925050508015611f1757506040513d601f19601f82011682018060405250810190611f1491906153d9565b60015b15611f2157809150505b5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611f5c575080155b15611f93576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051611fe5929190615741565b60405180910390a18160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b602381565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156120ec576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120f4612bda565b80600f5f6101000a81548160ff02191690831515021790555050565b61211c8484848461352f565b50505050565b6014602052805f5260405f205f915054906101000a900460ff1681565b61214761437d565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461223b5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016121f5919061440e565b606060405180830381865afa158015612210573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122349190615373565b905061228d565b60405180606001604052805f600681111561225957612258614858565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090505b90565b6010805461229d90614f4b565b80601f01602080910402602001604051908101604052809291908181526020018280546122c990614f4b565b80156123145780601f106122eb57610100808354040283529160200191612314565b820191905f5260205f20905b8154815290600101906020018083116122f757829003601f168201915b505050505081565b612324612bda565b8060135f6101000a81548160ff0219169083151502179055504260128190555050565b600e805461235490614f4b565b80601f016020809104026020016040519081016040528092919081815260200182805461238090614f4b565b80156123cb5780601f106123a2576101008083540402835291602001916123cb565b820191905f5260205f20905b8154815290600101906020018083116123ae57829003601f168201915b505050505081565b60606123de82612cc7565b61241d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612414906157d8565b60405180910390fd5b5f612426613580565b90505f8151116124445760405180602001604052805f81525061246f565b8061244e84613610565b60405160200161245f929190615830565b6040516020818303038152906040525b915050919050565b6001151560135f9054906101000a900460ff161515146124cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c390615660565b60405180910390fd5b620151806012546124dd919061567e565b42111561251f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612516906156fb565b60405180910390fd5b5f6011548261252e9190615248565b905080341015612573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256a9061589d565b60405180910390fd5b61257d83836132b5565b803411156125d5573373ffffffffffffffffffffffffffffffffffffffff166108fc82346125ab91906158bb565b90811502906040515f60405180830381858888f193505050501580156125d3573d5f803e3d5ffd5b505b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461276f5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317e94a6c60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016126c7919061440e565b606060405180830381865afa1580156126e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127069190615373565b604001516040518263ffffffff1660e01b81526004016127269190614b14565b5f60405180830381865afa158015612740573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906127689190615519565b90506127bb565b5f67ffffffffffffffff81111561278957612788614c61565b5b6040519080825280602002602001820160405280156127b75781602001602082028036833780820191505090505b5090505b90565b5f6127c8826136da565b9050919050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615612885576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61288d612bda565b602361289761372e565b106128ce576040517f1f0f14ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128d98160236132b5565b50565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b612972612bda565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036129e2575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016129d9919061440e565b60405180910390fd5b6129eb816131f2565b50565b6129f6612bda565b8060118190555050565b600f5f9054906101000a900460ff1681565b612a1a612c61565b612a2384611e7c565b8373ffffffffffffffffffffffffffffffffffffffff1663da0194c030856040518363ffffffff1660e01b8152600401612a5e929190615560565b5f604051808303815f87803b158015612a75575f80fd5b505af1158015612a87573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16632304aa0230846040518363ffffffff1660e01b8152600401612ac6929190615587565b5f604051808303815f87803b158015612add575f80fd5b505af1158015612aef573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16638d74431430836040518363ffffffff1660e01b8152600401612b2e929190615587565b5f604051808303815f87803b158015612b45575f80fd5b505af1158015612b57573d5f803e3d5ffd5b5050505050505050565b5f7f86455d28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612bd35750612bd282613775565b5b9050919050565b612be2613806565b73ffffffffffffffffffffffffffffffffffffffff16612c00611c1a565b73ffffffffffffffffffffffffffffffffffffffff1614612c5f57612c23613806565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612c56919061440e565b60405180910390fd5b565b612c69612bda565b565b612c75828261380d565b8173ffffffffffffffffffffffffffffffffffffffff167f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef82604051612cbb91906158fd565b60405180910390a25050565b5f81612cd1612d82565b11612d6457612cde612d8a565b821115612d0657612cff60045f8481526020019081526020015f20546139a8565b9050612d65565b5f54821015612d63575f5b5f60045f8581526020019081526020015f205491508103612d3d5782612d3690615916565b9250612d11565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b612d7e828260016139e8565b5050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f612dbb826130e3565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612e3057612e2f63a114810060e01b612d6a565b5b5f80612e3b84613b12565b91509150612e518187612e4c613b35565b613b43565b612e7c57612e6686612e61613b35565b6128dc565b612e7b57612e7a6359c896be60e01b612d6a565b5b5b612e898686866001613b86565b8015612e93575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815460010191905081905550612f5b85612f37888887613bb8565b7c020000000000000000000000000000000000000000000000000000000017613bdf565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603612fd7575f6001850190505f60045f8381526020019081526020015f205403612fd5575f548114612fd4578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036130465761304563ea553b3460e01b612d6a565b5b6130538787876001613c09565b50505050505050565b5f612710905090565b61307f83838360405180602001604052805f815250612110565b505050565b61308f838383613c3b565b8173ffffffffffffffffffffffffffffffffffffffff16837f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c836040516130d691906158fd565b60405180910390a3505050565b5f816130ed612d82565b116131dc5760045f8381526020019081526020015f2054905061310e612d8a565b8211156131335761311e816139a8565b6131ed5761313263df2d9b4260e01b612d6a565b5b5f81036131b4575f5482106131535761315263df2d9b4260e01b612d6a565b5b5b60045f836001900393508381526020019081526020015f205490505f8103156131af575f7c0100000000000000000000000000000000000000000000000000000000821603156131ed576131ae63df2d9b4260e01b612d6a565b5b613154565b5f7c0100000000000000000000000000000000000000000000000000000000821603156131ed575b6131ec63df2d9b4260e01b612d6a565b5b919050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f805490505f82036132d2576132d163b562e8dd60e01b612d6a565b5b6132de5f848385613b86565b6132fc836132ed5f865f613bb8565b6132f685613dea565b17613bdf565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f81036133ad576133ac632e07630060e01b612d6a565b5b5f83830190505f8390506133bf612d8a565b6001830311156133da576133d96381647e3a60e01b612d6a565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a48181600101915081036133db57815f819055505050506134245f848385613c09565b505050565b8060075f613435613b35565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166134de613b35565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161352391906144d2565b60405180910390a35050565b61353a848484610f9f565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1461357a5761356484848484613df9565b6135795761357863d1a57ed660e01b612d6a565b5b5b50505050565b6060600d805461358f90614f4b565b80601f01602080910402602001604051908101604052809291908181526020018280546135bb90614f4b565b80156136065780601f106135dd57610100808354040283529160200191613606565b820191905f5260205f20905b8154815290600101906020018083116135e957829003601f168201915b5050505050905090565b60605f600161361e84613f23565b0190505f8167ffffffffffffffff81111561363c5761363b614c61565b5b6040519080825280601f01601f19166020018201604052801561366e5781602001600182028036833780820191505090505b5090505f82602001820190505b6001156136cf578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816136c4576136c3615289565b5b0494505f850361367b575b819350505050919050565b5f67ffffffffffffffff604060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c169050919050565b5f613737612d82565b5f540390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613765612d8a565b1461377257600854810190505b90565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806137cf57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806137ff5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f33905090565b5f61381661305c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff16111561387b5781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161387292919061596d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036138eb575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016138e2919061440e565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600a5f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f6139f2836118fb565b9050818015613a3457508073ffffffffffffffffffffffffffffffffffffffff16613a1b613b35565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613a6057613a4a81613a45613b35565b6128dc565b613a5f57613a5e63cfb3b94260e01b612d6a565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f613b3e613806565b905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b5f5b81811015613bb157613ba685858386613ba1919061567e565b614074565b806001019050613b88565b5050505050565b5f8060e883901c905060e8613bce868684614172565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b5f5b81811015613c3457613c2985858386613c24919061567e565b61417a565b806001019050613c0b565b5050505050565b5f613c4461305c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff161115613cab578382826040517fdfd1fc1b000000000000000000000000000000000000000000000000000000008152600401613ca293929190615994565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613d1d57835f6040517f969f0852000000000000000000000000000000000000000000000000000000008152600401613d149291906159c9565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600b5f8681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555090505050505050565b5f6001821460e11b9050919050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613e1e613b35565b8786866040518563ffffffff1660e01b8152600401613e409493929190615a42565b6020604051808303815f875af1925050508015613e7b57506040513d601f19601f82011682018060405250810190613e789190615aa0565b60015b613ed0573d805f8114613ea9576040519150601f19603f3d011682016040523d82523d5f602084013e613eae565b606091505b505f815103613ec857613ec763d1a57ed660e01b612d6a565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613f7f577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613f7557613f74615289565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613fbc576d04ee2d6d415b85acef81000000008381613fb257613fb1615289565b5b0492506020810190505b662386f26fc100008310613feb57662386f26fc100008381613fe157613fe0615289565b5b0492506010810190505b6305f5e1008310614014576305f5e100838161400a57614009615289565b5b0492506008810190505b612710831061403957612710838161402f5761402e615289565b5b0492506004810190505b6064831061405c576064838161405257614051615289565b5b0492506002810190505b600a831061406b576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156140e25750805b15614119576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156141375761413261412a613806565b858534614278565b61416b565b801561415557614150614148613806565b86853461427e565b61416a565b614169614160613806565b86868634614284565b5b5b5050505050565b5f9392505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156141e85750805b1561421f576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811561423d57614238614230613806565b85853461436a565b614271565b801561425b5761425661424e613806565b868534614370565b614270565b61426f614266613806565b86868634614376565b5b5b5050505050565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143635760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88686866040518463ffffffff1660e01b8152600401614336939291906151e6565b5f6040518083038186803b15801561434c575f80fd5b505afa15801561435e573d5f803e3d5ffd5b505050505b5050505050565b50505050565b50505050565b5050505050565b60405180606001604052805f600681111561439b5761439a614858565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6143f8826143cf565b9050919050565b614408816143ee565b82525050565b5f6020820190506144215f8301846143ff565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61446c81614438565b8114614476575f80fd5b50565b5f8135905061448781614463565b92915050565b5f602082840312156144a2576144a1614430565b5b5f6144af84828501614479565b91505092915050565b5f8115159050919050565b6144cc816144b8565b82525050565b5f6020820190506144e55f8301846144c3565b92915050565b6144f4816143ee565b81146144fe575f80fd5b50565b5f8135905061450f816144eb565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b61453581614515565b811461453f575f80fd5b50565b5f813590506145508161452c565b92915050565b5f806040838503121561456c5761456b614430565b5b5f61457985828601614501565b925050602061458a85828601614542565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6145d682614594565b6145e0818561459e565b93506145f08185602086016145ae565b6145f9816145bc565b840191505092915050565b5f6020820190508181035f83015261461c81846145cc565b905092915050565b5f819050919050565b61463681614624565b8114614640575f80fd5b50565b5f813590506146518161462d565b92915050565b5f6020828403121561466c5761466b614430565b5b5f61467984828501614643565b91505092915050565b5f806040838503121561469857614697614430565b5b5f6146a585828601614501565b92505060206146b685828601614643565b9150509250929050565b5f819050919050565b5f6146e36146de6146d9846143cf565b6146c0565b6143cf565b9050919050565b5f6146f4826146c9565b9050919050565b5f614705826146ea565b9050919050565b614715816146fb565b82525050565b5f60208201905061472e5f83018461470c565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261475557614754614734565b5b8235905067ffffffffffffffff81111561477257614771614738565b5b60208301915083600182028301111561478e5761478d61473c565b5b9250929050565b5f80602083850312156147ab576147aa614430565b5b5f83013567ffffffffffffffff8111156147c8576147c7614434565b5b6147d485828601614740565b92509250509250929050565b6147e981614624565b82525050565b5f6020820190506148025f8301846147e0565b92915050565b5f805f6060848603121561481f5761481e614430565b5b5f61482c86828701614501565b935050602061483d86828701614501565b925050604061484e86828701614501565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6007811061489657614895614858565b5b50565b5f8190506148a682614885565b919050565b5f6148b582614899565b9050919050565b6148c5816148ab565b82525050565b5f6020820190506148de5f8301846148bc565b92915050565b5f805f606084860312156148fb576148fa614430565b5b5f61490886828701614501565b935050602061491986828701614501565b925050604061492a86828701614643565b9150509250925092565b5f806040838503121561494a57614949614430565b5b5f61495785828601614643565b925050602061496885828601614643565b9150509250929050565b5f6040820190506149855f8301856143ff565b61499260208301846147e0565b9392505050565b5f602082840312156149ae576149ad614430565b5b5f6149bb84828501614501565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6149f6816143ee565b82525050565b5f614a0783836149ed565b60208301905092915050565b5f602082019050919050565b5f614a29826149c4565b614a3381856149ce565b9350614a3e836149de565b805f5b83811015614a6e578151614a5588826149fc565b9750614a6083614a13565b925050600181019050614a41565b5085935050505092915050565b5f6020820190508181035f830152614a938184614a1f565b905092915050565b5f805f60608486031215614ab257614ab1614430565b5b5f614abf86828701614643565b9350506020614ad086828701614501565b9250506040614ae186828701614542565b9150509250925092565b5f6effffffffffffffffffffffffffffff82169050919050565b614b0e81614aeb565b82525050565b5f602082019050614b275f830184614b05565b92915050565b60078110614b39575f80fd5b50565b5f81359050614b4a81614b2d565b92915050565b614b5981614aeb565b8114614b63575f80fd5b50565b5f81359050614b7481614b50565b92915050565b5f805f60608486031215614b9157614b90614430565b5b5f614b9e86828701614b3c565b9350506020614baf86828701614b66565b9250506040614bc086828701614b66565b9150509250925092565b614bd3816144b8565b8114614bdd575f80fd5b50565b5f81359050614bee81614bca565b92915050565b5f8060408385031215614c0a57614c09614430565b5b5f614c1785828601614501565b9250506020614c2885828601614be0565b9150509250929050565b5f60208284031215614c4757614c46614430565b5b5f614c5484828501614be0565b91505092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614c97826145bc565b810181811067ffffffffffffffff82111715614cb657614cb5614c61565b5b80604052505050565b5f614cc8614427565b9050614cd48282614c8e565b919050565b5f67ffffffffffffffff821115614cf357614cf2614c61565b5b614cfc826145bc565b9050602081019050919050565b828183375f83830152505050565b5f614d29614d2484614cd9565b614cbf565b905082815260208101848484011115614d4557614d44614c5d565b5b614d50848285614d09565b509392505050565b5f82601f830112614d6c57614d6b614734565b5b8135614d7c848260208601614d17565b91505092915050565b5f805f8060808587031215614d9d57614d9c614430565b5b5f614daa87828801614501565b9450506020614dbb87828801614501565b9350506040614dcc87828801614643565b925050606085013567ffffffffffffffff811115614ded57614dec614434565b5b614df987828801614d58565b91505092959194509250565b614e0e816148ab565b82525050565b614e1d81614aeb565b82525050565b606082015f820151614e375f850182614e05565b506020820151614e4a6020850182614e14565b506040820151614e5d6040850182614e14565b50505050565b5f606082019050614e765f830184614e23565b92915050565b5f8060408385031215614e9257614e91614430565b5b5f614e9f85828601614501565b9250506020614eb085828601614501565b9150509250929050565b5f805f8060808587031215614ed257614ed1614430565b5b5f614edf87828801614501565b9450506020614ef087828801614b3c565b9350506040614f0187828801614b66565b9250506060614f1287828801614b66565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614f6257607f821691505b602082108103614f7557614f74614f1e565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614fe17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614fa6565b614feb8683614fa6565b95508019841693508086168417925050509392505050565b5f61501d61501861501384614624565b6146c0565b614624565b9050919050565b5f819050919050565b61503683615003565b61504a61504282615024565b848454614fb2565b825550505050565b5f90565b61505e615052565b61506981848461502d565b505050565b5b8181101561508c576150815f82615056565b60018101905061506f565b5050565b601f8211156150d1576150a281614f85565b6150ab84614f97565b810160208510156150ba578190505b6150ce6150c685614f97565b83018261506e565b50505b505050565b5f82821c905092915050565b5f6150f15f19846008026150d6565b1980831691505092915050565b5f61510983836150e2565b9150826002028217905092915050565b6151238383614f7b565b67ffffffffffffffff81111561513c5761513b614c61565b5b6151468254614f4b565b615151828285615090565b5f601f83116001811461517e575f841561516c578287013590505b61517685826150fe565b8655506151dd565b601f19841661518c86614f85565b5f5b828110156151b35784890135825560018201915060208501945060208101905061518e565b868310156151d057848901356151cc601f8916826150e2565b8355505b6001600288020188555050505b50505050505050565b5f6060820190506151f95f8301866143ff565b61520660208301856143ff565b61521360408301846143ff565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61525282614624565b915061525d83614624565b925082820261526b81614624565b915082820484148315176152825761528161521b565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6152c082614624565b91506152cb83614624565b9250826152db576152da615289565b5b828204905092915050565b5f80fd5b5f815190506152f881614b2d565b92915050565b5f8151905061530c81614b50565b92915050565b5f60608284031215615327576153266152e6565b5b6153316060614cbf565b90505f615340848285016152ea565b5f830152506020615353848285016152fe565b6020830152506040615367848285016152fe565b60408301525092915050565b5f6060828403121561538857615387614430565b5b5f61539584828501615312565b91505092915050565b5f6040820190506153b15f830185614b05565b6153be60208301846143ff565b9392505050565b5f815190506153d381614bca565b92915050565b5f602082840312156153ee576153ed614430565b5b5f6153fb848285016153c5565b91505092915050565b5f81905092915050565b50565b5f61541c5f83615404565b91506154278261540e565b5f82019050919050565b5f61543b82615411565b9150819050919050565b5f67ffffffffffffffff82111561545f5761545e614c61565b5b602082029050602081019050919050565b5f8151905061547e816144eb565b92915050565b5f61549661549184615445565b614cbf565b905080838252602082019050602084028301858111156154b9576154b861473c565b5b835b818110156154e257806154ce8882615470565b8452602084019350506020810190506154bb565b5050509392505050565b5f82601f830112615500576154ff614734565b5b8151615510848260208601615484565b91505092915050565b5f6020828403121561552e5761552d614430565b5b5f82015167ffffffffffffffff81111561554b5761554a614434565b5b615557848285016154ec565b91505092915050565b5f6040820190506155735f8301856143ff565b61558060208301846148bc565b9392505050565b5f60408201905061559a5f8301856143ff565b6155a76020830184614b05565b9392505050565b7f596f75277265206e6f742061206d696e746572000000000000000000000000005f82015250565b5f6155e260138361459e565b91506155ed826155ae565b602082019050919050565b5f6020820190508181035f83015261560f816155d6565b9050919050565b7f4d696e74696e67206973206e6f742073746172746564207965740000000000005f82015250565b5f61564a601a8361459e565b915061565582615616565b602082019050919050565b5f6020820190508181035f8301526156778161563e565b9050919050565b5f61568882614624565b915061569383614624565b92508282019050808211156156ab576156aa61521b565b5b92915050565b7f4d696e74696e672054696d6573207570000000000000000000000000000000005f82015250565b5f6156e560108361459e565b91506156f0826156b1565b602082019050919050565b5f6020820190508181035f830152615712816156d9565b9050919050565b61572281614438565b82525050565b5f60208201905061573b5f830184615719565b92915050565b5f6040820190506157545f8301856143ff565b61576160208301846143ff565b9392505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f6157c2602f8361459e565b91506157cd82615768565b604082019050919050565b5f6020820190508181035f8301526157ef816157b6565b9050919050565b5f81905092915050565b5f61580a82614594565b61581481856157f6565b93506158248185602086016145ae565b80840191505092915050565b5f61583b8285615800565b91506158478284615800565b91508190509392505050565b7f45746865722073656e74206973206e6f7420636f72726563742e0000000000005f82015250565b5f615887601a8361459e565b915061589282615853565b602082019050919050565b5f6020820190508181035f8301526158b48161587b565b9050919050565b5f6158c582614624565b91506158d083614624565b92508282039050818111156158e8576158e761521b565b5b92915050565b6158f781614515565b82525050565b5f6020820190506159105f8301846158ee565b92915050565b5f61592082614624565b91505f82036159325761593161521b565b5b600182039050919050565b5f61595761595261594d84614515565b6146c0565b614624565b9050919050565b6159678161593d565b82525050565b5f6040820190506159805f83018561595e565b61598d60208301846147e0565b9392505050565b5f6060820190506159a75f8301866147e0565b6159b4602083018561595e565b6159c160408301846147e0565b949350505050565b5f6040820190506159dc5f8301856147e0565b6159e960208301846143ff565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f615a14826159f0565b615a1e81856159fa565b9350615a2e8185602086016145ae565b615a37816145bc565b840191505092915050565b5f608082019050615a555f8301876143ff565b615a6260208301866143ff565b615a6f60408301856147e0565b8181036060830152615a818184615a0a565b905095945050505050565b5f81519050615a9a81614463565b92915050565b5f60208284031215615ab557615ab4614430565b5b5f615ac284828501615a8c565b9150509291505056fea26469706673582212209c037391f725b817460e13963593bc372f7c08c986f3066528cbac3d0def4b7e64736f6c634300081a0033

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

00000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318000000000000000000000000bb1d20b0250b298aa325219d56896fb6c1566c9c00000000000000000000000000000000000000000000000000000000000001f40000000000000000000000003bdc72443bd7fe4ab1ecbbfe04389e3b4197941b

-----Decoded View---------------
Arg [0] : initialOwner (address): 0x59dE7273191E6bf1907d614e94eCFbe8e5FB7318
Arg [1] : royaltyReceiver_ (address): 0xbb1d20B0250B298aa325219D56896fB6c1566C9c
Arg [2] : royaltyFeeNumerator_ (uint96): 500
Arg [3] : _minter (address): 0x3bDC72443bD7fE4Ab1EcbBFE04389e3B4197941B

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318
Arg [1] : 000000000000000000000000bb1d20b0250b298aa325219d56896fb6c1566c9c
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [3] : 0000000000000000000000003bdc72443bd7fe4ab1ecbbfe04389e3b4197941b


Deployed Bytecode Sourcemap

125898:6898:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44074:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;128741:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;128150:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75315:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82555:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131920:159;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;48600:137;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131082:269;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70517:573;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52384:387;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44185:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;132089:211;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120714:429;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;50729:357;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;130253:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;131532:207;;;;;;;;;;;;;:::i;:::-;;126362:38;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;132310:219;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49616:358;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;130809:136;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;128343:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44291:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46340:727;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76717:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126178:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44731:464;;;;;;;;;;;;;:::i;:::-;;72241:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31607:103;;;;;;;;;;;;;:::i;:::-;;127398:250;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30932:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75491:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51258:378;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131749:161;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47667:818;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126223:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;130541:160;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;132540:253;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126310:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48954:455;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126134:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;128558:126;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126056:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;129186:609;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127656:486;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50184:379;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;129960:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127218:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83513:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31865:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;131359:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126091:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45398:749;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44074:104;44135:42;44074:104;:::o;128741:221::-;128873:4;128915:39;128942:11;128915:26;:39::i;:::-;128895:59;;128741:221;;;:::o;128150:185::-;30818:13;:11;:13::i;:::-;128243:31:::1;:29;:31::i;:::-;128285:42;128304:8;128314:12;128285:18;:42::i;:::-;128150:185:::0;;:::o;75315:100::-;75369:13;75402:5;75395:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75315:100;:::o;82555:227::-;82631:7;82656:16;82664:7;82656;:16::i;:::-;82651:73;;82674:50;82682:41;;;82674:7;:50::i;:::-;82651:73;82744:15;:24;82760:7;82744:24;;;;;;;;;;;:30;;;;;;;;;;;;82737:37;;82555:227;;;:::o;131920:159::-;132039:32;132053:8;132063:7;132039:13;:32::i;:::-;131920:159;;:::o;48600:137::-;48662:30;48712:17;;;;;;;;;;;48705:24;;48600:137;:::o;131082:269::-;126878:14;:23;126893:7;;;;126878:23;;;;;;;;;;;;;;;;;;;;;;;;;;;126874:52;;;126910:16;;;;;;;;;;;;;;126874:52;30818:13:::1;:11;:13::i;:::-;131249:1:::2;131223:14;131217:28;;;;;:::i;:::-;;;:33;131213:85;;131272:26;;;;;;;;;;;;;;131213:85;131328:15;;131311:14;:32;;;;;;;:::i;:::-;;131082:269:::0;;:::o;70517:573::-;70578:14;70976:15;:13;:15::i;:::-;70961:12;;70945:13;;:28;:46;70936:55;;71031:17;71010;:15;:17::i;:::-;:38;71006:65;;71060:11;;71050:21;;;;71006:65;70517:573;:::o;52384:387::-;52483:4;52542:1;52504:40;;52512:17;;;;;;;;;;;52504:40;;;52500:242;;52565:17;;;;;;;;;;;:47;;;52613:6;52621:4;52627:2;52565:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52561:170;;52710:5;52703:12;;;;52561:170;52657:4;52650:11;;;;52500:242;52759:4;52752:11;;52384:387;;;;;;:::o;44185:99::-;44258:26;44185:99;:::o;132089:211::-;132255:37;132274:4;132280:2;132284:7;132255:18;:37::i;:::-;132089:211;;;:::o;120714:429::-;120800:7;120809;120829:26;120858:17;:26;120876:7;120858:26;;;;;;;;;;;120829:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120929:1;120901:30;;:7;:16;;;:30;;;120897:92;;120958:19;120948:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120897:92;121001:21;121065:17;:15;:17::i;:::-;121025:57;;121038:7;:23;;;121026:35;;:9;:35;;;;:::i;:::-;121025:57;;;;:::i;:::-;121001:81;;121103:7;:16;;;121121:13;121095:40;;;;;;120714:429;;;;;:::o;50729:357::-;50808:4;50867:1;50829:40;;50837:17;;;;;;;;;;;50829:40;;;50825:229;;50893:17;;;;;;;;;;;:39;;;50951:17;;;;;;;;;;;:45;;;51005:4;50951:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;;;51033:8;50893:149;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50886:156;;;;50825:229;51073:5;51066:12;;50729:357;;;;:::o;130253:96::-;30818:13;:11;:13::i;:::-;130337:4:::1;130316:14;:18;130331:2;130316:18;;;;;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;130253:96:::0;:::o;131532:207::-;30818:13;:11;:13::i;:::-;131583:12:::1;131609:10;131601:24;;131647:21;131601:82;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;131582:101;;;131699:7;131694:37;;131715:16;;;;;;;;;;;;;;131694:37;131571:168;131532:207::o:0;126362:38::-;;;;;;;;;;;;;;;;;;;;;;:::o;132310:219::-;132480:41;132503:4;132509:2;132513:7;132480:22;:41::i;:::-;132310:219;;;:::o;49616:358::-;49681:16;49752:1;49714:40;;49722:17;;;;;;;;;;;49714:40;;;49710:221;;49778:17;;;;;;;;;;;:41;;;49838:17;;;;;;;;;;;:45;;;49892:4;49838:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;;;49778:141;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49771:148;;;;49710:221;49964:1;49950:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49943:23;;49616:358;;:::o;130809:136::-;126878:14;:23;126893:7;;;;126878:23;;;;;;;;;;;;;;;;;;;;;;;;;;;126874:52;;;126910:16;;;;;;;;;;;;;;126874:52;130926:11:::1;;130910:13;:27;;;;;;;:::i;:::-;;130809:136:::0;;:::o;128343:207::-;30818:13;:11;:13::i;:::-;128451:31:::1;:29;:31::i;:::-;128493:49;128510:7;128519:8;128529:12;128493:16;:49::i;:::-;128343:207:::0;;;:::o;44291:66::-;44355:1;44291:66;:::o;46340:727::-;46529:31;:29;:31::i;:::-;46573:40;46616:22;:20;:22::i;:::-;46573:65;;46683:1;46653:32;;46661:9;46653:32;;;46649:117;;46709:45;;;;;;;;;;;;;;46649:117;46778:9;:46;;;46833:4;46840:5;46778:68;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46857:9;:42;;;46908:4;46915:19;46857:78;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46946:9;:59;;;47014:4;47021:37;46946:113;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46518:549;46340:727;;;:::o;76717:152::-;76789:7;76832:27;76851:7;76832:18;:27::i;:::-;76809:52;;76717:152;;;:::o;126178:38::-;;;;:::o;44731:464::-;44795:31;:29;:31::i;:::-;44837:48;44135:42;44837:20;:48::i;:::-;44135:42;44896:95;;;45000:4;44258:26;44896:143;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44135:42;45050:91;;;45150:4;44355:1;45050:137;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44731:464::o;72241:242::-;72313:7;72354:1;72337:19;;:5;:19;;;72333:69;;72358:44;72366:35;;;72358:7;:44::i;:::-;72333:69;65001:13;72420:18;:25;72439:5;72420:25;;;;;;;;;;;;;;;;:55;72413:62;;72241:242;;;:::o;31607:103::-;30818:13;:11;:13::i;:::-;31672:30:::1;31699:1;31672:18;:30::i;:::-;31607:103::o:0;127398:250::-;127017:4;126995:26;;:6;:18;127002:10;126995:18;;;;;;;;;;;;;;;;;;;;;;;;;:26;;;126987:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;127501:4:::1;127490:15;;:7;;;;;;;;;;;:15;;;127482:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;127585:8;127573:9;;:20;;;;:::i;:::-;127554:15;:39;;127546:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;127625:15;127631:2;127635:4;127625:5;:15::i;:::-;127398:250:::0;;:::o;30932:87::-;30978:7;31005:6;;;;;;;;;;;30998:13;;30932:87;:::o;75491:104::-;75547:13;75580:7;75573:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75491:104;:::o;51258:378::-;51343:4;51402:1;51364:40;;51372:17;;;;;;;;;;;51364:40;;;51360:244;;51428:17;;;;;;;;;;;:45;;;51492:17;;;;;;;;;;;:45;;;51546:4;51492:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;;;51583:8;51428:164;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51421:171;;;;51360:244;51623:5;51616:12;;51258:378;;;;:::o;131749:161::-;131859:43;131883:8;131893;131859:23;:43::i;:::-;131749:161;;:::o;47667:818::-;47743:31;:29;:31::i;:::-;47787:29;47873:1;47840:18;:30;;;:34;47837:304;;;47903:18;47895:45;;;47941:48;47895:95;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;47891:239;;;48088:17;48061:44;;48009:112;47891:239;47837:304;48186:1;48156:32;;:18;:32;;;;:61;;;;;48193:24;48192:25;48156:61;48153:152;;;48241:52;;;;;;;;;;;;;;48153:152;48322:72;48355:17;;;;;;;;;;;48375:18;48322:72;;;;;;;:::i;:::-;;;;;;;;48458:18;48407:17;;:70;;;;;;;;;;;;;;;;;;47732:753;47667:818;:::o;126223:37::-;126258:2;126223:37;:::o;130541:160::-;126878:14;:23;126893:7;;;;126878:23;;;;;;;;;;;;;;;;;;;;;;;;;;;126874:52;;;126910:16;;;;;;;;;;;;;;126874:52;30818:13:::1;:11;:13::i;:::-;130688:5:::2;130661:24;;:32;;;;;;;;;;;;;;;;;;130541:160:::0;:::o;132540:253::-;132738:47;132761:4;132767:2;132771:7;132780:4;132738:22;:47::i;:::-;132540:253;;;;:::o;126310:45::-;;;;;;;;;;;;;;;;;;;;;;:::o;48954:455::-;49013:31;;:::i;:::-;49099:1;49061:40;;49069:17;;;;;;;;;;;49061:40;;;49057:140;;49125:17;;;;;;;;;;;:45;;;49179:4;49125:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49118:67;;;;49057:140;49216:185;;;;;;;;49279:27;49216:185;;;;;;;;:::i;:::-;;;;;;49342:1;49216:185;;;;;;49388:1;49216:185;;;;;49209:192;;48954:455;;:::o;126134:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;128558:126::-;30818:13;:11;:13::i;:::-;128631:7:::1;128621;;:17;;;;;;;;;;;;;;;;;;128661:15;128649:9;:27;;;;128558:126:::0;:::o;126056:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;129186:609::-;129304:13;129357:16;129365:7;129357;:16::i;:::-;129335:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;129461:28;129492:10;:8;:10::i;:::-;129461:41;;129564:1;129539:14;129533:28;:32;:254;;;;;;;;;;;;;;;;;129657:14;129698:25;129715:7;129698:16;:25::i;:::-;129614:132;;;;;;;;;:::i;:::-;;;;;;;;;;;;;129533:254;129513:274;;;129186:609;;;:::o;127656:486::-;127753:4;127742:15;;:7;;;;;;;;;;;:15;;;127734:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;127837:8;127825:9;;:20;;;;:::i;:::-;127806:15;:39;;127798:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;127877:17;127908:9;;127897:8;:20;;;;:::i;:::-;127877:40;;127949:9;127936;:22;;127928:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;128000:19;128006:2;128010:8;128000:5;:19::i;:::-;128046:9;128034;:21;128030:105;;;128080:10;128072:28;;:51;128113:9;128101;:21;;;;:::i;:::-;128072:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;128030:105;127723:419;127656:486;;:::o;50184:379::-;50255:16;50326:1;50288:40;;50296:17;;;;;;;;;;;50288:40;;;50284:236;;50352:17;;;;;;;;;;;:47;;;50418:17;;;;;;;;;;;:45;;;50472:4;50418:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;;;50352:156;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50345:163;;;;50284:236;50553:1;50539:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50532:23;;50184:379;;:::o;129960:119::-;130022:7;130049:22;130063:7;130049:13;:22::i;:::-;130042:29;;129960:119;;;:::o;127218:168::-;126878:14;:23;126893:7;;;;126878:23;;;;;;;;;;;;;;;;;;;;;;;;;;;126874:52;;;126910:16;;;;;;;;;;;;;;126874:52;30818:13:::1;:11;:13::i;:::-;126258:2:::2;127290:14;:12;:14::i;:::-;:26;127286:62;;127325:23;;;;;;;;;;;;;;127286:62;127359:19;127365:2;126258;127359:5;:19::i;:::-;127218:168:::0;:::o;83513:164::-;83610:4;83634:18;:25;83653:5;83634:25;;;;;;;;;;;;;;;:35;83660:8;83634:35;;;;;;;;;;;;;;;;;;;;;;;;;83627:42;;83513:164;;;;:::o;31865:220::-;30818:13;:11;:13::i;:::-;31970:1:::1;31950:22;;:8;:22;;::::0;31946:93:::1;;32024:1;31996:31;;;;;;;;;;;:::i;:::-;;;;;;;;31946:93;32049:28;32068:8;32049:18;:28::i;:::-;31865:220:::0;:::o;131359:93::-;30818:13;:11;:13::i;:::-;131438:6:::1;131426:9;:18;;;;131359:93:::0;:::o;126091:36::-;;;;;;;;;;;;;:::o;45398:749::-;45628:31;:29;:31::i;:::-;45672;45693:9;45672:20;:31::i;:::-;45747:9;45716:92;;;45817:4;45824:5;45716:114;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45874:9;45843:88;;;45940:4;45947:19;45843:124;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46011:9;45980:105;;;46094:4;46101:37;45980:159;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45398:749;;;;:::o;115304:203::-;115389:4;115428:31;115413:46;;;:11;:46;;;;:86;;;;115463:36;115487:11;115463:23;:36::i;:::-;115413:86;115406:93;;115304:203;;;:::o;31097:166::-;31168:12;:10;:12::i;:::-;31157:23;;:7;:5;:7::i;:::-;:23;;;31153:103;;31231:12;:10;:12::i;:::-;31204:40;;;;;;;;;;;:::i;:::-;;;;;;;;31153:103;31097:166::o;32660:104::-;32743:13;:11;:13::i;:::-;32660:104::o;124130:217::-;124234:48;124259:8;124269:12;124234:24;:48::i;:::-;124316:8;124298:41;;;124326:12;124298:41;;;;;;:::i;:::-;;;;;;;;124130:217;;:::o;83935:475::-;84000:11;84047:7;84028:15;:13;:15::i;:::-;:26;84024:379;;84085:17;:15;:17::i;:::-;84075:7;:27;84071:90;;;84111:50;84134:17;:26;84152:7;84134:26;;;;;;;;;;;;84111:22;:50::i;:::-;84104:57;;;;84071:90;84192:13;;84182:7;:23;84178:214;;;84226:14;84259:60;84307:1;84276:17;:26;84294:7;84276:26;;;;;;;;;;;;84267:35;;;84266:42;84259:60;;84310:9;;;;:::i;:::-;;;84259:60;;;84375:1;65777:8;84347:6;:24;:29;84338:38;;84207:185;84178:214;84024:379;83935:475;;;;:::o;114444:165::-;114545:13;114539:4;114532:27;114586:4;114580;114573:18;82272:124;82361:27;82370:2;82374:7;82383:4;82361:8;:27::i;:::-;82272:124;;:::o;69565:92::-;69621:7;69648:1;69641:8;;69565:92;:::o;70015:110::-;70073:7;70100:17;70093:24;;70015:110;:::o;86827:3523::-;86969:27;86999;87018:7;86999:18;:27::i;:::-;86969:57;;66459:14;87170:4;87154:22;;:41;87131:66;;87255:4;87214:45;;87230:19;87214:45;;;87210:95;;87261:44;87269:35;;;87261:7;:44::i;:::-;87210:95;87319:27;87348:23;87375:35;87402:7;87375:26;:35::i;:::-;87318:92;;;;87510:68;87535:15;87552:4;87558:19;:17;:19::i;:::-;87510:24;:68::i;:::-;87505:189;;87598:43;87615:4;87621:19;:17;:19::i;:::-;87598:16;:43::i;:::-;87593:101;;87643:51;87651:42;;;87643:7;:51::i;:::-;87593:101;87505:189;87707:43;87729:4;87735:2;87739:7;87748:1;87707:21;:43::i;:::-;87843:15;87840:160;;;87983:1;87962:19;87955:30;87840:160;88380:18;:24;88399:4;88380:24;;;;;;;;;;;;;;;;88378:26;;;;;;;;;;;;88449:18;:22;88468:2;88449:22;;;;;;;;;;;;;;;;88447:24;;;;;;;;;;;88771:146;88808:2;88857:45;88872:4;88878:2;88882:19;88857:14;:45::i;:::-;66057:8;88829:73;88771:18;:146::i;:::-;88742:17;:26;88760:7;88742:26;;;;;;;;;;;:175;;;;89088:1;66057:8;89037:19;:47;:52;89033:627;;89110:19;89142:1;89132:7;:11;89110:33;;89299:1;89265:17;:30;89283:11;89265:30;;;;;;;;;;;;:35;89261:384;;89403:13;;89388:11;:28;89384:242;;89583:19;89550:17;:30;89568:11;89550:30;;;;;;;;;;;:52;;;;89384:242;89261:384;89091:569;89033:627;89773:16;66459:14;89808:2;89792:20;;:39;89773:58;;90172:7;90136:8;90102:4;90044:25;89989:1;89932;89909:299;90245:1;90233:8;:13;90229:58;;90248:39;90256:30;;;90248:7;:39::i;:::-;90229:58;90300:42;90321:4;90327:2;90331:7;90340:1;90300:20;:42::i;:::-;86958:3392;;;;86827:3523;;;:::o;121425:97::-;121483:6;121509:5;121502:12;;121425:97;:::o;90446:193::-;90592:39;90609:4;90615:2;90619:7;90592:39;;;;;;;;;;;;:16;:39::i;:::-;90446:193;;;:::o;124355:246::-;124474:55;124497:7;124506:8;124516:12;124474:22;:55::i;:::-;124570:8;124545:48;;124561:7;124545:48;124580:12;124545:48;;;;;;:::i;:::-;;;;;;;;124355:246;;;:::o;78202:2213::-;78269:14;78319:7;78300:15;:13;:15::i;:::-;:26;78296:2054;;78352:17;:26;78370:7;78352:26;;;;;;;;;;;;78343:35;;78409:17;:15;:17::i;:::-;78399:7;:27;78395:183;;;78451:30;78474:6;78451:22;:30::i;:::-;78483:13;78447:49;78515:47;78523:38;;;78515:7;:47::i;:::-;78395:183;78689:1;78679:6;:11;78675:1292;;78726:13;;78715:7;:24;78711:77;;78741:47;78749:38;;;78741:7;:47::i;:::-;78711:77;79345:607;79423:17;:28;79441:9;;;;;;;79423:28;;;;;;;;;;;;79414:37;;79511:1;79501:6;:11;79497:25;79514:8;79497:25;79577:1;65777:8;79549:6;:24;:29;79545:48;79580:13;79545:48;79885:47;79893:38;;;79885:7;:47::i;:::-;79345:607;;;78675:1292;80322:1;65777:8;80294:6;:24;:29;80290:48;80325:13;80290:48;78296:2054;80360:47;80368:38;;;80360:7;:47::i;:::-;78202:2213;;;;:::o;32245:191::-;32319:16;32338:6;;;;;;;;;;;32319:25;;32364:8;32355:6;;:17;;;;;;;;;;;;;;;;;;32419:8;32388:40;;32409:8;32388:40;;;;;;;;;;;;32308:128;32245:191;:::o;94890:2399::-;94963:20;94986:13;;94963:36;;95026:1;95014:8;:13;95010:53;;95029:34;95037:25;;;95029:7;:34::i;:::-;95010:53;95076:61;95106:1;95110:2;95114:12;95128:8;95076:21;:61::i;:::-;95610:139;95647:2;95701:33;95724:1;95728:2;95732:1;95701:14;:33::i;:::-;95668:30;95689:8;95668:20;:30::i;:::-;:66;95610:18;:139::i;:::-;95576:17;:31;95594:12;95576:31;;;;;;;;;;;:173;;;;96036:1;65139:2;96006:1;:26;;96005:32;95993:8;:45;95967:18;:22;95986:2;95967:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;96149:16;66459:14;96184:2;96168:20;;:39;96149:58;;96240:1;96228:8;:13;96224:54;;96243:35;96251:26;;;96243:7;:35::i;:::-;96224:54;96295:11;96324:8;96309:12;:23;96295:37;;96347:15;96365:12;96347:30;;96408:17;:15;:17::i;:::-;96404:1;96398:3;:7;:27;96394:77;;;96427:44;96435:35;;;96427:7;:44::i;:::-;96394:77;96488:676;96907:7;96863:8;96818:1;96752:25;96689:1;96624;96593:358;97159:3;97146:9;;;;;;:16;96488:676;;97196:3;97180:13;:19;;;;95325:1886;;;97221:60;97250:1;97254:2;97258:12;97272:8;97221:20;:60::i;:::-;94952:2337;94890:2399;;:::o;83122:234::-;83269:8;83217:18;:39;83236:19;:17;:19::i;:::-;83217:39;;;;;;;;;;;;;;;:49;83257:8;83217:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;83329:8;83293:55;;83308:19;:17;:19::i;:::-;83293:55;;;83339:8;83293:55;;;;;;:::i;:::-;;;;;;;;83122:234;;:::o;91237:416::-;91412:31;91425:4;91431:2;91435:7;91412:12;:31::i;:::-;91476:1;91458:2;:14;;;:19;91454:192;;91497:56;91528:4;91534:2;91538:7;91547:5;91497:30;:56::i;:::-;91492:154;;91574:56;91582:47;;;91574:7;:56::i;:::-;91492:154;91454:192;91237:416;;;;:::o;129064:114::-;129124:13;129157;129150:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129064:114;:::o;17495:718::-;17551:13;17602:14;17639:1;17619:17;17630:5;17619:10;:17::i;:::-;:21;17602:38;;17655:20;17689:6;17678:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17655:41;;17711:11;17840:6;17836:2;17832:15;17824:6;17820:28;17813:35;;17877:290;17884:4;17877:290;;;17909:5;;;;;;;;18051:10;18046:2;18039:5;18035:14;18030:32;18025:3;18017:46;18109:2;18100:11;;;;;;:::i;:::-;;;;;18143:1;18134:5;:10;17877:290;18130:21;17877:290;18188:6;18181:13;;;;;17495:718;;;:::o;72565:178::-;72626:7;65001:13;65139:2;72654:18;:25;72673:5;72654:25;;;;;;;;;;;;;;;;:50;;72653:82;72646:89;;72565:178;;;:::o;71188:385::-;71243:14;71459:15;:13;:15::i;:::-;71443:13;;:31;71434:40;;71514:17;71493;:15;:17::i;:::-;:38;71489:65;;71543:11;;71533:21;;;;71489:65;71188:385;:::o;74413:639::-;74498:4;74837:10;74822:25;;:11;:25;;;;:102;;;;74914:10;74899:25;;:11;:25;;;;74822:102;:179;;;;74991:10;74976:25;;:11;:25;;;;74822:179;74802:199;;74413:639;;;:::o;28666:98::-;28719:7;28746:10;28739:17;;28666:98;:::o;121793:518::-;121888:19;121910:17;:15;:17::i;:::-;121888:39;;;;121957:11;121942:12;:26;;;121938:176;;;122076:12;122090:11;122047:55;;;;;;;;;;;;:::i;:::-;;;;;;;;121938:176;122148:1;122128:22;;:8;:22;;;122124:110;;122219:1;122174:48;;;;;;;;;;;:::i;:::-;;;;;;;;122124:110;122268:35;;;;;;;;122280:8;122268:35;;;;;;122290:12;122268:35;;;;;122246:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121877:434;121793:518;;:::o;84506:335::-;84576:11;84806:15;84798:6;84794:28;84775:16;84767:6;84763:29;84760:63;84750:73;;84506:335;;;:::o;105859:474::-;105988:13;106004:16;106012:7;106004;:16::i;:::-;105988:32;;106037:13;:45;;;;;106077:5;106054:28;;:19;:17;:19::i;:::-;:28;;;;106037:45;106033:201;;;106102:44;106119:5;106126:19;:17;:19::i;:::-;106102:16;:44::i;:::-;106097:137;;106167:51;106175:42;;;106167:7;:51::i;:::-;106097:137;106033:201;106279:2;106246:15;:24;106262:7;106246:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;106317:7;106313:2;106297:28;;106306:5;106297:28;;;;;;;;;;;;105977:356;105859:474;;;:::o;85722:485::-;85824:27;85853:23;85894:38;85935:15;:24;85951:7;85935:24;;;;;;;;;;;85894:65;;86112:18;86089:41;;86169:19;86163:26;86144:45;;86074:126;85722:485;;;:::o;116447:116::-;116516:7;116543:12;:10;:12::i;:::-;116536:19;;116447:116;:::o;84950:659::-;85099:11;85264:16;85257:5;85253:28;85244:37;;85424:16;85413:9;85409:32;85396:45;;85574:15;85563:9;85560:30;85552:5;85541:9;85538:20;85535:56;85525:66;;84950:659;;;;;:::o;115616:359::-;115798:9;115793:175;115817:8;115813:1;:12;115793:175;;;115843:51;115867:4;115873:2;115892:1;115877:12;:16;;;;:::i;:::-;115843:23;:51::i;:::-;115938:3;;;;;115793:175;;;;115616:359;;;;:::o;111734:311::-;111869:7;111889:16;66181:3;111915:19;:41;;111889:68;;66181:3;111983:31;111994:4;112000:2;112004:9;111983:10;:31::i;:::-;111975:40;;:62;;111968:69;;;111734:311;;;;;:::o;80963:450::-;81043:14;81211:16;81204:5;81200:28;81191:37;;81388:5;81374:11;81349:23;81345:41;81342:52;81335:5;81332:63;81322:73;;80963:450;;;;:::o;116082:357::-;116263:9;116258:174;116282:8;116278:1;:12;116258:174;;;116308:50;116331:4;116337:2;116356:1;116341:12;:16;;;;:::i;:::-;116308:22;:50::i;:::-;116402:3;;;;;116258:174;;;;116082:357;;;;:::o;122762:554::-;122872:19;122894:17;:15;:17::i;:::-;122872:39;;;;122941:11;122926:12;:26;;;122922:183;;;123058:7;123067:12;123081:11;123031:62;;;;;;;;;;;;;:::i;:::-;;;;;;;;122922:183;123139:1;123119:22;;:8;:22;;;123115:117;;123200:7;123217:1;123165:55;;;;;;;;;;;;:::i;:::-;;;;;;;;123115:117;123273:35;;;;;;;;123285:8;123273:35;;;;;;123295:12;123273:35;;;;;123244:17;:26;123262:7;123244:26;;;;;;;;;;;:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122861:455;122762:554;;;:::o;81515:324::-;81585:14;81818:1;81808:8;81805:15;81779:24;81775:46;81765:56;;81515:324;;;:::o;93737:691::-;93900:4;93946:2;93921:45;;;93967:19;:17;:19::i;:::-;93988:4;93994:7;94003:5;93921:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;93917:504;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94221:1;94204:6;:13;:18;94200:115;;94243:56;94251:47;;;94243:7;:56::i;:::-;94200:115;94387:6;94381:13;94372:6;94368:2;94364:15;94357:38;93917:504;94090:54;;;94080:64;;;:6;:64;;;;94073:71;;;93737:691;;;;;;:::o;13899:948::-;13952:7;13972:14;13989:1;13972:18;;14039:8;14030:5;:17;14026:106;;14077:8;14068:17;;;;;;:::i;:::-;;;;;14114:2;14104:12;;;;14026:106;14159:8;14150:5;:17;14146:106;;14197:8;14188:17;;;;;;:::i;:::-;;;;;14234:2;14224:12;;;;14146:106;14279:8;14270:5;:17;14266:106;;14317:8;14308:17;;;;;;:::i;:::-;;;;;14354:2;14344:12;;;;14266:106;14399:7;14390:5;:16;14386:103;;14436:7;14427:16;;;;;;:::i;:::-;;;;;14472:1;14462:11;;;;14386:103;14516:7;14507:5;:16;14503:103;;14553:7;14544:16;;;;;;:::i;:::-;;;;;14589:1;14579:11;;;;14503:103;14633:7;14624:5;:16;14620:103;;14670:7;14661:16;;;;;;:::i;:::-;;;;;14706:1;14696:11;;;;14620:103;14750:7;14741:5;:16;14737:68;;14788:1;14778:11;;;;14737:68;14833:6;14826:13;;;13899:948;;;:::o;39597:623::-;39701:20;39740:1;39724:18;;:4;:18;;;39701:41;;39753:18;39788:1;39774:16;;:2;:16;;;39753:37;;39806:15;:32;;;;;39825:13;39806:32;39803:410;;;39862:28;;;;;;;;;;;;;;39803:410;39911:15;39908:305;;;39943:54;39960:12;:10;:12::i;:::-;39974:2;39978:7;39987:9;39943:16;:54::i;:::-;39908:305;;;40018:13;40015:198;;;40048:56;40065:12;:10;:12::i;:::-;40079:4;40085:7;40094:9;40048:16;:56::i;:::-;40015:198;;;40137:64;40158:12;:10;:12::i;:::-;40172:4;40178:2;40182:7;40191:9;40137:20;:64::i;:::-;40015:198;39908:305;39690:530;;39597:623;;;:::o;111435:147::-;111572:6;111435:147;;;;;:::o;40353:625::-;40456:20;40495:1;40479:18;;:4;:18;;;40456:41;;40508:18;40543:1;40529:16;;:2;:16;;;40508:37;;40561:15;:32;;;;;40580:13;40561:32;40558:413;;;40617:28;;;;;;;;;;;;;;40558:413;40666:15;40663:308;;;40698:55;40716:12;:10;:12::i;:::-;40730:2;40734:7;40743:9;40698:17;:55::i;:::-;40663:308;;;40774:13;40771:200;;;40804:57;40822:12;:10;:12::i;:::-;40836:4;40842:7;40851:9;40804:17;:57::i;:::-;40771:200;;;40894:65;40916:12;:10;:12::i;:::-;40930:4;40936:2;40940:7;40949:9;40894:21;:65::i;:::-;40771:200;40663:308;40445:533;;40353:625;;;:::o;41050:105::-;;;;;:::o;41404:107::-;;;;;:::o;53474:344::-;53715:1;53677:40;;53685:17;;;;;;;;;;;53677:40;;;53673:138;;53734:17;;;;;;;;;;;:47;;;53782:6;53790:4;53796:2;53734:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53673:138;53474:344;;;;;:::o;41226:106::-;;;;;:::o;41582:108::-;;;;;:::o;41964:124::-;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;7:126:1:-;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:96::-;176:7;205:24;223:5;205:24;:::i;:::-;194:35;;139:96;;;:::o;241:118::-;328:24;346:5;328:24;:::i;:::-;323:3;316:37;241:118;;:::o;365:222::-;458:4;496:2;485:9;481:18;473:26;;509:71;577:1;566:9;562:17;553:6;509:71;:::i;:::-;365:222;;;;:::o;593:75::-;626:6;659:2;653:9;643:19;;593:75;:::o;674:117::-;783:1;780;773:12;797:117;906:1;903;896:12;920:149;956:7;996:66;989:5;985:78;974:89;;920:149;;;:::o;1075:120::-;1147:23;1164:5;1147:23;:::i;:::-;1140:5;1137:34;1127:62;;1185:1;1182;1175:12;1127:62;1075:120;:::o;1201:137::-;1246:5;1284:6;1271:20;1262:29;;1300:32;1326:5;1300:32;:::i;:::-;1201:137;;;;:::o;1344:327::-;1402:6;1451:2;1439:9;1430:7;1426:23;1422:32;1419:119;;;1457:79;;:::i;:::-;1419:119;1577:1;1602:52;1646:7;1637:6;1626:9;1622:22;1602:52;:::i;:::-;1592:62;;1548:116;1344:327;;;;:::o;1677:90::-;1711:7;1754:5;1747:13;1740:21;1729:32;;1677:90;;;:::o;1773:109::-;1854:21;1869:5;1854:21;:::i;:::-;1849:3;1842:34;1773:109;;:::o;1888:210::-;1975:4;2013:2;2002:9;1998:18;1990:26;;2026:65;2088:1;2077:9;2073:17;2064:6;2026:65;:::i;:::-;1888:210;;;;:::o;2104:122::-;2177:24;2195:5;2177:24;:::i;:::-;2170:5;2167:35;2157:63;;2216:1;2213;2206:12;2157:63;2104:122;:::o;2232:139::-;2278:5;2316:6;2303:20;2294:29;;2332:33;2359:5;2332:33;:::i;:::-;2232:139;;;;:::o;2377:109::-;2413:7;2453:26;2446:5;2442:38;2431:49;;2377:109;;;:::o;2492:120::-;2564:23;2581:5;2564:23;:::i;:::-;2557:5;2554:34;2544:62;;2602:1;2599;2592:12;2544:62;2492:120;:::o;2618:137::-;2663:5;2701:6;2688:20;2679:29;;2717:32;2743:5;2717:32;:::i;:::-;2618:137;;;;:::o;2761:472::-;2828:6;2836;2885:2;2873:9;2864:7;2860:23;2856:32;2853:119;;;2891:79;;:::i;:::-;2853:119;3011:1;3036:53;3081:7;3072:6;3061:9;3057:22;3036:53;:::i;:::-;3026:63;;2982:117;3138:2;3164:52;3208:7;3199:6;3188:9;3184:22;3164:52;:::i;:::-;3154:62;;3109:117;2761:472;;;;;:::o;3239:99::-;3291:6;3325:5;3319:12;3309:22;;3239:99;;;:::o;3344:169::-;3428:11;3462:6;3457:3;3450:19;3502:4;3497:3;3493:14;3478:29;;3344:169;;;;:::o;3519:139::-;3608:6;3603:3;3598;3592:23;3649:1;3640:6;3635:3;3631:16;3624:27;3519:139;;;:::o;3664:102::-;3705:6;3756:2;3752:7;3747:2;3740:5;3736:14;3732:28;3722:38;;3664:102;;;:::o;3772:377::-;3860:3;3888:39;3921:5;3888:39;:::i;:::-;3943:71;4007:6;4002:3;3943:71;:::i;:::-;3936:78;;4023:65;4081:6;4076:3;4069:4;4062:5;4058:16;4023:65;:::i;:::-;4113:29;4135:6;4113:29;:::i;:::-;4108:3;4104:39;4097:46;;3864:285;3772:377;;;;:::o;4155:313::-;4268:4;4306:2;4295:9;4291:18;4283:26;;4355:9;4349:4;4345:20;4341:1;4330:9;4326:17;4319:47;4383:78;4456:4;4447:6;4383:78;:::i;:::-;4375:86;;4155:313;;;;:::o;4474:77::-;4511:7;4540:5;4529:16;;4474:77;;;:::o;4557:122::-;4630:24;4648:5;4630:24;:::i;:::-;4623:5;4620:35;4610:63;;4669:1;4666;4659:12;4610:63;4557:122;:::o;4685:139::-;4731:5;4769:6;4756:20;4747:29;;4785:33;4812:5;4785:33;:::i;:::-;4685:139;;;;:::o;4830:329::-;4889:6;4938:2;4926:9;4917:7;4913:23;4909:32;4906:119;;;4944:79;;:::i;:::-;4906:119;5064:1;5089:53;5134:7;5125:6;5114:9;5110:22;5089:53;:::i;:::-;5079:63;;5035:117;4830:329;;;;:::o;5165:474::-;5233:6;5241;5290:2;5278:9;5269:7;5265:23;5261:32;5258:119;;;5296:79;;:::i;:::-;5258:119;5416:1;5441:53;5486:7;5477:6;5466:9;5462:22;5441:53;:::i;:::-;5431:63;;5387:117;5543:2;5569:53;5614:7;5605:6;5594:9;5590:22;5569:53;:::i;:::-;5559:63;;5514:118;5165:474;;;;;:::o;5645:60::-;5673:3;5694:5;5687:12;;5645:60;;;:::o;5711:142::-;5761:9;5794:53;5812:34;5821:24;5839:5;5821:24;:::i;:::-;5812:34;:::i;:::-;5794:53;:::i;:::-;5781:66;;5711:142;;;:::o;5859:126::-;5909:9;5942:37;5973:5;5942:37;:::i;:::-;5929:50;;5859:126;;;:::o;5991:165::-;6080:9;6113:37;6144:5;6113:37;:::i;:::-;6100:50;;5991:165;;;:::o;6162:209::-;6288:76;6358:5;6288:76;:::i;:::-;6283:3;6276:89;6162:209;;:::o;6377:300::-;6509:4;6547:2;6536:9;6532:18;6524:26;;6560:110;6667:1;6656:9;6652:17;6643:6;6560:110;:::i;:::-;6377:300;;;;:::o;6683:117::-;6792:1;6789;6782:12;6806:117;6915:1;6912;6905:12;6929:117;7038:1;7035;7028:12;7066:553;7124:8;7134:6;7184:3;7177:4;7169:6;7165:17;7161:27;7151:122;;7192:79;;:::i;:::-;7151:122;7305:6;7292:20;7282:30;;7335:18;7327:6;7324:30;7321:117;;;7357:79;;:::i;:::-;7321:117;7471:4;7463:6;7459:17;7447:29;;7525:3;7517:4;7509:6;7505:17;7495:8;7491:32;7488:41;7485:128;;;7532:79;;:::i;:::-;7485:128;7066:553;;;;;:::o;7625:529::-;7696:6;7704;7753:2;7741:9;7732:7;7728:23;7724:32;7721:119;;;7759:79;;:::i;:::-;7721:119;7907:1;7896:9;7892:17;7879:31;7937:18;7929:6;7926:30;7923:117;;;7959:79;;:::i;:::-;7923:117;8072:65;8129:7;8120:6;8109:9;8105:22;8072:65;:::i;:::-;8054:83;;;;7850:297;7625:529;;;;;:::o;8160:118::-;8247:24;8265:5;8247:24;:::i;:::-;8242:3;8235:37;8160:118;;:::o;8284:222::-;8377:4;8415:2;8404:9;8400:18;8392:26;;8428:71;8496:1;8485:9;8481:17;8472:6;8428:71;:::i;:::-;8284:222;;;;:::o;8512:619::-;8589:6;8597;8605;8654:2;8642:9;8633:7;8629:23;8625:32;8622:119;;;8660:79;;:::i;:::-;8622:119;8780:1;8805:53;8850:7;8841:6;8830:9;8826:22;8805:53;:::i;:::-;8795:63;;8751:117;8907:2;8933:53;8978:7;8969:6;8958:9;8954:22;8933:53;:::i;:::-;8923:63;;8878:118;9035:2;9061:53;9106:7;9097:6;9086:9;9082:22;9061:53;:::i;:::-;9051:63;;9006:118;8512:619;;;;;:::o;9137:180::-;9185:77;9182:1;9175:88;9282:4;9279:1;9272:15;9306:4;9303:1;9296:15;9323:132;9423:1;9416:5;9413:12;9403:46;;9429:18;;:::i;:::-;9403:46;9323:132;:::o;9461:165::-;9525:7;9554:5;9543:16;;9560:60;9614:5;9560:60;:::i;:::-;9461:165;;;:::o;9632:::-;9707:9;9740:51;9785:5;9740:51;:::i;:::-;9727:64;;9632:165;;;:::o;9803:181::-;9915:62;9971:5;9915:62;:::i;:::-;9910:3;9903:75;9803:181;;:::o;9990:272::-;10108:4;10146:2;10135:9;10131:18;10123:26;;10159:96;10252:1;10241:9;10237:17;10228:6;10159:96;:::i;:::-;9990:272;;;;:::o;10268:619::-;10345:6;10353;10361;10410:2;10398:9;10389:7;10385:23;10381:32;10378:119;;;10416:79;;:::i;:::-;10378:119;10536:1;10561:53;10606:7;10597:6;10586:9;10582:22;10561:53;:::i;:::-;10551:63;;10507:117;10663:2;10689:53;10734:7;10725:6;10714:9;10710:22;10689:53;:::i;:::-;10679:63;;10634:118;10791:2;10817:53;10862:7;10853:6;10842:9;10838:22;10817:53;:::i;:::-;10807:63;;10762:118;10268:619;;;;;:::o;10893:474::-;10961:6;10969;11018:2;11006:9;10997:7;10993:23;10989:32;10986:119;;;11024:79;;:::i;:::-;10986:119;11144:1;11169:53;11214:7;11205:6;11194:9;11190:22;11169:53;:::i;:::-;11159:63;;11115:117;11271:2;11297:53;11342:7;11333:6;11322:9;11318:22;11297:53;:::i;:::-;11287:63;;11242:118;10893:474;;;;;:::o;11373:332::-;11494:4;11532:2;11521:9;11517:18;11509:26;;11545:71;11613:1;11602:9;11598:17;11589:6;11545:71;:::i;:::-;11626:72;11694:2;11683:9;11679:18;11670:6;11626:72;:::i;:::-;11373:332;;;;;:::o;11711:329::-;11770:6;11819:2;11807:9;11798:7;11794:23;11790:32;11787:119;;;11825:79;;:::i;:::-;11787:119;11945:1;11970:53;12015:7;12006:6;11995:9;11991:22;11970:53;:::i;:::-;11960:63;;11916:117;11711:329;;;;:::o;12046:114::-;12113:6;12147:5;12141:12;12131:22;;12046:114;;;:::o;12166:184::-;12265:11;12299:6;12294:3;12287:19;12339:4;12334:3;12330:14;12315:29;;12166:184;;;;:::o;12356:132::-;12423:4;12446:3;12438:11;;12476:4;12471:3;12467:14;12459:22;;12356:132;;;:::o;12494:108::-;12571:24;12589:5;12571:24;:::i;:::-;12566:3;12559:37;12494:108;;:::o;12608:179::-;12677:10;12698:46;12740:3;12732:6;12698:46;:::i;:::-;12776:4;12771:3;12767:14;12753:28;;12608:179;;;;:::o;12793:113::-;12863:4;12895;12890:3;12886:14;12878:22;;12793:113;;;:::o;12942:732::-;13061:3;13090:54;13138:5;13090:54;:::i;:::-;13160:86;13239:6;13234:3;13160:86;:::i;:::-;13153:93;;13270:56;13320:5;13270:56;:::i;:::-;13349:7;13380:1;13365:284;13390:6;13387:1;13384:13;13365:284;;;13466:6;13460:13;13493:63;13552:3;13537:13;13493:63;:::i;:::-;13486:70;;13579:60;13632:6;13579:60;:::i;:::-;13569:70;;13425:224;13412:1;13409;13405:9;13400:14;;13365:284;;;13369:14;13665:3;13658:10;;13066:608;;;12942:732;;;;:::o;13680:373::-;13823:4;13861:2;13850:9;13846:18;13838:26;;13910:9;13904:4;13900:20;13896:1;13885:9;13881:17;13874:47;13938:108;14041:4;14032:6;13938:108;:::i;:::-;13930:116;;13680:373;;;;:::o;14059:617::-;14135:6;14143;14151;14200:2;14188:9;14179:7;14175:23;14171:32;14168:119;;;14206:79;;:::i;:::-;14168:119;14326:1;14351:53;14396:7;14387:6;14376:9;14372:22;14351:53;:::i;:::-;14341:63;;14297:117;14453:2;14479:53;14524:7;14515:6;14504:9;14500:22;14479:53;:::i;:::-;14469:63;;14424:118;14581:2;14607:52;14651:7;14642:6;14631:9;14627:22;14607:52;:::i;:::-;14597:62;;14552:117;14059:617;;;;;:::o;14682:116::-;14719:7;14759:32;14752:5;14748:44;14737:55;;14682:116;;;:::o;14804:118::-;14891:24;14909:5;14891:24;:::i;:::-;14886:3;14879:37;14804:118;;:::o;14928:222::-;15021:4;15059:2;15048:9;15044:18;15036:26;;15072:71;15140:1;15129:9;15125:17;15116:6;15072:71;:::i;:::-;14928:222;;;;:::o;15156:126::-;15256:1;15249:5;15246:12;15236:40;;15272:1;15269;15262:12;15236:40;15156:126;:::o;15288:193::-;15361:5;15399:6;15386:20;15377:29;;15415:60;15469:5;15415:60;:::i;:::-;15288:193;;;;:::o;15487:122::-;15560:24;15578:5;15560:24;:::i;:::-;15553:5;15550:35;15540:63;;15599:1;15596;15589:12;15540:63;15487:122;:::o;15615:139::-;15661:5;15699:6;15686:20;15677:29;;15715:33;15742:5;15715:33;:::i;:::-;15615:139;;;;:::o;15760:673::-;15864:6;15872;15880;15929:2;15917:9;15908:7;15904:23;15900:32;15897:119;;;15935:79;;:::i;:::-;15897:119;16055:1;16080:80;16152:7;16143:6;16132:9;16128:22;16080:80;:::i;:::-;16070:90;;16026:144;16209:2;16235:53;16280:7;16271:6;16260:9;16256:22;16235:53;:::i;:::-;16225:63;;16180:118;16337:2;16363:53;16408:7;16399:6;16388:9;16384:22;16363:53;:::i;:::-;16353:63;;16308:118;15760:673;;;;;:::o;16439:116::-;16509:21;16524:5;16509:21;:::i;:::-;16502:5;16499:32;16489:60;;16545:1;16542;16535:12;16489:60;16439:116;:::o;16561:133::-;16604:5;16642:6;16629:20;16620:29;;16658:30;16682:5;16658:30;:::i;:::-;16561:133;;;;:::o;16700:468::-;16765:6;16773;16822:2;16810:9;16801:7;16797:23;16793:32;16790:119;;;16828:79;;:::i;:::-;16790:119;16948:1;16973:53;17018:7;17009:6;16998:9;16994:22;16973:53;:::i;:::-;16963:63;;16919:117;17075:2;17101:50;17143:7;17134:6;17123:9;17119:22;17101:50;:::i;:::-;17091:60;;17046:115;16700:468;;;;;:::o;17174:323::-;17230:6;17279:2;17267:9;17258:7;17254:23;17250:32;17247:119;;;17285:79;;:::i;:::-;17247:119;17405:1;17430:50;17472:7;17463:6;17452:9;17448:22;17430:50;:::i;:::-;17420:60;;17376:114;17174:323;;;;:::o;17503:117::-;17612:1;17609;17602:12;17626:180;17674:77;17671:1;17664:88;17771:4;17768:1;17761:15;17795:4;17792:1;17785:15;17812:281;17895:27;17917:4;17895:27;:::i;:::-;17887:6;17883:40;18025:6;18013:10;18010:22;17989:18;17977:10;17974:34;17971:62;17968:88;;;18036:18;;:::i;:::-;17968:88;18076:10;18072:2;18065:22;17855:238;17812:281;;:::o;18099:129::-;18133:6;18160:20;;:::i;:::-;18150:30;;18189:33;18217:4;18209:6;18189:33;:::i;:::-;18099:129;;;:::o;18234:307::-;18295:4;18385:18;18377:6;18374:30;18371:56;;;18407:18;;:::i;:::-;18371:56;18445:29;18467:6;18445:29;:::i;:::-;18437:37;;18529:4;18523;18519:15;18511:23;;18234:307;;;:::o;18547:148::-;18645:6;18640:3;18635;18622:30;18686:1;18677:6;18672:3;18668:16;18661:27;18547:148;;;:::o;18701:423::-;18778:5;18803:65;18819:48;18860:6;18819:48;:::i;:::-;18803:65;:::i;:::-;18794:74;;18891:6;18884:5;18877:21;18929:4;18922:5;18918:16;18967:3;18958:6;18953:3;18949:16;18946:25;18943:112;;;18974:79;;:::i;:::-;18943:112;19064:54;19111:6;19106:3;19101;19064:54;:::i;:::-;18784:340;18701:423;;;;;:::o;19143:338::-;19198:5;19247:3;19240:4;19232:6;19228:17;19224:27;19214:122;;19255:79;;:::i;:::-;19214:122;19372:6;19359:20;19397:78;19471:3;19463:6;19456:4;19448:6;19444:17;19397:78;:::i;:::-;19388:87;;19204:277;19143:338;;;;:::o;19487:943::-;19582:6;19590;19598;19606;19655:3;19643:9;19634:7;19630:23;19626:33;19623:120;;;19662:79;;:::i;:::-;19623:120;19782:1;19807:53;19852:7;19843:6;19832:9;19828:22;19807:53;:::i;:::-;19797:63;;19753:117;19909:2;19935:53;19980:7;19971:6;19960:9;19956:22;19935:53;:::i;:::-;19925:63;;19880:118;20037:2;20063:53;20108:7;20099:6;20088:9;20084:22;20063:53;:::i;:::-;20053:63;;20008:118;20193:2;20182:9;20178:18;20165:32;20224:18;20216:6;20213:30;20210:117;;;20246:79;;:::i;:::-;20210:117;20351:62;20405:7;20396:6;20385:9;20381:22;20351:62;:::i;:::-;20341:72;;20136:287;19487:943;;;;;;;:::o;20436:171::-;20538:62;20594:5;20538:62;:::i;:::-;20533:3;20526:75;20436:171;;:::o;20613:108::-;20690:24;20708:5;20690:24;:::i;:::-;20685:3;20678:37;20613:108;;:::o;20801:796::-;20982:4;20977:3;20973:14;21086:4;21079:5;21075:16;21069:23;21105:88;21187:4;21182:3;21178:14;21164:12;21105:88;:::i;:::-;20997:206;21300:4;21293:5;21289:16;21283:23;21319:63;21376:4;21371:3;21367:14;21353:12;21319:63;:::i;:::-;21213:179;21498:4;21491:5;21487:16;21481:23;21517:63;21574:4;21569:3;21565:14;21551:12;21517:63;:::i;:::-;21402:188;20951:646;20801:796;;:::o;21603:390::-;21780:4;21818:2;21807:9;21803:18;21795:26;;21831:155;21983:1;21972:9;21968:17;21959:6;21831:155;:::i;:::-;21603:390;;;;:::o;21999:474::-;22067:6;22075;22124:2;22112:9;22103:7;22099:23;22095:32;22092:119;;;22130:79;;:::i;:::-;22092:119;22250:1;22275:53;22320:7;22311:6;22300:9;22296:22;22275:53;:::i;:::-;22265:63;;22221:117;22377:2;22403:53;22448:7;22439:6;22428:9;22424:22;22403:53;:::i;:::-;22393:63;;22348:118;21999:474;;;;;:::o;22479:819::-;22592:6;22600;22608;22616;22665:3;22653:9;22644:7;22640:23;22636:33;22633:120;;;22672:79;;:::i;:::-;22633:120;22792:1;22817:53;22862:7;22853:6;22842:9;22838:22;22817:53;:::i;:::-;22807:63;;22763:117;22919:2;22945:80;23017:7;23008:6;22997:9;22993:22;22945:80;:::i;:::-;22935:90;;22890:145;23074:2;23100:53;23145:7;23136:6;23125:9;23121:22;23100:53;:::i;:::-;23090:63;;23045:118;23202:2;23228:53;23273:7;23264:6;23253:9;23249:22;23228:53;:::i;:::-;23218:63;;23173:118;22479:819;;;;;;;:::o;23304:180::-;23352:77;23349:1;23342:88;23449:4;23446:1;23439:15;23473:4;23470:1;23463:15;23490:320;23534:6;23571:1;23565:4;23561:12;23551:22;;23618:1;23612:4;23608:12;23639:18;23629:81;;23695:4;23687:6;23683:17;23673:27;;23629:81;23757:2;23749:6;23746:14;23726:18;23723:38;23720:84;;23776:18;;:::i;:::-;23720:84;23541:269;23490:320;;;:::o;23816:97::-;23875:6;23903:3;23893:13;;23816:97;;;;:::o;23919:141::-;23968:4;23991:3;23983:11;;24014:3;24011:1;24004:14;24048:4;24045:1;24035:18;24027:26;;23919:141;;;:::o;24066:93::-;24103:6;24150:2;24145;24138:5;24134:14;24130:23;24120:33;;24066:93;;;:::o;24165:107::-;24209:8;24259:5;24253:4;24249:16;24228:37;;24165:107;;;;:::o;24278:393::-;24347:6;24397:1;24385:10;24381:18;24420:97;24450:66;24439:9;24420:97;:::i;:::-;24538:39;24568:8;24557:9;24538:39;:::i;:::-;24526:51;;24610:4;24606:9;24599:5;24595:21;24586:30;;24659:4;24649:8;24645:19;24638:5;24635:30;24625:40;;24354:317;;24278:393;;;;;:::o;24677:142::-;24727:9;24760:53;24778:34;24787:24;24805:5;24787:24;:::i;:::-;24778:34;:::i;:::-;24760:53;:::i;:::-;24747:66;;24677:142;;;:::o;24825:75::-;24868:3;24889:5;24882:12;;24825:75;;;:::o;24906:269::-;25016:39;25047:7;25016:39;:::i;:::-;25077:91;25126:41;25150:16;25126:41;:::i;:::-;25118:6;25111:4;25105:11;25077:91;:::i;:::-;25071:4;25064:105;24982:193;24906:269;;;:::o;25181:73::-;25226:3;25181:73;:::o;25260:189::-;25337:32;;:::i;:::-;25378:65;25436:6;25428;25422:4;25378:65;:::i;:::-;25313:136;25260:189;;:::o;25455:186::-;25515:120;25532:3;25525:5;25522:14;25515:120;;;25586:39;25623:1;25616:5;25586:39;:::i;:::-;25559:1;25552:5;25548:13;25539:22;;25515:120;;;25455:186;;:::o;25647:543::-;25748:2;25743:3;25740:11;25737:446;;;25782:38;25814:5;25782:38;:::i;:::-;25866:29;25884:10;25866:29;:::i;:::-;25856:8;25852:44;26049:2;26037:10;26034:18;26031:49;;;26070:8;26055:23;;26031:49;26093:80;26149:22;26167:3;26149:22;:::i;:::-;26139:8;26135:37;26122:11;26093:80;:::i;:::-;25752:431;;25737:446;25647:543;;;:::o;26196:117::-;26250:8;26300:5;26294:4;26290:16;26269:37;;26196:117;;;;:::o;26319:169::-;26363:6;26396:51;26444:1;26440:6;26432:5;26429:1;26425:13;26396:51;:::i;:::-;26392:56;26477:4;26471;26467:15;26457:25;;26370:118;26319:169;;;;:::o;26493:295::-;26569:4;26715:29;26740:3;26734:4;26715:29;:::i;:::-;26707:37;;26777:3;26774:1;26770:11;26764:4;26761:21;26753:29;;26493:295;;;;:::o;26793:1403::-;26917:44;26957:3;26952;26917:44;:::i;:::-;27026:18;27018:6;27015:30;27012:56;;;27048:18;;:::i;:::-;27012:56;27092:38;27124:4;27118:11;27092:38;:::i;:::-;27177:67;27237:6;27229;27223:4;27177:67;:::i;:::-;27271:1;27300:2;27292:6;27289:14;27317:1;27312:632;;;;27988:1;28005:6;28002:84;;;28061:9;28056:3;28052:19;28039:33;28030:42;;28002:84;28112:67;28172:6;28165:5;28112:67;:::i;:::-;28106:4;28099:81;27961:229;27282:908;;27312:632;27364:4;27360:9;27352:6;27348:22;27398:37;27430:4;27398:37;:::i;:::-;27457:1;27471:215;27485:7;27482:1;27479:14;27471:215;;;27571:9;27566:3;27562:19;27549:33;27541:6;27534:49;27622:1;27614:6;27610:14;27600:24;;27669:2;27658:9;27654:18;27641:31;;27508:4;27505:1;27501:12;27496:17;;27471:215;;;27714:6;27705:7;27702:19;27699:186;;;27779:9;27774:3;27770:19;27757:33;27822:48;27864:4;27856:6;27852:17;27841:9;27822:48;:::i;:::-;27814:6;27807:64;27722:163;27699:186;27931:1;27927;27919:6;27915:14;27911:22;27905:4;27898:36;27319:625;;;27282:908;;26892:1304;;;26793:1403;;;:::o;28202:442::-;28351:4;28389:2;28378:9;28374:18;28366:26;;28402:71;28470:1;28459:9;28455:17;28446:6;28402:71;:::i;:::-;28483:72;28551:2;28540:9;28536:18;28527:6;28483:72;:::i;:::-;28565;28633:2;28622:9;28618:18;28609:6;28565:72;:::i;:::-;28202:442;;;;;;:::o;28650:180::-;28698:77;28695:1;28688:88;28795:4;28792:1;28785:15;28819:4;28816:1;28809:15;28836:410;28876:7;28899:20;28917:1;28899:20;:::i;:::-;28894:25;;28933:20;28951:1;28933:20;:::i;:::-;28928:25;;28988:1;28985;28981:9;29010:30;29028:11;29010:30;:::i;:::-;28999:41;;29189:1;29180:7;29176:15;29173:1;29170:22;29150:1;29143:9;29123:83;29100:139;;29219:18;;:::i;:::-;29100:139;28884:362;28836:410;;;;:::o;29252:180::-;29300:77;29297:1;29290:88;29397:4;29394:1;29387:15;29421:4;29418:1;29411:15;29438:185;29478:1;29495:20;29513:1;29495:20;:::i;:::-;29490:25;;29529:20;29547:1;29529:20;:::i;:::-;29524:25;;29568:1;29558:35;;29573:18;;:::i;:::-;29558:35;29615:1;29612;29608:9;29603:14;;29438:185;;;;:::o;29629:117::-;29738:1;29735;29728:12;29875:197;29959:5;29990:6;29984:13;29975:22;;30006:60;30060:5;30006:60;:::i;:::-;29875:197;;;;:::o;30078:143::-;30135:5;30166:6;30160:13;30151:22;;30182:33;30209:5;30182:33;:::i;:::-;30078:143;;;;:::o;30266:879::-;30368:5;30412:4;30400:9;30395:3;30391:19;30387:30;30384:117;;;30420:79;;:::i;:::-;30384:117;30519:21;30535:4;30519:21;:::i;:::-;30510:30;;30616:1;30656:87;30739:3;30730:6;30719:9;30715:22;30656:87;:::i;:::-;30649:4;30642:5;30638:16;30631:113;30550:205;30829:2;30870:60;30926:3;30917:6;30906:9;30902:22;30870:60;:::i;:::-;30863:4;30856:5;30852:16;30845:86;30765:177;31025:2;31066:60;31122:3;31113:6;31102:9;31098:22;31066:60;:::i;:::-;31059:4;31052:5;31048:16;31041:86;30952:186;30266:879;;;;:::o;31151:435::-;31263:6;31312:2;31300:9;31291:7;31287:23;31283:32;31280:119;;;31318:79;;:::i;:::-;31280:119;31438:1;31463:106;31561:7;31552:6;31541:9;31537:22;31463:106;:::i;:::-;31453:116;;31409:170;31151:435;;;;:::o;31592:332::-;31713:4;31751:2;31740:9;31736:18;31728:26;;31764:71;31832:1;31821:9;31817:17;31808:6;31764:71;:::i;:::-;31845:72;31913:2;31902:9;31898:18;31889:6;31845:72;:::i;:::-;31592:332;;;;;:::o;31930:137::-;31984:5;32015:6;32009:13;32000:22;;32031:30;32055:5;32031:30;:::i;:::-;31930:137;;;;:::o;32073:345::-;32140:6;32189:2;32177:9;32168:7;32164:23;32160:32;32157:119;;;32195:79;;:::i;:::-;32157:119;32315:1;32340:61;32393:7;32384:6;32373:9;32369:22;32340:61;:::i;:::-;32330:71;;32286:125;32073:345;;;;:::o;32424:147::-;32525:11;32562:3;32547:18;;32424:147;;;;:::o;32577:114::-;;:::o;32697:398::-;32856:3;32877:83;32958:1;32953:3;32877:83;:::i;:::-;32870:90;;32969:93;33058:3;32969:93;:::i;:::-;33087:1;33082:3;33078:11;33071:18;;32697:398;;;:::o;33101:379::-;33285:3;33307:147;33450:3;33307:147;:::i;:::-;33300:154;;33471:3;33464:10;;33101:379;;;:::o;33486:311::-;33563:4;33653:18;33645:6;33642:30;33639:56;;;33675:18;;:::i;:::-;33639:56;33725:4;33717:6;33713:17;33705:25;;33785:4;33779;33775:15;33767:23;;33486:311;;;:::o;33803:143::-;33860:5;33891:6;33885:13;33876:22;;33907:33;33934:5;33907:33;:::i;:::-;33803:143;;;;:::o;33969:732::-;34076:5;34101:81;34117:64;34174:6;34117:64;:::i;:::-;34101:81;:::i;:::-;34092:90;;34202:5;34231:6;34224:5;34217:21;34265:4;34258:5;34254:16;34247:23;;34318:4;34310:6;34306:17;34298:6;34294:30;34347:3;34339:6;34336:15;34333:122;;;34366:79;;:::i;:::-;34333:122;34481:6;34464:231;34498:6;34493:3;34490:15;34464:231;;;34573:3;34602:48;34646:3;34634:10;34602:48;:::i;:::-;34597:3;34590:61;34680:4;34675:3;34671:14;34664:21;;34540:155;34524:4;34519:3;34515:14;34508:21;;34464:231;;;34468:21;34082:619;;33969:732;;;;;:::o;34724:385::-;34806:5;34855:3;34848:4;34840:6;34836:17;34832:27;34822:122;;34863:79;;:::i;:::-;34822:122;34973:6;34967:13;34998:105;35099:3;35091:6;35084:4;35076:6;35072:17;34998:105;:::i;:::-;34989:114;;34812:297;34724:385;;;;:::o;35115:554::-;35210:6;35259:2;35247:9;35238:7;35234:23;35230:32;35227:119;;;35265:79;;:::i;:::-;35227:119;35406:1;35395:9;35391:17;35385:24;35436:18;35428:6;35425:30;35422:117;;;35458:79;;:::i;:::-;35422:117;35563:89;35644:7;35635:6;35624:9;35620:22;35563:89;:::i;:::-;35553:99;;35356:306;35115:554;;;;:::o;35675:382::-;35821:4;35859:2;35848:9;35844:18;35836:26;;35872:71;35940:1;35929:9;35925:17;35916:6;35872:71;:::i;:::-;35953:97;36046:2;36035:9;36031:18;36022:6;35953:97;:::i;:::-;35675:382;;;;;:::o;36063:332::-;36184:4;36222:2;36211:9;36207:18;36199:26;;36235:71;36303:1;36292:9;36288:17;36279:6;36235:71;:::i;:::-;36316:72;36384:2;36373:9;36369:18;36360:6;36316:72;:::i;:::-;36063:332;;;;;:::o;36401:169::-;36541:21;36537:1;36529:6;36525:14;36518:45;36401:169;:::o;36576:366::-;36718:3;36739:67;36803:2;36798:3;36739:67;:::i;:::-;36732:74;;36815:93;36904:3;36815:93;:::i;:::-;36933:2;36928:3;36924:12;36917:19;;36576:366;;;:::o;36948:419::-;37114:4;37152:2;37141:9;37137:18;37129:26;;37201:9;37195:4;37191:20;37187:1;37176:9;37172:17;37165:47;37229:131;37355:4;37229:131;:::i;:::-;37221:139;;36948:419;;;:::o;37373:176::-;37513:28;37509:1;37501:6;37497:14;37490:52;37373:176;:::o;37555:366::-;37697:3;37718:67;37782:2;37777:3;37718:67;:::i;:::-;37711:74;;37794:93;37883:3;37794:93;:::i;:::-;37912:2;37907:3;37903:12;37896:19;;37555:366;;;:::o;37927:419::-;38093:4;38131:2;38120:9;38116:18;38108:26;;38180:9;38174:4;38170:20;38166:1;38155:9;38151:17;38144:47;38208:131;38334:4;38208:131;:::i;:::-;38200:139;;37927:419;;;:::o;38352:191::-;38392:3;38411:20;38429:1;38411:20;:::i;:::-;38406:25;;38445:20;38463:1;38445:20;:::i;:::-;38440:25;;38488:1;38485;38481:9;38474:16;;38509:3;38506:1;38503:10;38500:36;;;38516:18;;:::i;:::-;38500:36;38352:191;;;;:::o;38549:166::-;38689:18;38685:1;38677:6;38673:14;38666:42;38549:166;:::o;38721:366::-;38863:3;38884:67;38948:2;38943:3;38884:67;:::i;:::-;38877:74;;38960:93;39049:3;38960:93;:::i;:::-;39078:2;39073:3;39069:12;39062:19;;38721:366;;;:::o;39093:419::-;39259:4;39297:2;39286:9;39282:18;39274:26;;39346:9;39340:4;39336:20;39332:1;39321:9;39317:17;39310:47;39374:131;39500:4;39374:131;:::i;:::-;39366:139;;39093:419;;;:::o;39518:115::-;39603:23;39620:5;39603:23;:::i;:::-;39598:3;39591:36;39518:115;;:::o;39639:218::-;39730:4;39768:2;39757:9;39753:18;39745:26;;39781:69;39847:1;39836:9;39832:17;39823:6;39781:69;:::i;:::-;39639:218;;;;:::o;39863:332::-;39984:4;40022:2;40011:9;40007:18;39999:26;;40035:71;40103:1;40092:9;40088:17;40079:6;40035:71;:::i;:::-;40116:72;40184:2;40173:9;40169:18;40160:6;40116:72;:::i;:::-;39863:332;;;;;:::o;40201:234::-;40341:34;40337:1;40329:6;40325:14;40318:58;40410:17;40405:2;40397:6;40393:15;40386:42;40201:234;:::o;40441:366::-;40583:3;40604:67;40668:2;40663:3;40604:67;:::i;:::-;40597:74;;40680:93;40769:3;40680:93;:::i;:::-;40798:2;40793:3;40789:12;40782:19;;40441:366;;;:::o;40813:419::-;40979:4;41017:2;41006:9;41002:18;40994:26;;41066:9;41060:4;41056:20;41052:1;41041:9;41037:17;41030:47;41094:131;41220:4;41094:131;:::i;:::-;41086:139;;40813:419;;;:::o;41238:148::-;41340:11;41377:3;41362:18;;41238:148;;;;:::o;41392:390::-;41498:3;41526:39;41559:5;41526:39;:::i;:::-;41581:89;41663:6;41658:3;41581:89;:::i;:::-;41574:96;;41679:65;41737:6;41732:3;41725:4;41718:5;41714:16;41679:65;:::i;:::-;41769:6;41764:3;41760:16;41753:23;;41502:280;41392:390;;;;:::o;41788:435::-;41968:3;41990:95;42081:3;42072:6;41990:95;:::i;:::-;41983:102;;42102:95;42193:3;42184:6;42102:95;:::i;:::-;42095:102;;42214:3;42207:10;;41788:435;;;;;:::o;42229:176::-;42369:28;42365:1;42357:6;42353:14;42346:52;42229:176;:::o;42411:366::-;42553:3;42574:67;42638:2;42633:3;42574:67;:::i;:::-;42567:74;;42650:93;42739:3;42650:93;:::i;:::-;42768:2;42763:3;42759:12;42752:19;;42411:366;;;:::o;42783:419::-;42949:4;42987:2;42976:9;42972:18;42964:26;;43036:9;43030:4;43026:20;43022:1;43011:9;43007:17;43000:47;43064:131;43190:4;43064:131;:::i;:::-;43056:139;;42783:419;;;:::o;43208:194::-;43248:4;43268:20;43286:1;43268:20;:::i;:::-;43263:25;;43302:20;43320:1;43302:20;:::i;:::-;43297:25;;43346:1;43343;43339:9;43331:17;;43370:1;43364:4;43361:11;43358:37;;;43375:18;;:::i;:::-;43358:37;43208:194;;;;:::o;43408:115::-;43493:23;43510:5;43493:23;:::i;:::-;43488:3;43481:36;43408:115;;:::o;43529:218::-;43620:4;43658:2;43647:9;43643:18;43635:26;;43671:69;43737:1;43726:9;43722:17;43713:6;43671:69;:::i;:::-;43529:218;;;;:::o;43753:171::-;43792:3;43815:24;43833:5;43815:24;:::i;:::-;43806:33;;43861:4;43854:5;43851:15;43848:41;;43869:18;;:::i;:::-;43848:41;43916:1;43909:5;43905:13;43898:20;;43753:171;;;:::o;43930:140::-;43979:9;44012:52;44030:33;44039:23;44056:5;44039:23;:::i;:::-;44030:33;:::i;:::-;44012:52;:::i;:::-;43999:65;;43930:140;;;:::o;44076:129::-;44162:36;44192:5;44162:36;:::i;:::-;44157:3;44150:49;44076:129;;:::o;44211:330::-;44331:4;44369:2;44358:9;44354:18;44346:26;;44382:70;44449:1;44438:9;44434:17;44425:6;44382:70;:::i;:::-;44462:72;44530:2;44519:9;44515:18;44506:6;44462:72;:::i;:::-;44211:330;;;;;:::o;44547:440::-;44695:4;44733:2;44722:9;44718:18;44710:26;;44746:71;44814:1;44803:9;44799:17;44790:6;44746:71;:::i;:::-;44827;44894:2;44883:9;44879:18;44870:6;44827:71;:::i;:::-;44908:72;44976:2;44965:9;44961:18;44952:6;44908:72;:::i;:::-;44547:440;;;;;;:::o;44993:332::-;45114:4;45152:2;45141:9;45137:18;45129:26;;45165:71;45233:1;45222:9;45218:17;45209:6;45165:71;:::i;:::-;45246:72;45314:2;45303:9;45299:18;45290:6;45246:72;:::i;:::-;44993:332;;;;;:::o;45331:98::-;45382:6;45416:5;45410:12;45400:22;;45331:98;;;:::o;45435:168::-;45518:11;45552:6;45547:3;45540:19;45592:4;45587:3;45583:14;45568:29;;45435:168;;;;:::o;45609:373::-;45695:3;45723:38;45755:5;45723:38;:::i;:::-;45777:70;45840:6;45835:3;45777:70;:::i;:::-;45770:77;;45856:65;45914:6;45909:3;45902:4;45895:5;45891:16;45856:65;:::i;:::-;45946:29;45968:6;45946:29;:::i;:::-;45941:3;45937:39;45930:46;;45699:283;45609:373;;;;:::o;45988:640::-;46183:4;46221:3;46210:9;46206:19;46198:27;;46235:71;46303:1;46292:9;46288:17;46279:6;46235:71;:::i;:::-;46316:72;46384:2;46373:9;46369:18;46360:6;46316:72;:::i;:::-;46398;46466:2;46455:9;46451:18;46442:6;46398:72;:::i;:::-;46517:9;46511:4;46507:20;46502:2;46491:9;46487:18;46480:48;46545:76;46616:4;46607:6;46545:76;:::i;:::-;46537:84;;45988:640;;;;;;;:::o;46634:141::-;46690:5;46721:6;46715:13;46706:22;;46737:32;46763:5;46737:32;:::i;:::-;46634:141;;;;:::o;46781:349::-;46850:6;46899:2;46887:9;46878:7;46874:23;46870:32;46867:119;;;46905:79;;:::i;:::-;46867:119;47025:1;47050:63;47105:7;47096:6;47085:9;47081:22;47050:63;:::i;:::-;47040:73;;46996:127;46781:349;;;;:::o

Swarm Source

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