ETH Price: $3,254.88 (+2.50%)
Gas: 2 Gwei

Token

Meta-Life Vehicle (MLV)
 

Overview

Max Total Supply

335 MLV

Holders

184

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 MLV
0xaF14020D77E37634dc32D42006Fb88C891EC63cc
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:
MetaLifeVehicle

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-12-02
*/

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

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

//
// OpenZeppelin Contracts (last updated v5.0.0) (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;
    }
}

// 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: @openzeppelin/contracts/utils/ReentrancyGuard.sol

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

pragma solidity ^0.8.20;

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

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

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

// File: contracts/ERC721.sol

//
pragma solidity ^0.8.4;

/// @notice Simple ERC721 implementation with storage hitchhiking.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol)
///
/// @dev Note:
/// The ERC721 standard allows for self-approvals.
/// For performance, this implementation WILL NOT revert for such actions.
/// Please add any checks with overrides if desired.
abstract contract ERC721 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev An account can hold up to 4294967295 tokens.
    uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Only the token owner or an approved account can manage the token.
    error NotOwnerNorApproved();

    /// @dev The token does not exist.
    error TokenDoesNotExist();

    /// @dev The token already exists.
    error TokenAlreadyExists();

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

    /// @dev Cannot mint or transfer to the zero address.
    error TransferToZeroAddress();

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

    /// @dev The recipient's balance has overflowed.
    error AccountBalanceOverflow();

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

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

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

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

    /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens.
    event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved);

    /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`.
    uint256 private constant _TRANSFER_EVENT_SIGNATURE =
    0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`.
    uint256 private constant _APPROVAL_EVENT_SIGNATURE =
    0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;

    /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`.
    uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE =
    0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership data slot of `id` is given by:
    /// ```
    ///     mstore(0x00, id)
    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
    ///     let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
    /// ```
    /// Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `extraData`
    ///
    /// The approved address slot is given by: `add(1, ownershipSlot)`.
    ///
    /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip
    ///
    /// The balance slot of `owner` is given by:
    /// ```
    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
    ///     mstore(0x00, owner)
    ///     let balanceSlot := keccak256(0x0c, 0x1c)
    /// ```
    /// Bits Layout:
    /// - [0..31]   `balance`
    /// - [32..225] `aux`
    ///
    /// The `operator` approval slot of `owner` is given by:
    /// ```
    ///     mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))
    ///     mstore(0x00, owner)
    ///     let operatorApprovalSlot := keccak256(0x0c, 0x30)
    /// ```
    uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192;

    /// @dev Pre-shifted and pre-masked constant.
    uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC721 METADATA                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

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

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

    /// @dev Returns the Uniform Resource Identifier (URI) for token `id`.
    function tokenURI(uint256 id) public view virtual returns (string memory);

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           ERC721                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of token `id`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    function ownerOf(uint256 id) public view virtual returns (address result) {
        result = _ownerOf(id);
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(result) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns the number of tokens owned by `owner`.
    ///
    /// Requirements:
    /// - `owner` must not be the zero address.
    function balanceOf(address owner) public view virtual returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
        // Revert if the `owner` is the zero address.
            if iszero(owner) {
                mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`.
                revert(0x1c, 0x04)
            }
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            mstore(0x00, owner)
            result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE)
        }
    }

    /// @dev Returns the account approved to managed token `id`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    function getApproved(uint256 id) public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            if iszero(shr(96, shl(96, sload(ownershipSlot)))) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
            result := sload(add(1, ownershipSlot))
        }
    }

    /// @dev Sets `account` as the approved account to manage token `id`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    /// - The caller must be the owner of the token,
    ///   or an approved operator for the token owner.
    ///
    /// Emits a {Approval} event.
    function approve(address account, uint256 id) public payable virtual {
        _approve(msg.sender, account, id);
    }

    /// @dev Returns whether `operator` is approved to manage the tokens of `owner`.
    function isApprovedForAll(address owner, address operator)
    public
    view
    virtual
    returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1c, operator)
            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
            mstore(0x00, owner)
            result := sload(keccak256(0x0c, 0x30))
        }
    }

    /// @dev Sets whether `operator` is approved to manage the tokens of the caller.
    ///
    /// Emits a {ApprovalForAll} event.
    function setApprovalForAll(address operator, bool isApproved) public virtual {
        /// @solidity memory-safe-assembly
        assembly {
        // Convert to 0 or 1.
            isApproved := iszero(iszero(isApproved))
        // Update the `isApproved` for (`msg.sender`, `operator`).
            mstore(0x1c, operator)
            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x30), isApproved)
        // Emit the {ApprovalForAll} event.
            mstore(0x00, isApproved)
            log3(
            0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))
            )
        }
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - The caller must be the owner of the token, or be approved to manage the token.
    ///
    /// Emits a {Transfer} event.
    function transferFrom(address from, address to, uint256 id) public payable virtual {
        _beforeTokenTransfer(from, to, id);
        /// @solidity memory-safe-assembly
        assembly {
        // Clear the upper 96 bits.
            let bitmaskAddress := shr(96, not(0))
            from := and(bitmaskAddress, from)
            to := and(bitmaskAddress, to)
        // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller()))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
            let owner := and(bitmaskAddress, ownershipPacked)
        // Revert if `from` is not the owner, or does not exist.
            if iszero(mul(owner, eq(owner, from))) {
                if iszero(owner) {
                    mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                    revert(0x1c, 0x04)
                }
                mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`.
                revert(0x1c, 0x04)
            }
        // Revert if `to` is the zero address.
            if iszero(to) {
                mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
                revert(0x1c, 0x04)
            }
        // Load, check, and update the token approval.
            {
                mstore(0x00, from)
                let approvedAddress := sload(add(1, ownershipSlot))
            // Revert if the caller is not the owner, nor approved.
                if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) {
                    if iszero(sload(keccak256(0x0c, 0x30))) {
                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                        revert(0x1c, 0x04)
                    }
                }
            // Delete the approved address if any.
                if approvedAddress { sstore(add(1, ownershipSlot), 0) }
            }
        // Update with the new owner.
            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
        // Decrement the balance of `from`.
            {
                let fromBalanceSlot := keccak256(0x0c, 0x1c)
                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
            }
        // Increment the balance of `to`.
            {
                mstore(0x00, to)
                let toBalanceSlot := keccak256(0x0c, 0x1c)
                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
                if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
                    mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
                    revert(0x1c, 0x04)
                }
                sstore(toBalanceSlot, toBalanceSlotPacked)
            }
        // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
        }
        _afterTokenTransfer(from, to, id);
    }

    /// @dev Equivalent to `safeTransferFrom(from, to, id, "")`.
    function safeTransferFrom(address from, address to, uint256 id) public payable virtual {
        transferFrom(from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, "");
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - The caller must be the owner of the token, or be approved to manage the token.
    /// - 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 id, bytes calldata data)
    public
    payable
    virtual
    {
        transferFrom(from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
    }

    /// @dev Returns true if this contract implements the interface defined by `interfaceId`.
    /// See: https://eips.ethereum.org/EIPS/eip-165
    /// This function call must use less than 30000 gas.
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            let s := shr(224, interfaceId)
        // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f.
            result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  INTERNAL QUERY FUNCTIONS                  */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns if token `id` exists.
    function _exists(uint256 id) internal view virtual returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))
        }
    }

    /// @dev Returns the owner of token `id`.
    /// Returns the zero address instead of reverting if the token does not exist.
    function _ownerOf(uint256 id) internal view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*            INTERNAL DATA HITCHHIKING FUNCTIONS             */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the auxiliary data for `owner`.
    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.
    /// Auxiliary data can be set for any address, even if it does not have any tokens.
    function _getAux(address owner) internal view virtual returns (uint224 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            mstore(0x00, owner)
            result := shr(32, sload(keccak256(0x0c, 0x1c)))
        }
    }

    /// @dev Set the auxiliary data for `owner` to `value`.
    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.
    /// Auxiliary data can be set for any address, even if it does not have any tokens.
    function _setAux(address owner, uint224 value) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            mstore(0x00, owner)
            let balanceSlot := keccak256(0x0c, 0x1c)
            let packed := sload(balanceSlot)
            sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed)))))
        }
    }

    /// @dev Returns the extra data for token `id`.
    /// Minting, transferring, burning a token will not change the extra data.
    /// The extra data can be set on a non-existent token.
    function _getExtraData(uint256 id) internal view virtual returns (uint96 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20)))))
        }
    }

    /// @dev Sets the extra data for token `id` to `value`.
    /// Minting, transferring, burning a token will not change the extra data.
    /// The extra data can be set on a non-existent token.
    function _setExtraData(uint256 id, uint96 value) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let packed := sload(ownershipSlot)
            sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed)))))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  INTERNAL MINT FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Mints token `id` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must not exist.
    /// - `to` cannot be the zero address.
    ///
    /// Emits a {Transfer} event.
    function _mint(address to, uint256 id) internal virtual {
        _beforeTokenTransfer(address(0), to, id);
        /// @solidity memory-safe-assembly
        assembly {
        // Clear the upper 96 bits.
            to := shr(96, shl(96, to))
        // Revert if `to` is the zero address.
            if iszero(to) {
                mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
                revert(0x1c, 0x04)
            }
        // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
        // Revert if the token already exists.
            if shl(96, ownershipPacked) {
                mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`.
                revert(0x1c, 0x04)
            }
        // Update with the owner.
            sstore(ownershipSlot, or(ownershipPacked, to))
        // Increment the balance of the owner.
            {
                mstore(0x00, to)
                let balanceSlot := keccak256(0x0c, 0x1c)
                let balanceSlotPacked := add(sload(balanceSlot), 1)
                if iszero(and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
                    mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
                    revert(0x1c, 0x04)
                }
                sstore(balanceSlot, balanceSlotPacked)
            }
        // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)
        }
        _afterTokenTransfer(address(0), to, id);
    }

    /// @dev Equivalent to `_safeMint(to, id, "")`.
    function _safeMint(address to, uint256 id) internal virtual {
        _safeMint(to, id, "");
    }

    /// @dev Mints token `id` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must not exist.
    /// - `to` cannot be the zero address.
    /// - If `to` refers to a smart contract, it must implement
    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    ///
    /// Emits a {Transfer} event.
    function _safeMint(address to, uint256 id, bytes memory data) internal virtual {
        _mint(to, id);
        if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  INTERNAL BURN FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Equivalent to `_burn(address(0), id)`.
    function _burn(uint256 id) internal virtual {
        _burn(address(0), id);
    }

    /// @dev Destroys token `id`, using `by`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - If `by` is not the zero address,
    ///   it must be the owner of the token, or be approved to manage the token.
    ///
    /// Emits a {Transfer} event.
    function _burn(address by, uint256 id) internal virtual {
        address owner = ownerOf(id);
        _beforeTokenTransfer(owner, address(0), id);
        /// @solidity memory-safe-assembly
        assembly {
        // Clear the upper 96 bits.
            by := shr(96, shl(96, by))
        // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
        // Reload the owner in case it is changed in `_beforeTokenTransfer`.
            owner := shr(96, shl(96, ownershipPacked))
        // Revert if the token does not exist.
            if iszero(owner) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
        // Load and check the token approval.
            {
                mstore(0x00, owner)
                let approvedAddress := sload(add(1, ownershipSlot))
            // If `by` is not the zero address, do the authorization check.
            // Revert if the `by` is not the owner, nor approved.
                if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) {
                    if iszero(sload(keccak256(0x0c, 0x30))) {
                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                        revert(0x1c, 0x04)
                    }
                }
            // Delete the approved address if any.
                if approvedAddress { sstore(add(1, ownershipSlot), 0) }
            }
        // Clear the owner.
            sstore(ownershipSlot, xor(ownershipPacked, owner))
        // Decrement the balance of `owner`.
            {
                let balanceSlot := keccak256(0x0c, 0x1c)
                sstore(balanceSlot, sub(sload(balanceSlot), 1))
            }
        // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id)
        }
        _afterTokenTransfer(owner, address(0), id);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                INTERNAL APPROVAL FUNCTIONS                 */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns whether `account` is the owner of token `id`, or is approved to managed it.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    function _isApprovedOrOwner(address account, uint256 id)
    internal
    view
    virtual
    returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            result := 1
        // Clear the upper 96 bits.
            account := shr(96, shl(96, account))
        // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let owner := shr(96, shl(96, sload(ownershipSlot)))
        // Revert if the token does not exist.
            if iszero(owner) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
        // Check if `account` is the `owner`.
            if iszero(eq(account, owner)) {
                mstore(0x00, owner)
            // Check if `account` is approved to
                if iszero(sload(keccak256(0x0c, 0x30))) {
                    result := eq(account, sload(add(1, ownershipSlot)))
                }
            }
        }
    }

    /// @dev Returns the account approved to manage token `id`.
    /// Returns the zero address instead of reverting if the token does not exist.
    function _getApproved(uint256 id) internal view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20)))))
        }
    }

    /// @dev Equivalent to `_approve(address(0), account, id)`.
    function _approve(address account, uint256 id) internal virtual {
        _approve(address(0), account, id);
    }

    /// @dev Sets `account` as the approved account to manage token `id`, using `by`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    /// - If `by` is not the zero address, `by` must be the owner
    ///   or an approved operator for the token owner.
    ///
    /// Emits a {Transfer} event.
    function _approve(address by, address account, uint256 id) internal virtual {
        assembly {
        // Clear the upper 96 bits.
            let bitmaskAddress := shr(96, not(0))
            account := and(bitmaskAddress, account)
            by := and(bitmaskAddress, by)
        // Load the owner of the token.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let owner := and(bitmaskAddress, sload(ownershipSlot))
        // Revert if the token does not exist.
            if iszero(owner) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
        // If `by` is not the zero address, do the authorization check.
        // Revert if `by` is not the owner, nor approved.
            if iszero(or(iszero(by), eq(by, owner))) {
                mstore(0x00, owner)
                if iszero(sload(keccak256(0x0c, 0x30))) {
                    mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                    revert(0x1c, 0x04)
                }
            }
        // Sets `account` as the approved account to manage `id`.
            sstore(add(1, ownershipSlot), account)
        // Emit the {Approval} event.
            log4(0x00, 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id)
        }
    }

    /// @dev Approve or remove the `operator` as an operator for `by`,
    /// without authorization checks.
    ///
    /// Emits a {ApprovalForAll} event.
    function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
        // Clear the upper 96 bits.
            by := shr(96, shl(96, by))
            operator := shr(96, shl(96, operator))
        // Convert to 0 or 1.
            isApproved := iszero(iszero(isApproved))
        // Update the `isApproved` for (`by`, `operator`).
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))
            mstore(0x00, by)
            sstore(keccak256(0x0c, 0x30), isApproved)
        // Emit the {ApprovalForAll} event.
            mstore(0x00, isApproved)
            log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                INTERNAL TRANSFER FUNCTIONS                 */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Equivalent to `_transfer(address(0), from, to, id)`.
    function _transfer(address from, address to, uint256 id) internal virtual {
        _transfer(address(0), from, to, id);
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - If `by` is not the zero address,
    ///   it must be the owner of the token, or be approved to manage the token.
    ///
    /// Emits a {Transfer} event.
    function _transfer(address by, address from, address to, uint256 id) internal virtual {
        _beforeTokenTransfer(from, to, id);
        /// @solidity memory-safe-assembly
        assembly {
        // Clear the upper 96 bits.
            let bitmaskAddress := shr(96, not(0))
            from := and(bitmaskAddress, from)
            to := and(bitmaskAddress, to)
            by := and(bitmaskAddress, by)
        // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
            let owner := and(bitmaskAddress, ownershipPacked)
        // Revert if `from` is not the owner, or does not exist.
            if iszero(mul(owner, eq(owner, from))) {
                if iszero(owner) {
                    mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                    revert(0x1c, 0x04)
                }
                mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`.
                revert(0x1c, 0x04)
            }
        // Revert if `to` is the zero address.
            if iszero(to) {
                mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
                revert(0x1c, 0x04)
            }
        // Load, check, and update the token approval.
            {
                mstore(0x00, from)
                let approvedAddress := sload(add(1, ownershipSlot))
            // If `by` is not the zero address, do the authorization check.
            // Revert if the `by` is not the owner, nor approved.
                if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) {
                    if iszero(sload(keccak256(0x0c, 0x30))) {
                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                        revert(0x1c, 0x04)
                    }
                }
            // Delete the approved address if any.
                if approvedAddress { sstore(add(1, ownershipSlot), 0) }
            }
        // Update with the new owner.
            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
        // Decrement the balance of `from`.
            {
                let fromBalanceSlot := keccak256(0x0c, 0x1c)
                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
            }
        // Increment the balance of `to`.
            {
                mstore(0x00, to)
                let toBalanceSlot := keccak256(0x0c, 0x1c)
                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
                if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
                    mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
                    revert(0x1c, 0x04)
                }
                sstore(toBalanceSlot, toBalanceSlotPacked)
            }
        // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
        }
        _afterTokenTransfer(from, to, id);
    }

    /// @dev Equivalent to `_safeTransfer(from, to, id, "")`.
    function _safeTransfer(address from, address to, uint256 id) internal virtual {
        _safeTransfer(from, to, id, "");
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - The caller must be the owner of the token, or be approved to manage the token.
    /// - If `to` refers to a smart contract, it must implement
    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    ///
    /// Emits a {Transfer} event.
    function _safeTransfer(address from, address to, uint256 id, bytes memory data)
    internal
    virtual
    {
        _transfer(address(0), from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
    }

    /// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`.
    function _safeTransfer(address by, address from, address to, uint256 id) internal virtual {
        _safeTransfer(by, from, to, id, "");
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - If `by` is not the zero address,
    ///   it must be the owner of the token, or be approved to manage the token.
    /// - If `to` refers to a smart contract, it must implement
    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    ///
    /// Emits a {Transfer} event.
    function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data)
    internal
    virtual
    {
        _transfer(by, from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                    HOOKS FOR OVERRIDING                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Hook that is called before any token transfers, including minting and burning.
    function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {}

    /// @dev Hook that is called after any token transfers, including minting and burning.
    function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {}

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      PRIVATE HELPERS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns if `a` has bytecode of non-zero length.
    function _hasCode(address a) private view returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := extcodesize(a) // Can handle dirty upper bits.
        }
    }

    /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`.
    /// Reverts if the target does not support the function correctly.
    function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data)
    private
    {
        /// @solidity memory-safe-assembly
        assembly {
        // Prepare the calldata.
            let m := mload(0x40)
            let onERC721ReceivedSelector := 0x150b7a02
            mstore(m, onERC721ReceivedSelector)
            mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`.
            mstore(add(m, 0x40), shr(96, shl(96, from)))
            mstore(add(m, 0x60), id)
            mstore(add(m, 0x80), 0x80)
            let n := mload(data)
            mstore(add(m, 0xa0), n)
            if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) }
        // Revert if the call reverts.
            if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) {
                if returndatasize() {
                // Bubble up the revert if the call reverts.
                    returndatacopy(0x00, 0x00, returndatasize())
                    revert(0x00, returndatasize())
                }
                mstore(m, 0)
            }
        // Load the returndata and compare it.
            if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) {
                mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`.
                revert(0x1c, 0x04)
            }
        }
    }
}

// File: contracts/LibPRNG.sol

//
pragma solidity ^0.8.4;

/// @notice Library for generating psuedorandom numbers.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibPRNG.sol)
library LibPRNG {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STRUCTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev A psuedorandom number state in memory.
    struct PRNG {
        uint256 state;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         OPERATIONS                         */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Seeds the `prng` with `state`.
    function seed(PRNG memory prng, uint256 state) internal pure {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(prng, state)
        }
    }

    /// @dev Returns the next psuedorandom uint256.
    /// All bits of the returned uint256 pass the NIST Statistical Test Suite.
    function next(PRNG memory prng) internal pure returns (uint256 result) {
        // We simply use `keccak256` for a great balance between
        // runtime gas costs, bytecode size, and statistical properties.
        //
        // A high-quality LCG with a 32-byte state
        // is only about 30% more gas efficient during runtime,
        // but requires a 32-byte multiplier, which can cause bytecode bloat
        // when this function is inlined.
        //
        // Using this method is about 2x more efficient than
        // `nextRandomness = uint256(keccak256(abi.encode(randomness)))`.
        /// @solidity memory-safe-assembly
        assembly {
            result := keccak256(prng, 0x20)
            mstore(prng, result)
        }
    }

    /// @dev Returns a psuedorandom uint256, uniformly distributed
    /// between 0 (inclusive) and `upper` (exclusive).
    /// If your modulus is big, this method is recommended
    /// for uniform sampling to avoid modulo bias.
    /// For uniform sampling across all uint256 values,
    /// or for small enough moduli such that the bias is neligible,
    /// use {next} instead.
    function uniform(PRNG memory prng, uint256 upper) internal pure returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            for {} 1 {} {
                result := keccak256(prng, 0x20)
                mstore(prng, result)
                if iszero(lt(result, mod(sub(0, upper), upper))) { break }
            }
            result := mod(result, upper)
        }
    }

    /// @dev Shuffles the array in-place with Fisher-Yates shuffle.
    function shuffle(PRNG memory prng, uint256[] memory a) internal pure {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(a)
            let w := not(0)
            let mask := shr(128, w)
            if n {
                for { a := add(a, 0x20) } 1 {} {
                // We can just directly use `keccak256`, cuz
                // the other approaches don't save much.
                    let r := keccak256(prng, 0x20)
                    mstore(prng, r)

                // Note that there will be a very tiny modulo bias
                // if the length of the array is not a power of 2.
                // For all practical purposes, it is negligible
                // and will not be a fairness or security concern.
                    {
                        let j := add(a, shl(5, mod(shr(128, r), n)))
                        n := add(n, w) // `sub(n, 1)`.
                        if iszero(n) { break }

                        let i := add(a, shl(5, n))
                        let t := mload(i)
                        mstore(i, mload(j))
                        mstore(j, t)
                    }

                    {
                        let j := add(a, shl(5, mod(and(r, mask), n)))
                        n := add(n, w) // `sub(n, 1)`.
                        if iszero(n) { break }

                        let i := add(a, shl(5, n))
                        let t := mload(i)
                        mstore(i, mload(j))
                        mstore(j, t)
                    }
                }
            }
        }
    }

    /// @dev Shuffles the bytes in-place with Fisher-Yates shuffle.
    function shuffle(PRNG memory prng, bytes memory a) internal pure {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(a)
            let w := not(0)
            let mask := shr(128, w)
            if n {
                let b := add(a, 0x01)
                for { a := add(a, 0x20) } 1 {} {
                // We can just directly use `keccak256`, cuz
                // the other approaches don't save much.
                    let r := keccak256(prng, 0x20)
                    mstore(prng, r)

                // Note that there will be a very tiny modulo bias
                // if the length of the array is not a power of 2.
                // For all practical purposes, it is negligible
                // and will not be a fairness or security concern.
                    {
                        let o := mod(shr(128, r), n)
                        n := add(n, w) // `sub(n, 1)`.
                        if iszero(n) { break }

                        let t := mload(add(b, n))
                        mstore8(add(a, n), mload(add(b, o)))
                        mstore8(add(a, o), t)
                    }

                    {
                        let o := mod(and(r, mask), n)
                        n := add(n, w) // `sub(n, 1)`.
                        if iszero(n) { break }

                        let t := mload(add(b, n))
                        mstore8(add(a, n), mload(add(b, o)))
                        mstore8(add(a, o), t)
                    }
                }
            }
        }
    }
}

// File: contracts/LibString.sol

//
pragma solidity ^0.8.4;

/// @notice Library for converting numbers into strings and other string operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)
library LibString {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                        CUSTOM ERRORS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The `length` of the output is too small to contain all the hex digits.
    error HexLengthInsufficient();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The constant returned when the `search` is not found in the string.
    uint256 internal constant NOT_FOUND = type(uint256).max;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     DECIMAL OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the base 10 decimal representation of `value`.
    function toString(uint256 value) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        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.
            str := add(mload(0x40), 0x80)
        // Update the free memory pointer to allocate.
            mstore(0x40, add(str, 0x20))
        // Zeroize the slot after the string.
            mstore(str, 0)

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

            let w := not(0) // Tsk.
        // We write the string from rightmost digit to leftmost digit.
        // The following is essentially a do-while loop that also handles the zero case.
            for { let temp := value } 1 {} {
                str := add(str, w) // `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)
                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 Returns the base 10 decimal representation of `value`.
    function toString(int256 value) internal pure returns (string memory str) {
        if (value >= 0) {
            return toString(uint256(value));
        }
    unchecked {
        str = toString(uint256(-value));
    }
        /// @solidity memory-safe-assembly
        assembly {
        // We still have some spare memory space on the left,
        // as we have allocated 3 words (96 bytes) for up to 78 digits.
            let length := mload(str) // Load the string length.
            mstore(str, 0x2d) // Store the '-' character.
            str := sub(str, 1) // Move back the string pointer by a byte.
            mstore(str, add(length, 1)) // Update the string length.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   HEXADECIMAL OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the hexadecimal representation of `value`,
    /// left-padded to an input length of `length` bytes.
    /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
    /// giving a total length of `length * 2 + 2` bytes.
    /// Reverts if `length` is too small for the output to contain all the digits.
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value, length);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`,
    /// left-padded to an input length of `length` bytes.
    /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
    /// giving a total length of `length * 2` bytes.
    /// Reverts if `length` is too small for the output to contain all the digits.
    function toHexStringNoPrefix(uint256 value, uint256 length)
    internal
    pure
    returns (string memory str)
    {
        /// @solidity memory-safe-assembly
        assembly {
        // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes
        // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.
        // We add 0x20 to the total and round down to a multiple of 0x20.
        // (0x20 + 0x20 + 0x02 + 0x20) = 0x62.
            str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f)))
        // Allocate the memory.
            mstore(0x40, add(str, 0x20))
        // Zeroize the slot after the string.
            mstore(str, 0)

        // Cache the end to calculate the length later.
            let end := str
        // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let start := sub(str, add(length, length))
            let w := not(1) // Tsk.
            let temp := value
        // We write the string from rightmost digit to leftmost digit.
        // The following is essentially a do-while loop that also handles the zero case.
            for {} 1 {} {
                str := add(str, w) // `sub(str, 2)`.
                mstore8(add(str, 1), mload(and(temp, 15)))
                mstore8(str, mload(and(shr(4, temp), 15)))
                temp := shr(8, temp)
                if iszero(xor(str, start)) { break }
            }

            if temp {
            // Store the function selector of `HexLengthInsufficient()`.
                mstore(0x00, 0x2194895a)
            // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

        // Compute the string's length.
            let strLength := sub(end, str)
        // Move the pointer and write the length.
            str := sub(str, 0x20)
            mstore(str, strLength)
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
    /// As address are 20 bytes long, the output will left-padded to have
    /// a length of `20 * 2 + 2` bytes.
    function toHexString(uint256 value) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is encoded using 2 hexadecimal digits per byte.
    /// As address are 20 bytes long, the output will left-padded to have
    /// a length of `20 * 2` bytes.
    function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        assembly {
        // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
        // 0x02 bytes for the prefix, and 0x40 bytes for the digits.
        // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.
            str := add(mload(0x40), 0x80)
        // Allocate the memory.
            mstore(0x40, add(str, 0x20))
        // Zeroize the slot after the string.
            mstore(str, 0)

        // Cache the end to calculate the length later.
            let end := str
        // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let w := not(1) // Tsk.
        // We write the string from rightmost digit to leftmost digit.
        // The following is essentially a do-while loop that also handles the zero case.
            for { let temp := value } 1 {} {
                str := add(str, w) // `sub(str, 2)`.
                mstore8(add(str, 1), mload(and(temp, 15)))
                mstore8(str, mload(and(shr(4, temp), 15)))
                temp := shr(8, temp)
                if iszero(temp) { break }
            }

        // Compute the string's length.
            let strLength := sub(end, str)
        // Move the pointer and write the length.
            str := sub(str, 0x20)
            mstore(str, strLength)
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte,
    /// and the alphabets are capitalized conditionally according to
    /// https://eips.ethereum.org/EIPS/eip-55
    function toHexStringChecksummed(address value) internal pure returns (string memory str) {
        str = toHexString(value);
        /// @solidity memory-safe-assembly
        assembly {
            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`
            let o := add(str, 0x22)
            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `
            let t := shl(240, 136) // `0b10001000 << 240`
            for { let i := 0 } 1 {} {
                mstore(add(i, i), mul(t, byte(i, hashed)))
                i := add(i, 1)
                if eq(i, 20) { break }
            }
            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))
            o := add(o, 0x20)
            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
    function toHexString(address value) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is encoded using 2 hexadecimal digits per byte.
    function toHexStringNoPrefix(address value) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        assembly {
            str := mload(0x40)

        // Allocate the memory.
        // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
        // 0x02 bytes for the prefix, and 0x28 bytes for the digits.
        // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.
            mstore(0x40, add(str, 0x80))

        // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            str := add(str, 2)
            mstore(str, 40)

            let o := add(str, 0x20)
            mstore(add(o, 40), 0)

            value := shl(96, value)

        // We write the string from rightmost digit to leftmost digit.
        // The following is essentially a do-while loop that also handles the zero case.
            for { let i := 0 } 1 {} {
                let p := add(o, add(i, i))
                let temp := byte(i, value)
                mstore8(add(p, 1), mload(and(temp, 15)))
                mstore8(p, mload(shr(4, temp)))
                i := add(i, 1)
                if eq(i, 20) { break }
            }
        }
    }

    /// @dev Returns the hex encoded string from the raw bytes.
    /// The output is encoded using 2 hexadecimal digits per byte.
    function toHexString(bytes memory raw) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(raw);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hex encoded string from the raw bytes.
    /// The output is encoded using 2 hexadecimal digits per byte.
    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        assembly {
            let length := mload(raw)
            str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.
            mstore(str, add(length, length)) // Store the length of the output.

        // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let o := add(str, 0x20)
            let end := add(raw, length)

            for {} iszero(eq(raw, end)) {} {
                raw := add(raw, 1)
                mstore8(add(o, 1), mload(and(mload(raw), 15)))
                mstore8(o, mload(and(shr(4, mload(raw)), 15)))
                o := add(o, 2)
            }
            mstore(o, 0) // Zeroize the slot after the string.
            mstore(0x40, add(o, 0x20)) // Allocate the memory.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   RUNE STRING OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the number of UTF characters in the string.
    function runeCount(string memory s) internal pure returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            if mload(s) {
                mstore(0x00, div(not(0), 255))
                mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)
                let o := add(s, 0x20)
                let end := add(o, mload(s))
                for { result := 1 } 1 { result := add(result, 1) } {
                    o := add(o, byte(0, mload(shr(250, mload(o)))))
                    if iszero(lt(o, end)) { break }
                }
            }
        }
    }

    /// @dev Returns if this string is a 7-bit ASCII string.
    /// (i.e. all characters codes are in [0..127])
    function is7BitASCII(string memory s) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            let mask := shl(7, div(not(0), 255))
            result := 1
            let n := mload(s)
            if n {
                let o := add(s, 0x20)
                let end := add(o, n)
                let last := mload(end)
                mstore(end, 0)
                for {} 1 {} {
                    if and(mask, mload(o)) {
                        result := 0
                        break
                    }
                    o := add(o, 0x20)
                    if iszero(lt(o, end)) { break }
                }
                mstore(end, last)
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   BYTE STRING OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // For performance and bytecode compactness, all indices of the following operations
    // are byte (ASCII) offsets, not UTF character offsets.

    /// @dev Returns `subject` all occurrences of `search` replaced with `replacement`.
    function replace(string memory subject, string memory search, string memory replacement)
    internal
    pure
    returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            let searchLength := mload(search)
            let replacementLength := mload(replacement)

            subject := add(subject, 0x20)
            search := add(search, 0x20)
            replacement := add(replacement, 0x20)
            result := add(mload(0x40), 0x20)

            let subjectEnd := add(subject, subjectLength)
            if iszero(gt(searchLength, subjectLength)) {
                let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1)
                let h := 0
                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }
                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
                let s := mload(search)
                for {} 1 {} {
                    let t := mload(subject)
                // Whether the first `searchLength % 32` bytes of
                // `subject` and `search` matches.
                    if iszero(shr(m, xor(t, s))) {
                        if h {
                            if iszero(eq(keccak256(subject, searchLength), h)) {
                                mstore(result, t)
                                result := add(result, 1)
                                subject := add(subject, 1)
                                if iszero(lt(subject, subjectSearchEnd)) { break }
                                continue
                            }
                        }
                    // Copy the `replacement` one word at a time.
                        for { let o := 0 } 1 {} {
                            mstore(add(result, o), mload(add(replacement, o)))
                            o := add(o, 0x20)
                            if iszero(lt(o, replacementLength)) { break }
                        }
                        result := add(result, replacementLength)
                        subject := add(subject, searchLength)
                        if searchLength {
                            if iszero(lt(subject, subjectSearchEnd)) { break }
                            continue
                        }
                    }
                    mstore(result, t)
                    result := add(result, 1)
                    subject := add(subject, 1)
                    if iszero(lt(subject, subjectSearchEnd)) { break }
                }
            }

            let resultRemainder := result
            result := add(mload(0x40), 0x20)
            let k := add(sub(resultRemainder, result), sub(subjectEnd, subject))
        // Copy the rest of the string one word at a time.
            for {} lt(subject, subjectEnd) {} {
                mstore(resultRemainder, mload(subject))
                resultRemainder := add(resultRemainder, 0x20)
                subject := add(subject, 0x20)
            }
            result := sub(result, 0x20)
            let last := add(add(result, 0x20), k) // Zeroize the slot after the string.
            mstore(last, 0)
            mstore(0x40, add(last, 0x20)) // Allocate the memory.
            mstore(result, k) // Store the length.
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from left to right, starting from `from`.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function indexOf(string memory subject, string memory search, uint256 from)
    internal
    pure
    returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for { let subjectLength := mload(subject) } 1 {} {
                if iszero(mload(search)) {
                    if iszero(gt(from, subjectLength)) {
                        result := from
                        break
                    }
                    result := subjectLength
                    break
                }
                let searchLength := mload(search)
                let subjectStart := add(subject, 0x20)

                result := not(0) // Initialize to `NOT_FOUND`.

                subject := add(subjectStart, from)
                let end := add(sub(add(subjectStart, subjectLength), searchLength), 1)

                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
                let s := mload(add(search, 0x20))

                if iszero(and(lt(subject, end), lt(from, subjectLength))) { break }

                if iszero(lt(searchLength, 0x20)) {
                    for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
                        if iszero(shr(m, xor(mload(subject), s))) {
                            if eq(keccak256(subject, searchLength), h) {
                                result := sub(subject, subjectStart)
                                break
                            }
                        }
                        subject := add(subject, 1)
                        if iszero(lt(subject, end)) { break }
                    }
                    break
                }
                for {} 1 {} {
                    if iszero(shr(m, xor(mload(subject), s))) {
                        result := sub(subject, subjectStart)
                        break
                    }
                    subject := add(subject, 1)
                    if iszero(lt(subject, end)) { break }
                }
                break
            }
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from left to right.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function indexOf(string memory subject, string memory search)
    internal
    pure
    returns (uint256 result)
    {
        result = indexOf(subject, search, 0);
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from right to left, starting from `from`.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function lastIndexOf(string memory subject, string memory search, uint256 from)
    internal
    pure
    returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for {} 1 {} {
                result := not(0) // Initialize to `NOT_FOUND`.
                let searchLength := mload(search)
                if gt(searchLength, mload(subject)) { break }
                let w := result

                let fromMax := sub(mload(subject), searchLength)
                if iszero(gt(fromMax, from)) { from := fromMax }

                let end := add(add(subject, 0x20), w)
                subject := add(add(subject, 0x20), from)
                if iszero(gt(subject, end)) { break }
            // As this function is not too often used,
            // we shall simply use keccak256 for smaller bytecode size.
                for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
                    if eq(keccak256(subject, searchLength), h) {
                        result := sub(subject, add(end, 1))
                        break
                    }
                    subject := add(subject, w) // `sub(subject, 1)`.
                    if iszero(gt(subject, end)) { break }
                }
                break
            }
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from right to left.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function lastIndexOf(string memory subject, string memory search)
    internal
    pure
    returns (uint256 result)
    {
        result = lastIndexOf(subject, search, uint256(int256(-1)));
    }

    /// @dev Returns whether `subject` starts with `search`.
    function startsWith(string memory subject, string memory search)
    internal
    pure
    returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let searchLength := mload(search)
        // Just using keccak256 directly is actually cheaper.
        // forgefmt: disable-next-item
            result := and(
            iszero(gt(searchLength, mload(subject))),
            eq(
            keccak256(add(subject, 0x20), searchLength),
            keccak256(add(search, 0x20), searchLength)
            )
            )
        }
    }

    /// @dev Returns whether `subject` ends with `search`.
    function endsWith(string memory subject, string memory search)
    internal
    pure
    returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let searchLength := mload(search)
            let subjectLength := mload(subject)
        // Whether `search` is not longer than `subject`.
            let withinRange := iszero(gt(searchLength, subjectLength))
        // Just using keccak256 directly is actually cheaper.
        // forgefmt: disable-next-item
            result := and(
            withinRange,
            eq(
            keccak256(
            // `subject + 0x20 + max(subjectLength - searchLength, 0)`.
            add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))),
            searchLength
            ),
            keccak256(add(search, 0x20), searchLength)
            )
            )
        }
    }

    /// @dev Returns `subject` repeated `times`.
    function repeat(string memory subject, uint256 times)
    internal
    pure
    returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            if iszero(or(iszero(times), iszero(subjectLength))) {
                subject := add(subject, 0x20)
                result := mload(0x40)
                let output := add(result, 0x20)
                for {} 1 {} {
                // Copy the `subject` one word at a time.
                    for { let o := 0 } 1 {} {
                        mstore(add(output, o), mload(add(subject, o)))
                        o := add(o, 0x20)
                        if iszero(lt(o, subjectLength)) { break }
                    }
                    output := add(output, subjectLength)
                    times := sub(times, 1)
                    if iszero(times) { break }
                }
                mstore(output, 0) // Zeroize the slot after the string.
                let resultLength := sub(output, add(result, 0x20))
                mstore(result, resultLength) // Store the length.
            // Allocate the memory.
                mstore(0x40, add(result, add(resultLength, 0x20)))
            }
        }
    }

    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function slice(string memory subject, uint256 start, uint256 end)
    internal
    pure
    returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            if iszero(gt(subjectLength, end)) { end := subjectLength }
            if iszero(gt(subjectLength, start)) { start := subjectLength }
            if lt(start, end) {
                result := mload(0x40)
                let resultLength := sub(end, start)
                mstore(result, resultLength)
                subject := add(subject, start)
                let w := not(0x1f)
            // Copy the `subject` one word at a time, backwards.
                for { let o := and(add(resultLength, 0x1f), w) } 1 {} {
                    mstore(add(result, o), mload(add(subject, o)))
                    o := add(o, w) // `sub(o, 0x20)`.
                    if iszero(o) { break }
                }
            // Zeroize the slot after the string.
                mstore(add(add(result, 0x20), resultLength), 0)
            // Allocate memory for the length and the bytes,
            // rounded up to a multiple of 32.
                mstore(0x40, add(result, and(add(resultLength, 0x3f), w)))
            }
        }
    }

    /// @dev Returns a copy of `subject` sliced from `start` to the end of the string.
    /// `start` is a byte offset.
    function slice(string memory subject, uint256 start)
    internal
    pure
    returns (string memory result)
    {
        result = slice(subject, start, uint256(int256(-1)));
    }

    /// @dev Returns all the indices of `search` in `subject`.
    /// The indices are byte offsets.
    function indicesOf(string memory subject, string memory search)
    internal
    pure
    returns (uint256[] memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            let searchLength := mload(search)

            if iszero(gt(searchLength, subjectLength)) {
                subject := add(subject, 0x20)
                search := add(search, 0x20)
                result := add(mload(0x40), 0x20)

                let subjectStart := subject
                let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1)
                let h := 0
                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }
                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
                let s := mload(search)
                for {} 1 {} {
                    let t := mload(subject)
                // Whether the first `searchLength % 32` bytes of
                // `subject` and `search` matches.
                    if iszero(shr(m, xor(t, s))) {
                        if h {
                            if iszero(eq(keccak256(subject, searchLength), h)) {
                                subject := add(subject, 1)
                                if iszero(lt(subject, subjectSearchEnd)) { break }
                                continue
                            }
                        }
                    // Append to `result`.
                        mstore(result, sub(subject, subjectStart))
                        result := add(result, 0x20)
                    // Advance `subject` by `searchLength`.
                        subject := add(subject, searchLength)
                        if searchLength {
                            if iszero(lt(subject, subjectSearchEnd)) { break }
                            continue
                        }
                    }
                    subject := add(subject, 1)
                    if iszero(lt(subject, subjectSearchEnd)) { break }
                }
                let resultEnd := result
            // Assign `result` to the free memory pointer.
                result := mload(0x40)
            // Store the length of `result`.
                mstore(result, shr(5, sub(resultEnd, add(result, 0x20))))
            // Allocate memory for result.
            // We allocate one more word, so this array can be recycled for {split}.
                mstore(0x40, add(resultEnd, 0x20))
            }
        }
    }

    /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string.
    function split(string memory subject, string memory delimiter)
    internal
    pure
    returns (string[] memory result)
    {
        uint256[] memory indices = indicesOf(subject, delimiter);
        /// @solidity memory-safe-assembly
        assembly {
            let w := not(0x1f)
            let indexPtr := add(indices, 0x20)
            let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))
            mstore(add(indicesEnd, w), mload(subject))
            mstore(indices, add(mload(indices), 1))
            let prevIndex := 0
            for {} 1 {} {
                let index := mload(indexPtr)
                mstore(indexPtr, 0x60)
                if iszero(eq(index, prevIndex)) {
                    let element := mload(0x40)
                    let elementLength := sub(index, prevIndex)
                    mstore(element, elementLength)
                // Copy the `subject` one word at a time, backwards.
                    for { let o := and(add(elementLength, 0x1f), w) } 1 {} {
                        mstore(add(element, o), mload(add(add(subject, prevIndex), o)))
                        o := add(o, w) // `sub(o, 0x20)`.
                        if iszero(o) { break }
                    }
                // Zeroize the slot after the string.
                    mstore(add(add(element, 0x20), elementLength), 0)
                // Allocate memory for the length and the bytes,
                // rounded up to a multiple of 32.
                    mstore(0x40, add(element, and(add(elementLength, 0x3f), w)))
                // Store the `element` into the array.
                    mstore(indexPtr, element)
                }
                prevIndex := add(index, mload(delimiter))
                indexPtr := add(indexPtr, 0x20)
                if iszero(lt(indexPtr, indicesEnd)) { break }
            }
            result := indices
            if iszero(mload(delimiter)) {
                result := add(indices, 0x20)
                mstore(result, sub(mload(indices), 2))
            }
        }
    }

    /// @dev Returns a concatenated string of `a` and `b`.
    /// Cheaper than `string.concat()` and does not de-align the free memory pointer.
    function concat(string memory a, string memory b)
    internal
    pure
    returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let w := not(0x1f)
            result := mload(0x40)
            let aLength := mload(a)
        // Copy `a` one word at a time, backwards.
            for { let o := and(add(mload(a), 0x20), w) } 1 {} {
                mstore(add(result, o), mload(add(a, o)))
                o := add(o, w) // `sub(o, 0x20)`.
                if iszero(o) { break }
            }
            let bLength := mload(b)
            let output := add(result, mload(a))
        // Copy `b` one word at a time, backwards.
            for { let o := and(add(bLength, 0x20), w) } 1 {} {
                mstore(add(output, o), mload(add(b, o)))
                o := add(o, w) // `sub(o, 0x20)`.
                if iszero(o) { break }
            }
            let totalLength := add(aLength, bLength)
            let last := add(add(result, 0x20), totalLength)
        // Zeroize the slot after the string.
            mstore(last, 0)
        // Stores the length.
            mstore(result, totalLength)
        // Allocate memory for the length and the bytes,
        // rounded up to a multiple of 32.
            mstore(0x40, and(add(last, 0x1f), w))
        }
    }

    /// @dev Returns a copy of the string in either lowercase or UPPERCASE.
    /// WARNING! This function is only compatible with 7-bit ASCII strings.
    function toCase(string memory subject, bool toUpper)
    internal
    pure
    returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let length := mload(subject)
            if length {
                result := add(mload(0x40), 0x20)
                subject := add(subject, 1)
                let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)
                let w := not(0)
                for { let o := length } 1 {} {
                    o := add(o, w)
                    let b := and(0xff, mload(add(subject, o)))
                    mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20)))
                    if iszero(o) { break }
                }
                result := mload(0x40)
                mstore(result, length) // Store the length.
                let last := add(add(result, 0x20), length)
                mstore(last, 0) // Zeroize the slot after the string.
                mstore(0x40, add(last, 0x20)) // Allocate the memory.
            }
        }
    }

    /// @dev Returns a lowercased copy of the string.
    /// WARNING! This function is only compatible with 7-bit ASCII strings.
    function lower(string memory subject) internal pure returns (string memory result) {
        result = toCase(subject, false);
    }

    /// @dev Returns an UPPERCASED copy of the string.
    /// WARNING! This function is only compatible with 7-bit ASCII strings.
    function upper(string memory subject) internal pure returns (string memory result) {
        result = toCase(subject, true);
    }

    /// @dev Escapes the string to be used within HTML tags.
    function escapeHTML(string memory s) internal pure returns (string memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            for {
                let end := add(s, mload(s))
                result := add(mload(0x40), 0x20)
            // Store the bytes of the packed offsets and strides into the scratch space.
            // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6.
                mstore(0x1f, 0x900094)
                mstore(0x08, 0xc0000000a6ab)
            // Store "&quot;&amp;&#39;&lt;&gt;" into the scratch space.
                mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))
            } iszero(eq(s, end)) {} {
                s := add(s, 1)
                let c := and(mload(s), 0xff)
            // Not in `["\"","'","&","<",">"]`.
                if iszero(and(shl(c, 1), 0x500000c400000000)) {
                    mstore8(result, c)
                    result := add(result, 1)
                    continue
                }
                let t := shr(248, mload(c))
                mstore(result, mload(and(t, 0x1f)))
                result := add(result, shr(5, t))
            }
            let last := result
            mstore(last, 0) // Zeroize the slot after the string.
            result := mload(0x40)
            mstore(result, sub(last, add(result, 0x20))) // Store the length.
            mstore(0x40, add(last, 0x20)) // Allocate the memory.
        }
    }

    /// @dev Escapes the string to be used within double-quotes in a JSON.
    function escapeJSON(string memory s) internal pure returns (string memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            for {
                let end := add(s, mload(s))
                result := add(mload(0x40), 0x20)
            // Store "\\u0000" in scratch space.
            // Store "0123456789abcdef" in scratch space.
            // Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`.
            // into the scratch space.
                mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)
            // Bitmask for detecting `["\"","\\"]`.
                let e := or(shl(0x22, 1), shl(0x5c, 1))
            } iszero(eq(s, end)) {} {
                s := add(s, 1)
                let c := and(mload(s), 0xff)
                if iszero(lt(c, 0x20)) {
                    if iszero(and(shl(c, 1), e)) {
                    // Not in `["\"","\\"]`.
                        mstore8(result, c)
                        result := add(result, 1)
                        continue
                    }
                    mstore8(result, 0x5c) // "\\".
                    mstore8(add(result, 1), c)
                    result := add(result, 2)
                    continue
                }
                if iszero(and(shl(c, 1), 0x3700)) {
                // Not in `["\b","\t","\n","\f","\d"]`.
                    mstore8(0x1d, mload(shr(4, c))) // Hex value.
                    mstore8(0x1e, mload(and(c, 15))) // Hex value.
                    mstore(result, mload(0x19)) // "\\u00XX".
                    result := add(result, 6)
                    continue
                }
                mstore8(result, 0x5c) // "\\".
                mstore8(add(result, 1), mload(add(c, 8)))
                result := add(result, 2)
            }
            let last := result
            mstore(last, 0) // Zeroize the slot after the string.
            result := mload(0x40)
            mstore(result, sub(last, add(result, 0x20))) // Store the length.
            mstore(0x40, add(last, 0x20)) // Allocate the memory.
        }
    }

    /// @dev Returns whether `a` equals `b`.
    function eq(string memory a, string memory b) internal pure returns (bool result) {
        assembly {
            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))
        }
    }

    /// @dev Packs a single string with its length into a single word.
    /// Returns `bytes32(0)` if the length is zero or greater than 31.
    function packOne(string memory a) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
        // We don't need to zero right pad the string,
        // since this is our own custom non-standard packing scheme.
            result :=
            mul(
            // Load the length and the bytes.
            mload(add(a, 0x1f)),
            // `length != 0 && length < 32`. Abuses underflow.
            // Assumes that the length is valid and within the block gas limit.
            lt(sub(mload(a), 1), 0x1f)
            )
        }
    }

    /// @dev Unpacks a string packed using {packOne}.
    /// Returns the empty string if `packed` is `bytes32(0)`.
    /// If `packed` is not an output of {packOne}, the output behaviour is undefined.
    function unpackOne(bytes32 packed) internal pure returns (string memory result) {
        /// @solidity memory-safe-assembly
        assembly {
        // Grab the free memory pointer.
            result := mload(0x40)
        // Allocate 2 words (1 for the length, 1 for the bytes).
            mstore(0x40, add(result, 0x40))
        // Zeroize the length slot.
            mstore(result, 0)
        // Store the length and bytes.
            mstore(add(result, 0x1f), packed)
        // Right pad with zeroes.
            mstore(add(add(result, 0x20), mload(result)), 0)
        }
    }

    /// @dev Packs two strings with their lengths into a single word.
    /// Returns `bytes32(0)` if combined length is zero or greater than 30.
    function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let aLength := mload(a)
        // We don't need to zero right pad the strings,
        // since this is our own custom non-standard packing scheme.
            result :=
            mul(
            // Load the length and the bytes of `a` and `b`.
            or(
            shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))),
            mload(sub(add(b, 0x1e), aLength))
            ),
            // `totalLength != 0 && totalLength < 31`. Abuses underflow.
            // Assumes that the lengths are valid and within the block gas limit.
            lt(sub(add(aLength, mload(b)), 1), 0x1e)
            )
        }
    }

    /// @dev Unpacks strings packed using {packTwo}.
    /// Returns the empty strings if `packed` is `bytes32(0)`.
    /// If `packed` is not an output of {packTwo}, the output behaviour is undefined.
    function unpackTwo(bytes32 packed)
    internal
    pure
    returns (string memory resultA, string memory resultB)
    {
        /// @solidity memory-safe-assembly
        assembly {
        // Grab the free memory pointer.
            resultA := mload(0x40)
            resultB := add(resultA, 0x40)
        // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.
            mstore(0x40, add(resultB, 0x40))
        // Zeroize the length slots.
            mstore(resultA, 0)
            mstore(resultB, 0)
        // Store the lengths and bytes.
            mstore(add(resultA, 0x1f), packed)
            mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))
        // Right pad with zeroes.
            mstore(add(add(resultA, 0x20), mload(resultA)), 0)
            mstore(add(add(resultB, 0x20), mload(resultB)), 0)
        }
    }

    /// @dev Directly returns `a` without copying.
    function directReturn(string memory a) internal pure {
        assembly {
        // Assumes that the string does not start from the scratch space.
            let retStart := sub(a, 0x20)
            let retSize := add(mload(a), 0x40)
        // Right pad with zeroes. Just in case the string is produced
        // by a method that doesn't zero right pad.
            mstore(add(retStart, retSize), 0)
        // Store the return offset.
            mstore(retStart, 0x20)
        // End the transaction, returning the string.
            return(retStart, retSize)
        }
    }
}

// File: contracts/ERC721r.sol

//
pragma solidity ^0.8.17;

//import "@openzeppelin/contracts/token/ERC721/ERC721.sol";



//import {ERC721} from "solady/src/tokens/ERC721.sol";
//import {LibPRNG} from "solady/src/utils/LibPRNG.sol";
//import {LibString} from "solady/src/utils/LibString.sol";


abstract contract ERC721r is ERC721 {
    using LibPRNG for LibPRNG.PRNG;
    using LibString for uint256;

    error ContractsCannotMint();
    error MustMintAtLeastOneToken();
    error NotEnoughAvailableTokens();

    string private _name;
    string private _symbol;

    mapping(uint256 => uint256) private _availableTokens;
    uint256 public remainingSupply;

    uint256 public immutable maxSupply;

    constructor(string memory name_, string memory symbol_, uint256 maxSupply_) {
        _name = name_;
        _symbol = symbol_;
        maxSupply = maxSupply_;
        remainingSupply = maxSupply_;
    }

    function totalSupply() public view virtual returns (uint256) {
        return maxSupply - remainingSupply;
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    function numberMinted(address minter) public view virtual returns (uint32) {
        return uint32(ERC721._getAux(minter) >> 192);
    }

    function _mintRandom(address to, uint256 _numToMint) internal virtual {
        if (msg.sender != tx.origin) revert ContractsCannotMint();
        if (_numToMint == 0) revert MustMintAtLeastOneToken();
        if (remainingSupply < _numToMint) revert NotEnoughAvailableTokens();

        LibPRNG.PRNG memory prng = LibPRNG.PRNG(uint256(keccak256(abi.encodePacked(
            block.timestamp, block.prevrandao
        ))));

        uint256 updatedRemainingSupply = remainingSupply;

        for (uint256 i; i < _numToMint; ) {
            uint256 randomIndex = prng.uniform(updatedRemainingSupply);

            uint256 tokenId = getAvailableTokenAtIndex(randomIndex, updatedRemainingSupply);

            _mint(to, tokenId);

            --updatedRemainingSupply;

        unchecked {++i;}
        }

        _incrementAmountMinted(to, uint32(_numToMint));
        remainingSupply = updatedRemainingSupply;
    }

    // Must be called in descending order of index
    function _mintAtIndex(address to, uint256 index) internal virtual {
        if (msg.sender != tx.origin) revert ContractsCannotMint();
        if (remainingSupply == 0) revert NotEnoughAvailableTokens();

        uint256 tokenId = getAvailableTokenAtIndex(index, remainingSupply);

        --remainingSupply;
        _incrementAmountMinted(to, 1);

        _mint(to, tokenId);
    }

    // Implements https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. Code taken from CryptoPhunksV2
    function getAvailableTokenAtIndex(uint256 indexToUse, uint256 updatedNumAvailableTokens)
    private
    returns (uint256 result)
    {
        uint256 valAtIndex = _availableTokens[indexToUse];
        uint256 lastIndex = updatedNumAvailableTokens - 1;
        uint256 lastValInArray = _availableTokens[lastIndex];

        result = valAtIndex == 0 ? indexToUse : valAtIndex;

        if (indexToUse != lastIndex) {
            _availableTokens[indexToUse] = lastValInArray == 0 ? lastIndex : lastValInArray;
        }

        if (lastValInArray != 0) {
            delete _availableTokens[lastIndex];
        }
    }

    function _setExtraAddressData(address minter, uint192 extraData) internal virtual {
        uint32 numMinted = numberMinted(minter);

        ERC721._setAux(
            minter,
            uint224((uint256(numMinted) << 192)) | uint224(extraData)
        );
    }

    function _getAddressExtraData(address minter) internal view virtual returns (uint192) {
        return uint192(_getAux(minter));
    }

    function _incrementAmountMinted(address minter, uint32 newMints) private {
        uint32 numMinted = numberMinted(minter);
        uint32 newMintNumMinted = numMinted + uint32(newMints);
        uint224 auxData = ERC721._getAux(minter);

        ERC721._setAux(
            minter,
            uint224(uint256(newMintNumMinted) << 192) | uint224(uint192(auxData))
        );
    }
}

// File: contracts/MetaLifeVehicle.sol

//
pragma solidity 0.8.23;




contract MetaLifeVehicle is ReentrancyGuard, Ownable, ERC721r {

    using Strings for uint256;
    string public baseURI;
    uint16 public mainMaxSupply = 1200;

    uint16 public nbMintedCouncil = 0;
    uint16 public nbMintedHonorary = 0;
    uint16 public nbMintedGuardian = 0;
    uint16 public nbMintedJudge = 0;
    uint16 public nbMintedWhale = 0;

    uint16 public maxSupplyCouncil = 250;
    uint16 public maxSupplyHonorary = 66;
    uint16 public maxSupplyGuardian = 22;
    uint16 public maxSupplyJudge = 10;
    uint16 public maxSupplyWhale = 31;

    // Fri May 31 2024 21:59:59 GMT+0000
    uint256 public limitSpecialMint = 1717192799;
    address public originOwner = 0x87a1AB9Aab7BAE43AD4ce4951A93e7F5bBCAc230;
    address payable public collector;

    struct Eligibility {
        uint8 total;
        uint8 claimed;
    }

    mapping(address => Eligibility) public allowlistRandom;
    event MintedRandom(address indexed from, uint256 timestamp);

    uint16 private _tokenIdCurrentCouncil = 822;
    mapping(address => Eligibility) public allowlistCouncil;
    event MintedCouncil(address indexed from, uint256 timestamp, uint16[] tokenIds);

    uint16 private _tokenIdCurrentHonorary = 1072;
    mapping(address => Eligibility) public allowlistHonorary;
    event MintedHonorary(address indexed from, uint256 timestamp, uint16[] tokenIds);

    uint16 private _tokenIdCurrentGuardian = 1138;
    mapping(address => Eligibility) public allowlistGuardian;
    event MintedGuardian(address indexed from, uint256 timestamp, uint16 tokenId);

    uint16 private _tokenIdCurrentJudge = 1160;
    mapping(address => Eligibility) public allowlistJudge;
    event MintedJudge(address indexed from, uint256 timestamp, uint16 tokenId);

    uint16 private _tokenIdCurrentWhale = 1170;
    mapping(address => Eligibility) public allowlistWhale;
    event MintedWhale(address indexed from, uint256 timestamp, uint16[] tokenIds);

    constructor() ERC721r('Meta-Life Vehicle', 'MLV', 8_20) Ownable(originOwner){}

    function withdrawAll() public payable onlyOwner {
        collector.transfer(address(this).balance);
    }

    function setCollector(address payable _newCollector) public onlyOwner {
        collector = _newCollector;
    }

    function _setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }

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

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), 'unknow token');
        string memory uri = _baseURI();
        return bytes(uri).length > 0 ? string(abi.encodePacked(uri, tokenId.toString())) : "";
    }

    function tokenExist(uint256 tokenId) public view returns(bool) {
        return _exists(tokenId);
    }

    function mainTotalSupply() public view returns (uint256){
        return totalSupply() + nbMintedCouncil + nbMintedHonorary + nbMintedGuardian + nbMintedJudge + nbMintedWhale;
    }

    function remainingRandom(address wallet) public view virtual returns (uint8) {
        return allowlistRandom[wallet].total - allowlistRandom[wallet].claimed;
    }

    function remainingCouncil(address wallet) public view virtual returns (uint8) {
        return allowlistCouncil[wallet].total - allowlistCouncil[wallet].claimed;
    }

    function remainingHonorary(address wallet) public view virtual returns (uint8) {
        return allowlistHonorary[wallet].total - allowlistHonorary[wallet].claimed;
    }

    function remainingWhale(address wallet) public view virtual returns (uint8) {
        return allowlistWhale[wallet].total - allowlistWhale[wallet].claimed;
    }

    function remainingJudge(address wallet) public view virtual returns (uint8) {
        return allowlistJudge[wallet].total - allowlistJudge[wallet].claimed;
    }

    function remainingGuardian(address wallet) public view virtual returns (uint8) {
        return allowlistGuardian[wallet].total - allowlistGuardian[wallet].claimed;
    }

    function addAllowlistRandom(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner {
        require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal');
        for (uint i = 0; i < _toAddAddresses.length; i++) {
            allowlistRandom[_toAddAddresses[i]].total += _quantities[i];
        }
    }

    function mintRandom(uint8 _quantities) external {
        require(remainingRandom(msg.sender) > 0, "Not eligible");
        require(remainingRandom(msg.sender) >= _quantities, "Not enough claimable tokens");
        require(maxSupply >= totalSupply() + _quantities, "Supply limit exceed");
        allowlistRandom[msg.sender].claimed += _quantities;
        _mintRandom(msg.sender, _quantities);
        emit MintedRandom(msg.sender, block.timestamp);
    }

    function addAllowlistCouncil(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner {
        require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal');
        for (uint i = 0; i < _toAddAddresses.length; i++) {
            allowlistCouncil[_toAddAddresses[i]].total = _quantities[i];
        }
    }

    function mintCouncil(uint8 _quantities) external {
        require(block.timestamp < limitSpecialMint, "Council mint close");
        require(remainingCouncil(msg.sender) > 0, "Not eligible");
        require(remainingCouncil(msg.sender) >= _quantities, "Not enough claimable tokens");
        require(nbMintedCouncil + _quantities <= maxSupplyCouncil, "Max supply council exceed");
        uint16[] memory _tokenIdsMinted = new uint16[](_quantities);
        allowlistCouncil[msg.sender].claimed += _quantities;
        for (uint8 i = 0; i < _quantities; i++) {
            _safeMint(msg.sender, _tokenIdCurrentCouncil);
            _tokenIdsMinted[i] = _tokenIdCurrentCouncil;
            _tokenIdCurrentCouncil++;
            nbMintedCouncil++;
        }
        emit MintedCouncil(msg.sender, block.timestamp, _tokenIdsMinted);
    }

    function addAllowlistHonorary(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner {
        require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal');
        for (uint i = 0; i < _toAddAddresses.length; i++) {
            allowlistHonorary[_toAddAddresses[i]].total = _quantities[i];
        }
    }

    function mintHonorary(uint8 _quantities) external {
        require(block.timestamp < limitSpecialMint, "Honorary mint close");
        require(remainingHonorary(msg.sender) > 0, "Not eligible");
        require(remainingHonorary(msg.sender) >= _quantities, "Not enough claimable tokens");
        require(nbMintedHonorary + _quantities <= maxSupplyHonorary, "Max supply honorary exceed");
        uint16[] memory _tokenIdsMinted = new uint16[](_quantities);
        allowlistHonorary[msg.sender].claimed += _quantities;
        for (uint8 i = 0; i < _quantities; i++) {
            _safeMint(msg.sender, _tokenIdCurrentHonorary);
            _tokenIdsMinted[i] = _tokenIdCurrentHonorary;
            _tokenIdCurrentHonorary++;
            nbMintedHonorary++;
        }
        emit MintedHonorary(msg.sender, block.timestamp, _tokenIdsMinted);
    }

    function addAllowlistGuardian(address[] calldata _toAddAddresses) external onlyOwner {
        for (uint i = 0; i < _toAddAddresses.length; i++) {
            allowlistGuardian[_toAddAddresses[i]].total = 1;
        }
    }

    function mintGuardian() external {
        require(block.timestamp < limitSpecialMint, "Guardian mint close");
        require(remainingGuardian(msg.sender) > 0, "No giveway");
        require(nbMintedGuardian + 1 <= maxSupplyGuardian, "Max supply guardian exceed");
        allowlistGuardian[msg.sender].claimed = 1;
        _safeMint(msg.sender, _tokenIdCurrentGuardian);
        emit MintedGuardian(msg.sender, block.timestamp, _tokenIdCurrentGuardian);
        _tokenIdCurrentGuardian++;
        nbMintedGuardian++;
    }

    function addAllowlistJudge(address[] calldata _toAddAddresses) external onlyOwner {
        for (uint i = 0; i < _toAddAddresses.length; i++) {
            allowlistJudge[_toAddAddresses[i]].total = 1;
        }
    }

    function mintJudge() external {
        require(block.timestamp < limitSpecialMint, "Judge mint close");
        require(remainingJudge(msg.sender) > 0, "Not eligible");
        require(nbMintedJudge + 1 <= maxSupplyJudge, "Max supply judge exceed");
        allowlistJudge[msg.sender].claimed = 1;
        _safeMint(msg.sender, _tokenIdCurrentJudge);
        emit MintedJudge(msg.sender, block.timestamp, _tokenIdCurrentJudge);
        _tokenIdCurrentJudge++;
        nbMintedJudge++;
    }

    function addAllowlistWhale(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner {
        for (uint i = 0; i < _toAddAddresses.length; i++) {
            allowlistWhale[_toAddAddresses[i]].total = _quantities[i];
        }
    }

    function mintWhale(uint8 _quantities) external {
        require(block.timestamp < limitSpecialMint, "Whale mint close");
        require(remainingWhale(msg.sender) > 0, "Not eligible");
        require(remainingWhale(msg.sender) >= _quantities, "Not enough claimable tokens");
        require(nbMintedWhale + _quantities <= maxSupplyCouncil, "Max supply whale exceed");
        uint16[] memory _tokenIdsMinted = new uint16[](_quantities);
        allowlistWhale[msg.sender].claimed += _quantities;
        for (uint8 i = 0; i < _quantities; i++) {
            _safeMint(msg.sender, _tokenIdCurrentWhale);
            _tokenIdsMinted[i] = _tokenIdCurrentWhale;
            _tokenIdCurrentWhale++;
            nbMintedWhale++;
        }
        emit MintedWhale(msg.sender, block.timestamp, _tokenIdsMinted);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"ContractsCannotMint","type":"error"},{"inputs":[],"name":"MustMintAtLeastOneToken","type":"error"},{"inputs":[],"name":"NotEnoughAvailableTokens","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","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":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","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":"isApproved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"}],"name":"MintedCouncil","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"}],"name":"MintedGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"}],"name":"MintedHonorary","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"}],"name":"MintedJudge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MintedRandom","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"}],"name":"MintedWhale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"_setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAllowlistGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistHonorary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAllowlistJudge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistCouncil","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistGuardian","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistHonorary","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistJudge","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistRandom","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistWhale","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collector","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","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":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitSpecialMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainMaxSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyCouncil","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyGuardian","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyHonorary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyJudge","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyWhale","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintHonorary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintJudge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedCouncil","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedGuardian","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedHonorary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedJudge","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedWhale","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"originOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingCouncil","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingGuardian","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingHonorary","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingJudge","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingRandom","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remainingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingWhale","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","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":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newCollector","type":"address"}],"name":"setCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","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":"tokenExist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","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":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]

60a06040526104b060075f6101000a81548161ffff021916908361ffff1602179055505f600760026101000a81548161ffff021916908361ffff1602179055505f600760046101000a81548161ffff021916908361ffff1602179055505f600760066101000a81548161ffff021916908361ffff1602179055505f600760086101000a81548161ffff021916908361ffff1602179055505f6007600a6101000a81548161ffff021916908361ffff16021790555060fa6007600c6101000a81548161ffff021916908361ffff16021790555060426007600e6101000a81548161ffff021916908361ffff1602179055506016600760106101000a81548161ffff021916908361ffff160217905550600a600760126101000a81548161ffff021916908361ffff160217905550601f600760146101000a81548161ffff021916908361ffff16021790555063665a485f6008557387a1ab9aab7bae43ad4ce4951a93e7f5bbcac23060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610336600c5f6101000a81548161ffff021916908361ffff160217905550610430600e5f6101000a81548161ffff021916908361ffff16021790555061047260105f6101000a81548161ffff021916908361ffff16021790555061048860125f6101000a81548161ffff021916908361ffff16021790555061049260145f6101000a81548161ffff021916908361ffff16021790555034801562000247575f80fd5b506040518060400160405280601181526020017f4d6574612d4c6966652056656869636c650000000000000000000000000000008152506040518060400160405280600381526020017f4d4c56000000000000000000000000000000000000000000000000000000000081525061033460095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660015f819055505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000353575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016200034a9190620004a7565b60405180910390fd5b6200036481620003a160201b60201c565b50826002908162000376919062000726565b50816003908162000388919062000726565b508060808181525050806005819055505050506200080a565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200048f8262000464565b9050919050565b620004a18162000483565b82525050565b5f602082019050620004bc5f83018462000496565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200053e57607f821691505b602082108103620005545762000553620004f9565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620005b87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200057b565b620005c486836200057b565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200060e620006086200060284620005dc565b620005e5565b620005dc565b9050919050565b5f819050919050565b6200062983620005ee565b62000641620006388262000615565b84845462000587565b825550505050565b5f90565b6200065762000649565b620006648184846200061e565b505050565b5b818110156200068b576200067f5f826200064d565b6001810190506200066a565b5050565b601f821115620006da57620006a4816200055a565b620006af846200056c565b81016020851015620006bf578190505b620006d7620006ce856200056c565b83018262000669565b50505b505050565b5f82821c905092915050565b5f620006fc5f1984600802620006df565b1980831691505092915050565b5f620007168383620006eb565b9150826002028217905092915050565b6200073182620004c2565b67ffffffffffffffff8111156200074d576200074c620004cc565b5b62000759825462000526565b620007668282856200068f565b5f60209050601f8311600181146200079c575f841562000787578287015190505b62000793858262000709565b86555062000802565b601f198416620007ac866200055a565b5f5b82811015620007d557848901518255600182019150602085019450602081019050620007ae565b86831015620007f55784890151620007f1601f891682620006eb565b8355505b6001600288020188555050505b505050505050565b6080516154d2620008315f395f8181611419015281816116b0015261316e01526154d25ff3fe6080604052600436106103c2575f3560e01c80637a12ef82116101f1578063b88d4fde1161010c578063dc33e6811161009f578063ea3d74181161006e578063ea3d741814610e60578063f2fde38b14610e8a578063fb5b82d014610eb2578063fc89067914610eda576103c2565b8063dc33e68114610d6e578063dd330e4d14610daa578063df1dc2c514610de7578063e985e9c514610e24576103c2565b8063cc0c5236116100db578063cc0c523614610cb6578063d5abeb0114610cf2578063da0239a614610d1c578063dab00abb14610d46576103c2565b8063b88d4fde14610c0e578063b904e37a14610c2a578063bc68ed6c14610c52578063c87b56dd14610c7a576103c2565b8063916ec2c611610184578063a22cb46511610153578063a22cb46514610b6c578063a2cd568914610b94578063ac497a4814610bbe578063b55698d514610be6576103c2565b8063916ec2c614610ac657806391ec4b4c14610af057806395d89b4114610b1a5780639a3e276814610b44576103c2565b8063889960ea116101c0578063889960ea14610a0c5780638b4303a614610a485780638da5cb5b14610a72578063913e77ad14610a9c576103c2565b80637a12ef82146109885780637ca470b1146109b0578063853828b6146109da57806385ad1cf5146109e4576103c2565b80632ff1474d116102e157806352186417116102745780636c0360eb116102435780636c0360eb146108e457806370a082311461090e578063715018a61461094a5780637400c92214610960576103c2565b806352186417146108055780635d42a059146108415780636352211e1461087e5780636802e529146108ba576103c2565b8063376e1b1f116102b0578063376e1b1f1461076d57806342842e0e1461078357806346fbed6f1461079f5780634e27acff146107c9576103c2565b80632ff1474d146106a257806331b5b907146106de57806333a3600714610706578063343bc89314610730576103c2565b8063106e707b1161035957806323b872dd1161032857806323b872dd146105f757806326d6327914610613578063282e7811146106505780632db5b8e71461067a576103c2565b8063106e707b1461053d57806318160ddd146105795780631bf3dd4f146105a35780631d490ee3146105cd576103c2565b806306fdde031161039557806306fdde031461049157806307edf9ef146104bb578063081812fc146104e5578063095ea7b314610521576103c2565b80630129b0b9146103c657806301ffc9a714610403578063022c01991461043f5780630322ba9814610455575b5f80fd5b3480156103d1575f80fd5b506103ec60048036038101906103e79190613e8d565b610f04565b6040516103fa929190613ed3565b60405180910390f35b34801561040e575f80fd5b5061042960048036038101906104249190613f4f565b610f3c565b6040516104369190613f94565b60405180910390f35b34801561044a575f80fd5b50610453610f60565b005b348015610460575f80fd5b5061047b60048036038101906104769190613e8d565b6111b4565b6040516104889190613fad565b60405180910390f35b34801561049c575f80fd5b506104a561125f565b6040516104b29190614050565b60405180910390f35b3480156104c6575f80fd5b506104cf6112ef565b6040516104dc919061408c565b60405180910390f35b3480156104f0575f80fd5b5061050b600480360381019061050691906140d8565b611303565b6040516105189190614112565b60405180910390f35b61053b6004803603810190610536919061412b565b611359565b005b348015610548575f80fd5b50610563600480360381019061055e9190613e8d565b611368565b6040516105709190613fad565b60405180910390f35b348015610584575f80fd5b5061058d611413565b60405161059a9190614178565b60405180910390f35b3480156105ae575f80fd5b506105b7611447565b6040516105c49190614178565b60405180910390f35b3480156105d8575f80fd5b506105e161144d565b6040516105ee919061408c565b60405180910390f35b610611600480360381019061060c9190614191565b611461565b005b34801561061e575f80fd5b5061063960048036038101906106349190613e8d565b61159d565b604051610647929190613ed3565b60405180910390f35b34801561065b575f80fd5b506106646115d5565b6040516106719190614112565b60405180910390f35b348015610685575f80fd5b506106a0600480360381019061069b919061420b565b6115fa565b005b3480156106ad575f80fd5b506106c860048036038101906106c39190613e8d565b6117e1565b6040516106d59190613fad565b60405180910390f35b3480156106e9575f80fd5b5061070460048036038101906106ff9190614362565b61188c565b005b348015610711575f80fd5b5061071a6118a7565b6040516107279190614178565b60405180910390f35b34801561073b575f80fd5b5061075660048036038101906107519190613e8d565b611950565b604051610764929190613ed3565b60405180910390f35b348015610778575f80fd5b50610781611988565b005b61079d60048036038101906107989190614191565b611bdc565b005b3480156107aa575f80fd5b506107b3611c15565b6040516107c0919061408c565b60405180910390f35b3480156107d4575f80fd5b506107ef60048036038101906107ea9190613e8d565b611c29565b6040516107fc9190613fad565b60405180910390f35b348015610810575f80fd5b5061082b60048036038101906108269190613e8d565b611cd4565b6040516108389190613fad565b60405180910390f35b34801561084c575f80fd5b5061086760048036038101906108629190613e8d565b611d7f565b604051610875929190613ed3565b60405180910390f35b348015610889575f80fd5b506108a4600480360381019061089f91906140d8565b611db7565b6040516108b19190614112565b60405180910390f35b3480156108c5575f80fd5b506108ce611dda565b6040516108db919061408c565b60405180910390f35b3480156108ef575f80fd5b506108f8611dee565b6040516109059190614050565b60405180910390f35b348015610919575f80fd5b50610934600480360381019061092f9190613e8d565b611e7a565b6040516109419190614178565b60405180910390f35b348015610955575f80fd5b5061095e611ec7565b005b34801561096b575f80fd5b506109866004803603810190610981919061420b565b611eda565b005b348015610993575f80fd5b506109ae60048036038101906109a99190614406565b612237565b005b3480156109bb575f80fd5b506109c46122dd565b6040516109d1919061408c565b60405180910390f35b6109e26122f1565b005b3480156109ef575f80fd5b50610a0a6004803603810190610a05919061420b565b612360565b005b348015610a17575f80fd5b50610a326004803603810190610a2d9190613e8d565b6126bd565b604051610a3f9190613fad565b60405180910390f35b348015610a53575f80fd5b50610a5c612768565b604051610a69919061408c565b60405180910390f35b348015610a7d575f80fd5b50610a8661277b565b604051610a939190614112565b60405180910390f35b348015610aa7575f80fd5b50610ab06127a3565b604051610abd9190614471565b60405180910390f35b348015610ad1575f80fd5b50610ada6127c8565b604051610ae7919061408c565b60405180910390f35b348015610afb575f80fd5b50610b046127dc565b604051610b11919061408c565b60405180910390f35b348015610b25575f80fd5b50610b2e6127f0565b604051610b3b9190614050565b60405180910390f35b348015610b4f575f80fd5b50610b6a6004803603810190610b6591906144df565b612880565b005b348015610b77575f80fd5b50610b926004803603810190610b8d9190614587565b612996565b005b348015610b9f575f80fd5b50610ba86129e9565b604051610bb5919061408c565b60405180910390f35b348015610bc9575f80fd5b50610be46004803603810190610bdf91906144df565b6129fd565b005b348015610bf1575f80fd5b50610c0c6004803603810190610c0791906144df565b612b2e565b005b610c286004803603810190610c23919061461a565b612c44565b005b348015610c35575f80fd5b50610c506004803603810190610c4b9190614406565b612cb4565b005b348015610c5d575f80fd5b50610c786004803603810190610c73919061420b565b612d5a565b005b348015610c85575f80fd5b50610ca06004803603810190610c9b91906140d8565b6130b7565b604051610cad9190614050565b60405180910390f35b348015610cc1575f80fd5b50610cdc6004803603810190610cd791906140d8565b61315b565b604051610ce99190613f94565b60405180910390f35b348015610cfd575f80fd5b50610d0661316c565b604051610d139190614178565b60405180910390f35b348015610d27575f80fd5b50610d30613190565b604051610d3d9190614178565b60405180910390f35b348015610d51575f80fd5b50610d6c6004803603810190610d6791906144df565b613196565b005b348015610d79575f80fd5b50610d946004803603810190610d8f9190613e8d565b613264565b604051610da191906146bc565b60405180910390f35b348015610db5575f80fd5b50610dd06004803603810190610dcb9190613e8d565b613297565b604051610dde929190613ed3565b60405180910390f35b348015610df2575f80fd5b50610e0d6004803603810190610e089190613e8d565b6132cf565b604051610e1b929190613ed3565b60405180910390f35b348015610e2f575f80fd5b50610e4a6004803603810190610e4591906146d5565b613307565b604051610e579190613f94565b60405180910390f35b348015610e6b575f80fd5b50610e74613329565b604051610e81919061408c565b60405180910390f35b348015610e95575f80fd5b50610eb06004803603810190610eab9190613e8d565b61333d565b005b348015610ebd575f80fd5b50610ed86004803603810190610ed3919061473d565b6133c1565b005b348015610ee5575f80fd5b50610eee61340c565b604051610efb919061408c565b60405180910390f35b600f602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f8160e01c635b5e139f81146380ac58cd82146301ffc9a783141717915050919050565b6008544210610fa4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9b906147b2565b60405180910390fd5b5f610fae33611cd4565b60ff1611610ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe89061481a565b60405180910390fd5b600760129054906101000a900461ffff1661ffff166001600760089054906101000a900461ffff166110239190614865565b61ffff161115611068576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105f906148e4565b60405180910390fd5b600160135f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff1602179055506110de3360125f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f2c1e4cf372ff5cbf0acd582e8b37836cb25ceeedaf74e174d4ff14656f21b39d4260125f9054906101000a900461ffff16604051611135929190614902565b60405180910390a260125f81819054906101000a900461ffff168092919061115c90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600881819054906101000a900461ffff168092919061119790614929565b91906101000a81548161ffff021916908361ffff16021790555050565b5f600f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166112589190614952565b9050919050565b60606002805461126e906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461129a906149b3565b80156112e55780601f106112bc576101008083540402835291602001916112e5565b820191905f5260205f20905b8154815290600101906020018083116112c857829003601f168201915b5050505050905090565b600760029054906101000a900461ffff1681565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f2082018201805460601b60601c61134c5763ceea21b65f526004601cfd5b8060010154915050919050565b61136433838361343d565b5050565b5f60115f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660115f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff1661140c9190614952565b9050919050565b5f6005547f000000000000000000000000000000000000000000000000000000000000000061144291906149e3565b905090565b60085481565b6007600e9054906101000a900461ffff1681565b61146c8383836134ed565b5f1960601c83811693508281169250815f52337f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f2082018201805480831686811481026114d957806114cc5763ceea21b65f526004601cfd5b63a11481005f526004601cfd5b856114eb5763ea553b345f526004601cfd5b865f52826001015480331488331417611516576030600c205461151557634b6e7f185f526004601cfd5b5b8015611523575f84600101555b5085871882188355601c600c206001815403815550855f52601c600c20600181540163ffffffff811661155d576301336cea5f526004601cfd5b80825550508486887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4505050506115988383836134f2565b505050565b6013602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f611604336117e1565b60ff1611611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e9061481a565b60405180910390fd5b8060ff16611654336117e1565b60ff161015611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f90614a60565b60405180910390fd5b8060ff166116a4611413565b6116ae9190614a7e565b7f00000000000000000000000000000000000000000000000000000000000000001015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170790614afb565b60405180910390fd5b80600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff1661176b9190614b19565b92506101000a81548160ff021916908360ff160217905550611790338260ff166134f7565b3373ffffffffffffffffffffffffffffffffffffffff167f30603f56befad35715d530ed1090c153118f6822d031c1e03fc5bc0e3f308089426040516117d69190614178565b60405180910390a250565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166118859190614952565b9050919050565b61189461367b565b80600690816118a39190614cea565b5050565b5f6007600a9054906101000a900461ffff1661ffff16600760089054906101000a900461ffff1661ffff16600760069054906101000a900461ffff1661ffff16600760049054906101000a900461ffff1661ffff16600760029054906101000a900461ffff1661ffff16611919611413565b6119239190614a7e565b61192d9190614a7e565b6119379190614a7e565b6119419190614a7e565b61194b9190614a7e565b905090565b6015602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60085442106119cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c390614e03565b60405180910390fd5b5f6119d633611368565b60ff1611611a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1090614e6b565b60405180910390fd5b600760109054906101000a900461ffff1661ffff166001600760069054906101000a900461ffff16611a4b9190614865565b61ffff161115611a90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8790614ed3565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff160217905550611b063360105f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f263f38b7218c24f51b965c0b6593d85c8dccaefbb20333808a8543f59874b6db4260105f9054906101000a900461ffff16604051611b5d929190614902565b60405180910390a260105f81819054906101000a900461ffff1680929190611b8490614929565b91906101000a81548161ffff021916908361ffff160217905550506007600681819054906101000a900461ffff1680929190611bbf90614929565b91906101000a81548161ffff021916908361ffff16021790555050565b611be7838383611461565b611bf082613702565b15611c1057611c0f83838360405180602001604052805f81525061370c565b5b505050565b600760049054906101000a900461ffff1681565b5f60155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660155f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611ccd9190614952565b9050919050565b5f60135f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660135f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611d789190614952565b9050919050565b600d602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f611dc182613799565b905080611dd55763ceea21b65f526004601cfd5b919050565b6007600a9054906101000a900461ffff1681565b60068054611dfb906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054611e27906149b3565b8015611e725780601f10611e4957610100808354040283529160200191611e72565b820191905f5260205f20905b815481529060010190602001808311611e5557829003601f168201915b505050505081565b5f81611e8d57638f4eb6045f526004601cfd5b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f5263ffffffff601c600c2054169050919050565b611ecf61367b565b611ed85f6137d7565b565b6008544210611f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1590614f3b565b60405180910390fd5b5f611f2833611c29565b60ff1611611f6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f629061481a565b60405180910390fd5b8060ff16611f7833611c29565b60ff161015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff166007600a9054906101000a900461ffff16611ff09190614865565b61ffff161115612035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202c90614fa3565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156120535761205261423e565b5b6040519080825280602002602001820160405280156120815781602001602082028036833780820191505090505b5090508160155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166120df9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff1610156121e2576121243360145f9054906101000a900461ffff1661ffff16613420565b60145f9054906101000a900461ffff16828260ff168151811061214a57612149614fc1565b5b602002602001019061ffff16908161ffff168152505060145f81819054906101000a900461ffff168092919061217f90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600a81819054906101000a900461ffff16809291906121ba90614929565b91906101000a81548161ffff021916908361ffff1602179055505080806001019150506120f9565b503373ffffffffffffffffffffffffffffffffffffffff167f9a7729d96d93ef9a9153e2274fdbdf5c747b943e4279957ad6f7cf8ced687b27428360405161222b9291906150a5565b60405180910390a25050565b61223f61367b565b5f5b828290508110156122d857600160115f85858581811061226457612263614fc1565b5b90506020020160208101906122799190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612241565b505050565b600760149054906101000a900461ffff1681565b6122f961367b565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f1935050505015801561235d573d5f803e3d5ffd5b50565b60085442106123a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239b9061511d565b60405180910390fd5b5f6123ae336111b4565b60ff16116123f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e89061481a565b60405180910390fd5b8060ff166123fe336111b4565b60ff161015612442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243990614a60565b60405180910390fd5b6007600e9054906101000a900461ffff1661ffff168160ff16600760049054906101000a900461ffff166124769190614865565b61ffff1611156124bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b290615185565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156124d9576124d861423e565b5b6040519080825280602002602001820160405280156125075781602001602082028036833780820191505090505b50905081600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166125659190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff161015612668576125aa33600e5f9054906101000a900461ffff1661ffff16613420565b600e5f9054906101000a900461ffff16828260ff16815181106125d0576125cf614fc1565b5b602002602001019061ffff16908161ffff1681525050600e5f81819054906101000a900461ffff168092919061260590614929565b91906101000a81548161ffff021916908361ffff160217905550506007600481819054906101000a900461ffff168092919061264090614929565b91906101000a81548161ffff021916908361ffff16021790555050808060010191505061257f565b503373ffffffffffffffffffffffffffffffffffffffff167f8623fb7c4a27402c7d1eed0c33dbc59d1c2c0b397dd45db820a50b3ce3a67c9542836040516126b19291906150a5565b60405180910390a25050565b5f600d5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166127619190614952565b9050919050565b60075f9054906101000a900461ffff1681565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6007600c9054906101000a900461ffff1681565b600760089054906101000a900461ffff1681565b6060600380546127ff906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461282b906149b3565b80156128765780601f1061284d57610100808354040283529160200191612876565b820191905f5260205f20905b81548152906001019060200180831161285957829003601f168201915b5050505050905090565b61288861367b565b8181905084849050146128d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c790615213565b60405180910390fd5b5f5b8484905081101561298f578282828181106128f0576128ef614fc1565b5b9050602002016020810190612905919061420b565b600f5f87878581811061291b5761291a614fc1565b5b90506020020160208101906129309190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506128d2565b5050505050565b801515905081601c52670a5a2e7a00000000600852335f52806030600c2055805f528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa35050565b600760069054906101000a900461ffff1681565b612a0561367b565b818190508484905014612a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a4490615213565b60405180910390fd5b5f5b84849050811015612b2757828282818110612a6d57612a6c614fc1565b5b9050602002016020810190612a82919061420b565b600b5f878785818110612a9857612a97614fc1565b5b9050602002016020810190612aad9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f8282829054906101000a900460ff16612b029190614b19565b92506101000a81548160ff021916908360ff1602179055508080600101915050612a4f565b5050505050565b612b3661367b565b818190508484905014612b7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b7590615213565b60405180910390fd5b5f5b84849050811015612c3d57828282818110612b9e57612b9d614fc1565b5b9050602002016020810190612bb3919061420b565b600d5f878785818110612bc957612bc8614fc1565b5b9050602002016020810190612bde9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612b80565b5050505050565b612c4f858585611461565b612c5884613702565b15612cad57612cac85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505061370c565b5b5050505050565b612cbc61367b565b5f5b82829050811015612d5557600160135f858585818110612ce157612ce0614fc1565b5b9050602002016020810190612cf69190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612cbe565b505050565b6008544210612d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d959061527b565b60405180910390fd5b5f612da8336126bd565b60ff1611612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de29061481a565b60405180910390fd5b8060ff16612df8336126bd565b60ff161015612e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff16600760029054906101000a900461ffff16612e709190614865565b61ffff161115612eb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eac906152e3565b60405180910390fd5b5f8160ff1667ffffffffffffffff811115612ed357612ed261423e565b5b604051908082528060200260200182016040528015612f015781602001602082028036833780820191505090505b50905081600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff16612f5f9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff16101561306257612fa433600c5f9054906101000a900461ffff1661ffff16613420565b600c5f9054906101000a900461ffff16828260ff1681518110612fca57612fc9614fc1565b5b602002602001019061ffff16908161ffff1681525050600c5f81819054906101000a900461ffff1680929190612fff90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600281819054906101000a900461ffff168092919061303a90614929565b91906101000a81548161ffff021916908361ffff160217905550508080600101915050612f79565b503373ffffffffffffffffffffffffffffffffffffffff167f217c0dc2383a06fa566bfc4a8dbe3281dc6a3642e0e56927edfdf03d8efbdf6042836040516130ab9291906150a5565b60405180910390a25050565b60606130c28261389a565b613101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130f89061534b565b60405180910390fd5b5f61310a6138d5565b90505f8151116131285760405180602001604052805f815250613153565b8061313284613965565b6040516020016131439291906153a3565b6040516020818303038152906040525b915050919050565b5f6131658261389a565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055481565b61319e61367b565b5f5b8484905081101561325d578282828181106131be576131bd614fc1565b5b90506020020160208101906131d3919061420b565b60155f8787858181106131e9576131e8614fc1565b5b90506020020160208101906131fe9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506131a0565b5050505050565b5f60c061327083613a2f565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050919050565b6011602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b600b602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f81601c52670a5a2e7a00000000600852825f526030600c2054905092915050565b600760109054906101000a900461ffff1681565b61334561367b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036133b5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016133ac9190614112565b60405180910390fd5b6133be816137d7565b50565b6133c961367b565b80600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600760129054906101000a900461ffff1681565b613439828260405180602001604052805f815250613a67565b5050565b5f1960601c82811692508381169350815f52837f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f208201820180548216806134935763ceea21b65f526004601cfd5b8086148615176134b857805f526030600c20546134b757634b6e7f185f526004601cfd5b5b8482600101558385827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4505050505050565b505050565b505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461355c576040517fd9d552c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8103613595576040517f4600cfe900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060055410156135d1576040517f7775abdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051806020016040528042446040516020016135f09291906153e6565b604051602081830303815290604052805190602001205f1c81525090505f60055490505f5b83811015613663575f6136318385613a9190919063ffffffff16565b90505f61363e8285613aba565b905061364a8782613b57565b8361365490615411565b93508260010192505050613615565b5061366e8484613c2b565b8060058190555050505050565b613683613c89565b73ffffffffffffffffffffffffffffffffffffffff166136a161277b565b73ffffffffffffffffffffffffffffffffffffffff1614613700576136c4613c89565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016136f79190614112565b60405180910390fd5b565b5f813b9050919050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015613753578060c08401826020870160045afa505b60208360a48301601c86015f8a5af1613778573d15613774573d5f803e3d5ffd5b5f83525b8160e01b8351146137905763d1a57ed65f526004601cfd5b50505050505050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b60601c9050919050565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b9050919050565b6060600680546138e4906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054613910906149b3565b801561395b5780601f106139325761010080835404028352916020019161395b565b820191905f5260205f20905b81548152906001019060200180831161393e57829003601f168201915b5050505050905090565b60605f600161397384613c90565b0190505f8167ffffffffffffffff8111156139915761399061423e565b5b6040519080825280601f01601f1916602001820160405280156139c35781602001600182028036833780820191505090505b5090505f82602001820190505b600115613a24578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613a1957613a18615438565b5b0494505f85036139d0575b819350505050919050565b5f7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c205460201c9050919050565b613a718383613b57565b613a7a83613702565b15613a8c57613a8b5f84848461370c565b5b505050565b5f5b600115613aaf5760208320905080835281825f03068110613a93575b818106905092915050565b5f8060045f8581526020019081526020015f205490505f600184613ade91906149e3565b90505f60045f8381526020019081526020015f205490505f8314613b025782613b04565b855b9350818614613b32575f8114613b1a5780613b1c565b815b60045f8881526020019081526020015f20819055505b5f8114613b4e5760045f8381526020019081526020015f205f90555b50505092915050565b613b625f83836134ed565b8160601b60601c915081613b7d5763ea553b345f526004601cfd5b805f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f208101810180548060601b15613bc45763c991cbb15f526004601cfd5b8381178255835f52601c600c20600181540163ffffffff8116613bee576301336cea5f526004601cfd5b808255505082845f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45050613c275f83836134f2565b5050565b5f613c3583613264565b90505f8282613c449190615465565b90505f613c5085613a2f565b9050613c82858277ffffffffffffffffffffffffffffffffffffffffffffffff1660c08563ffffffff16901b17613de1565b5050505050565b5f33905090565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613cec577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613ce257613ce1615438565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613d29576d04ee2d6d415b85acef81000000008381613d1f57613d1e615438565b5b0492506020810190505b662386f26fc100008310613d5857662386f26fc100008381613d4e57613d4d615438565b5b0492506010810190505b6305f5e1008310613d81576305f5e1008381613d7757613d76615438565b5b0492506008810190505b6127108310613da6576127108381613d9c57613d9b615438565b5b0492506004810190505b60648310613dc95760648381613dbf57613dbe615438565b5b0492506002810190505b600a8310613dd8576001810190505b80915050919050565b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c2080548060201c831860201b8118825550505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613e5c82613e33565b9050919050565b613e6c81613e52565b8114613e76575f80fd5b50565b5f81359050613e8781613e63565b92915050565b5f60208284031215613ea257613ea1613e2b565b5b5f613eaf84828501613e79565b91505092915050565b5f60ff82169050919050565b613ecd81613eb8565b82525050565b5f604082019050613ee65f830185613ec4565b613ef36020830184613ec4565b9392505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f2e81613efa565b8114613f38575f80fd5b50565b5f81359050613f4981613f25565b92915050565b5f60208284031215613f6457613f63613e2b565b5b5f613f7184828501613f3b565b91505092915050565b5f8115159050919050565b613f8e81613f7a565b82525050565b5f602082019050613fa75f830184613f85565b92915050565b5f602082019050613fc05f830184613ec4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613ffd578082015181840152602081019050613fe2565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61402282613fc6565b61402c8185613fd0565b935061403c818560208601613fe0565b61404581614008565b840191505092915050565b5f6020820190508181035f8301526140688184614018565b905092915050565b5f61ffff82169050919050565b61408681614070565b82525050565b5f60208201905061409f5f83018461407d565b92915050565b5f819050919050565b6140b7816140a5565b81146140c1575f80fd5b50565b5f813590506140d2816140ae565b92915050565b5f602082840312156140ed576140ec613e2b565b5b5f6140fa848285016140c4565b91505092915050565b61410c81613e52565b82525050565b5f6020820190506141255f830184614103565b92915050565b5f806040838503121561414157614140613e2b565b5b5f61414e85828601613e79565b925050602061415f858286016140c4565b9150509250929050565b614172816140a5565b82525050565b5f60208201905061418b5f830184614169565b92915050565b5f805f606084860312156141a8576141a7613e2b565b5b5f6141b586828701613e79565b93505060206141c686828701613e79565b92505060406141d7868287016140c4565b9150509250925092565b6141ea81613eb8565b81146141f4575f80fd5b50565b5f81359050614205816141e1565b92915050565b5f602082840312156142205761421f613e2b565b5b5f61422d848285016141f7565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61427482614008565b810181811067ffffffffffffffff821117156142935761429261423e565b5b80604052505050565b5f6142a5613e22565b90506142b1828261426b565b919050565b5f67ffffffffffffffff8211156142d0576142cf61423e565b5b6142d982614008565b9050602081019050919050565b828183375f83830152505050565b5f614306614301846142b6565b61429c565b9050828152602081018484840111156143225761432161423a565b5b61432d8482856142e6565b509392505050565b5f82601f83011261434957614348614236565b5b81356143598482602086016142f4565b91505092915050565b5f6020828403121561437757614376613e2b565b5b5f82013567ffffffffffffffff81111561439457614393613e2f565b5b6143a084828501614335565b91505092915050565b5f80fd5b5f80fd5b5f8083601f8401126143c6576143c5614236565b5b8235905067ffffffffffffffff8111156143e3576143e26143a9565b5b6020830191508360208202830111156143ff576143fe6143ad565b5b9250929050565b5f806020838503121561441c5761441b613e2b565b5b5f83013567ffffffffffffffff81111561443957614438613e2f565b5b614445858286016143b1565b92509250509250929050565b5f61445b82613e33565b9050919050565b61446b81614451565b82525050565b5f6020820190506144845f830184614462565b92915050565b5f8083601f84011261449f5761449e614236565b5b8235905067ffffffffffffffff8111156144bc576144bb6143a9565b5b6020830191508360208202830111156144d8576144d76143ad565b5b9250929050565b5f805f80604085870312156144f7576144f6613e2b565b5b5f85013567ffffffffffffffff81111561451457614513613e2f565b5b614520878288016143b1565b9450945050602085013567ffffffffffffffff81111561454357614542613e2f565b5b61454f8782880161448a565b925092505092959194509250565b61456681613f7a565b8114614570575f80fd5b50565b5f813590506145818161455d565b92915050565b5f806040838503121561459d5761459c613e2b565b5b5f6145aa85828601613e79565b92505060206145bb85828601614573565b9150509250929050565b5f8083601f8401126145da576145d9614236565b5b8235905067ffffffffffffffff8111156145f7576145f66143a9565b5b602083019150836001820283011115614613576146126143ad565b5b9250929050565b5f805f805f6080868803121561463357614632613e2b565b5b5f61464088828901613e79565b955050602061465188828901613e79565b9450506040614662888289016140c4565b935050606086013567ffffffffffffffff81111561468357614682613e2f565b5b61468f888289016145c5565b92509250509295509295909350565b5f63ffffffff82169050919050565b6146b68161469e565b82525050565b5f6020820190506146cf5f8301846146ad565b92915050565b5f80604083850312156146eb576146ea613e2b565b5b5f6146f885828601613e79565b925050602061470985828601613e79565b9150509250929050565b61471c81614451565b8114614726575f80fd5b50565b5f8135905061473781614713565b92915050565b5f6020828403121561475257614751613e2b565b5b5f61475f84828501614729565b91505092915050565b7f4a75646765206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f61479c601083613fd0565b91506147a782614768565b602082019050919050565b5f6020820190508181035f8301526147c981614790565b9050919050565b7f4e6f7420656c696769626c6500000000000000000000000000000000000000005f82015250565b5f614804600c83613fd0565b915061480f826147d0565b602082019050919050565b5f6020820190508181035f830152614831816147f8565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61486f82614070565b915061487a83614070565b9250828201905061ffff81111561489457614893614838565b5b92915050565b7f4d617820737570706c79206a75646765206578636565640000000000000000005f82015250565b5f6148ce601783613fd0565b91506148d98261489a565b602082019050919050565b5f6020820190508181035f8301526148fb816148c2565b9050919050565b5f6040820190506149155f830185614169565b614922602083018461407d565b9392505050565b5f61493382614070565b915061ffff820361494757614946614838565b5b600182019050919050565b5f61495c82613eb8565b915061496783613eb8565b9250828203905060ff8111156149805761497f614838565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806149ca57607f821691505b6020821081036149dd576149dc614986565b5b50919050565b5f6149ed826140a5565b91506149f8836140a5565b9250828203905081811115614a1057614a0f614838565b5b92915050565b7f4e6f7420656e6f75676820636c61696d61626c6520746f6b656e7300000000005f82015250565b5f614a4a601b83613fd0565b9150614a5582614a16565b602082019050919050565b5f6020820190508181035f830152614a7781614a3e565b9050919050565b5f614a88826140a5565b9150614a93836140a5565b9250828201905080821115614aab57614aaa614838565b5b92915050565b7f537570706c79206c696d697420657863656564000000000000000000000000005f82015250565b5f614ae5601383613fd0565b9150614af082614ab1565b602082019050919050565b5f6020820190508181035f830152614b1281614ad9565b9050919050565b5f614b2382613eb8565b9150614b2e83613eb8565b9250828201905060ff811115614b4757614b46614838565b5b92915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614ba97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614b6e565b614bb38683614b6e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f614bee614be9614be4846140a5565b614bcb565b6140a5565b9050919050565b5f819050919050565b614c0783614bd4565b614c1b614c1382614bf5565b848454614b7a565b825550505050565b5f90565b614c2f614c23565b614c3a818484614bfe565b505050565b5b81811015614c5d57614c525f82614c27565b600181019050614c40565b5050565b601f821115614ca257614c7381614b4d565b614c7c84614b5f565b81016020851015614c8b578190505b614c9f614c9785614b5f565b830182614c3f565b50505b505050565b5f82821c905092915050565b5f614cc25f1984600802614ca7565b1980831691505092915050565b5f614cda8383614cb3565b9150826002028217905092915050565b614cf382613fc6565b67ffffffffffffffff811115614d0c57614d0b61423e565b5b614d1682546149b3565b614d21828285614c61565b5f60209050601f831160018114614d52575f8415614d40578287015190505b614d4a8582614ccf565b865550614db1565b601f198416614d6086614b4d565b5f5b82811015614d8757848901518255600182019150602085019450602081019050614d62565b86831015614da45784890151614da0601f891682614cb3565b8355505b6001600288020188555050505b505050505050565b7f477561726469616e206d696e7420636c6f7365000000000000000000000000005f82015250565b5f614ded601383613fd0565b9150614df882614db9565b602082019050919050565b5f6020820190508181035f830152614e1a81614de1565b9050919050565b7f4e6f2067697665776179000000000000000000000000000000000000000000005f82015250565b5f614e55600a83613fd0565b9150614e6082614e21565b602082019050919050565b5f6020820190508181035f830152614e8281614e49565b9050919050565b7f4d617820737570706c7920677561726469616e206578636565640000000000005f82015250565b5f614ebd601a83613fd0565b9150614ec882614e89565b602082019050919050565b5f6020820190508181035f830152614eea81614eb1565b9050919050565b7f5768616c65206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f614f25601083613fd0565b9150614f3082614ef1565b602082019050919050565b5f6020820190508181035f830152614f5281614f19565b9050919050565b7f4d617820737570706c79207768616c65206578636565640000000000000000005f82015250565b5f614f8d601783613fd0565b9150614f9882614f59565b602082019050919050565b5f6020820190508181035f830152614fba81614f81565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61502081614070565b82525050565b5f6150318383615017565b60208301905092915050565b5f602082019050919050565b5f61505382614fee565b61505d8185614ff8565b935061506883615008565b805f5b8381101561509857815161507f8882615026565b975061508a8361503d565b92505060018101905061506b565b5085935050505092915050565b5f6040820190506150b85f830185614169565b81810360208301526150ca8184615049565b90509392505050565b7f486f6e6f72617279206d696e7420636c6f7365000000000000000000000000005f82015250565b5f615107601383613fd0565b9150615112826150d3565b602082019050919050565b5f6020820190508181035f830152615134816150fb565b9050919050565b7f4d617820737570706c7920686f6e6f72617279206578636565640000000000005f82015250565b5f61516f601a83613fd0565b915061517a8261513b565b602082019050919050565b5f6020820190508181035f83015261519c81615163565b9050919050565b7f4e62206164647265737320616e64206e62207175616e746974696573206d75735f8201527f7420626520657175616c00000000000000000000000000000000000000000000602082015250565b5f6151fd602a83613fd0565b9150615208826151a3565b604082019050919050565b5f6020820190508181035f83015261522a816151f1565b9050919050565b7f436f756e63696c206d696e7420636c6f736500000000000000000000000000005f82015250565b5f615265601283613fd0565b915061527082615231565b602082019050919050565b5f6020820190508181035f83015261529281615259565b9050919050565b7f4d617820737570706c7920636f756e63696c20657863656564000000000000005f82015250565b5f6152cd601983613fd0565b91506152d882615299565b602082019050919050565b5f6020820190508181035f8301526152fa816152c1565b9050919050565b7f756e6b6e6f7720746f6b656e00000000000000000000000000000000000000005f82015250565b5f615335600c83613fd0565b915061534082615301565b602082019050919050565b5f6020820190508181035f83015261536281615329565b9050919050565b5f81905092915050565b5f61537d82613fc6565b6153878185615369565b9350615397818560208601613fe0565b80840191505092915050565b5f6153ae8285615373565b91506153ba8284615373565b91508190509392505050565b5f819050919050565b6153e06153db826140a5565b6153c6565b82525050565b5f6153f182856153cf565b60208201915061540182846153cf565b6020820191508190509392505050565b5f61541b826140a5565b91505f820361542d5761542c614838565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61546f8261469e565b915061547a8361469e565b9250828201905063ffffffff81111561549657615495614838565b5b9291505056fea2646970667358221220e90b78fd1e48f9522ce04e38979dd9b18bffed2f6a6e775afd6152c433fa750964736f6c63430008170033

Deployed Bytecode

0x6080604052600436106103c2575f3560e01c80637a12ef82116101f1578063b88d4fde1161010c578063dc33e6811161009f578063ea3d74181161006e578063ea3d741814610e60578063f2fde38b14610e8a578063fb5b82d014610eb2578063fc89067914610eda576103c2565b8063dc33e68114610d6e578063dd330e4d14610daa578063df1dc2c514610de7578063e985e9c514610e24576103c2565b8063cc0c5236116100db578063cc0c523614610cb6578063d5abeb0114610cf2578063da0239a614610d1c578063dab00abb14610d46576103c2565b8063b88d4fde14610c0e578063b904e37a14610c2a578063bc68ed6c14610c52578063c87b56dd14610c7a576103c2565b8063916ec2c611610184578063a22cb46511610153578063a22cb46514610b6c578063a2cd568914610b94578063ac497a4814610bbe578063b55698d514610be6576103c2565b8063916ec2c614610ac657806391ec4b4c14610af057806395d89b4114610b1a5780639a3e276814610b44576103c2565b8063889960ea116101c0578063889960ea14610a0c5780638b4303a614610a485780638da5cb5b14610a72578063913e77ad14610a9c576103c2565b80637a12ef82146109885780637ca470b1146109b0578063853828b6146109da57806385ad1cf5146109e4576103c2565b80632ff1474d116102e157806352186417116102745780636c0360eb116102435780636c0360eb146108e457806370a082311461090e578063715018a61461094a5780637400c92214610960576103c2565b806352186417146108055780635d42a059146108415780636352211e1461087e5780636802e529146108ba576103c2565b8063376e1b1f116102b0578063376e1b1f1461076d57806342842e0e1461078357806346fbed6f1461079f5780634e27acff146107c9576103c2565b80632ff1474d146106a257806331b5b907146106de57806333a3600714610706578063343bc89314610730576103c2565b8063106e707b1161035957806323b872dd1161032857806323b872dd146105f757806326d6327914610613578063282e7811146106505780632db5b8e71461067a576103c2565b8063106e707b1461053d57806318160ddd146105795780631bf3dd4f146105a35780631d490ee3146105cd576103c2565b806306fdde031161039557806306fdde031461049157806307edf9ef146104bb578063081812fc146104e5578063095ea7b314610521576103c2565b80630129b0b9146103c657806301ffc9a714610403578063022c01991461043f5780630322ba9814610455575b5f80fd5b3480156103d1575f80fd5b506103ec60048036038101906103e79190613e8d565b610f04565b6040516103fa929190613ed3565b60405180910390f35b34801561040e575f80fd5b5061042960048036038101906104249190613f4f565b610f3c565b6040516104369190613f94565b60405180910390f35b34801561044a575f80fd5b50610453610f60565b005b348015610460575f80fd5b5061047b60048036038101906104769190613e8d565b6111b4565b6040516104889190613fad565b60405180910390f35b34801561049c575f80fd5b506104a561125f565b6040516104b29190614050565b60405180910390f35b3480156104c6575f80fd5b506104cf6112ef565b6040516104dc919061408c565b60405180910390f35b3480156104f0575f80fd5b5061050b600480360381019061050691906140d8565b611303565b6040516105189190614112565b60405180910390f35b61053b6004803603810190610536919061412b565b611359565b005b348015610548575f80fd5b50610563600480360381019061055e9190613e8d565b611368565b6040516105709190613fad565b60405180910390f35b348015610584575f80fd5b5061058d611413565b60405161059a9190614178565b60405180910390f35b3480156105ae575f80fd5b506105b7611447565b6040516105c49190614178565b60405180910390f35b3480156105d8575f80fd5b506105e161144d565b6040516105ee919061408c565b60405180910390f35b610611600480360381019061060c9190614191565b611461565b005b34801561061e575f80fd5b5061063960048036038101906106349190613e8d565b61159d565b604051610647929190613ed3565b60405180910390f35b34801561065b575f80fd5b506106646115d5565b6040516106719190614112565b60405180910390f35b348015610685575f80fd5b506106a0600480360381019061069b919061420b565b6115fa565b005b3480156106ad575f80fd5b506106c860048036038101906106c39190613e8d565b6117e1565b6040516106d59190613fad565b60405180910390f35b3480156106e9575f80fd5b5061070460048036038101906106ff9190614362565b61188c565b005b348015610711575f80fd5b5061071a6118a7565b6040516107279190614178565b60405180910390f35b34801561073b575f80fd5b5061075660048036038101906107519190613e8d565b611950565b604051610764929190613ed3565b60405180910390f35b348015610778575f80fd5b50610781611988565b005b61079d60048036038101906107989190614191565b611bdc565b005b3480156107aa575f80fd5b506107b3611c15565b6040516107c0919061408c565b60405180910390f35b3480156107d4575f80fd5b506107ef60048036038101906107ea9190613e8d565b611c29565b6040516107fc9190613fad565b60405180910390f35b348015610810575f80fd5b5061082b60048036038101906108269190613e8d565b611cd4565b6040516108389190613fad565b60405180910390f35b34801561084c575f80fd5b5061086760048036038101906108629190613e8d565b611d7f565b604051610875929190613ed3565b60405180910390f35b348015610889575f80fd5b506108a4600480360381019061089f91906140d8565b611db7565b6040516108b19190614112565b60405180910390f35b3480156108c5575f80fd5b506108ce611dda565b6040516108db919061408c565b60405180910390f35b3480156108ef575f80fd5b506108f8611dee565b6040516109059190614050565b60405180910390f35b348015610919575f80fd5b50610934600480360381019061092f9190613e8d565b611e7a565b6040516109419190614178565b60405180910390f35b348015610955575f80fd5b5061095e611ec7565b005b34801561096b575f80fd5b506109866004803603810190610981919061420b565b611eda565b005b348015610993575f80fd5b506109ae60048036038101906109a99190614406565b612237565b005b3480156109bb575f80fd5b506109c46122dd565b6040516109d1919061408c565b60405180910390f35b6109e26122f1565b005b3480156109ef575f80fd5b50610a0a6004803603810190610a05919061420b565b612360565b005b348015610a17575f80fd5b50610a326004803603810190610a2d9190613e8d565b6126bd565b604051610a3f9190613fad565b60405180910390f35b348015610a53575f80fd5b50610a5c612768565b604051610a69919061408c565b60405180910390f35b348015610a7d575f80fd5b50610a8661277b565b604051610a939190614112565b60405180910390f35b348015610aa7575f80fd5b50610ab06127a3565b604051610abd9190614471565b60405180910390f35b348015610ad1575f80fd5b50610ada6127c8565b604051610ae7919061408c565b60405180910390f35b348015610afb575f80fd5b50610b046127dc565b604051610b11919061408c565b60405180910390f35b348015610b25575f80fd5b50610b2e6127f0565b604051610b3b9190614050565b60405180910390f35b348015610b4f575f80fd5b50610b6a6004803603810190610b6591906144df565b612880565b005b348015610b77575f80fd5b50610b926004803603810190610b8d9190614587565b612996565b005b348015610b9f575f80fd5b50610ba86129e9565b604051610bb5919061408c565b60405180910390f35b348015610bc9575f80fd5b50610be46004803603810190610bdf91906144df565b6129fd565b005b348015610bf1575f80fd5b50610c0c6004803603810190610c0791906144df565b612b2e565b005b610c286004803603810190610c23919061461a565b612c44565b005b348015610c35575f80fd5b50610c506004803603810190610c4b9190614406565b612cb4565b005b348015610c5d575f80fd5b50610c786004803603810190610c73919061420b565b612d5a565b005b348015610c85575f80fd5b50610ca06004803603810190610c9b91906140d8565b6130b7565b604051610cad9190614050565b60405180910390f35b348015610cc1575f80fd5b50610cdc6004803603810190610cd791906140d8565b61315b565b604051610ce99190613f94565b60405180910390f35b348015610cfd575f80fd5b50610d0661316c565b604051610d139190614178565b60405180910390f35b348015610d27575f80fd5b50610d30613190565b604051610d3d9190614178565b60405180910390f35b348015610d51575f80fd5b50610d6c6004803603810190610d6791906144df565b613196565b005b348015610d79575f80fd5b50610d946004803603810190610d8f9190613e8d565b613264565b604051610da191906146bc565b60405180910390f35b348015610db5575f80fd5b50610dd06004803603810190610dcb9190613e8d565b613297565b604051610dde929190613ed3565b60405180910390f35b348015610df2575f80fd5b50610e0d6004803603810190610e089190613e8d565b6132cf565b604051610e1b929190613ed3565b60405180910390f35b348015610e2f575f80fd5b50610e4a6004803603810190610e4591906146d5565b613307565b604051610e579190613f94565b60405180910390f35b348015610e6b575f80fd5b50610e74613329565b604051610e81919061408c565b60405180910390f35b348015610e95575f80fd5b50610eb06004803603810190610eab9190613e8d565b61333d565b005b348015610ebd575f80fd5b50610ed86004803603810190610ed3919061473d565b6133c1565b005b348015610ee5575f80fd5b50610eee61340c565b604051610efb919061408c565b60405180910390f35b600f602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f8160e01c635b5e139f81146380ac58cd82146301ffc9a783141717915050919050565b6008544210610fa4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9b906147b2565b60405180910390fd5b5f610fae33611cd4565b60ff1611610ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe89061481a565b60405180910390fd5b600760129054906101000a900461ffff1661ffff166001600760089054906101000a900461ffff166110239190614865565b61ffff161115611068576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105f906148e4565b60405180910390fd5b600160135f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff1602179055506110de3360125f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f2c1e4cf372ff5cbf0acd582e8b37836cb25ceeedaf74e174d4ff14656f21b39d4260125f9054906101000a900461ffff16604051611135929190614902565b60405180910390a260125f81819054906101000a900461ffff168092919061115c90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600881819054906101000a900461ffff168092919061119790614929565b91906101000a81548161ffff021916908361ffff16021790555050565b5f600f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166112589190614952565b9050919050565b60606002805461126e906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461129a906149b3565b80156112e55780601f106112bc576101008083540402835291602001916112e5565b820191905f5260205f20905b8154815290600101906020018083116112c857829003601f168201915b5050505050905090565b600760029054906101000a900461ffff1681565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f2082018201805460601b60601c61134c5763ceea21b65f526004601cfd5b8060010154915050919050565b61136433838361343d565b5050565b5f60115f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660115f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff1661140c9190614952565b9050919050565b5f6005547f000000000000000000000000000000000000000000000000000000000000033461144291906149e3565b905090565b60085481565b6007600e9054906101000a900461ffff1681565b61146c8383836134ed565b5f1960601c83811693508281169250815f52337f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f2082018201805480831686811481026114d957806114cc5763ceea21b65f526004601cfd5b63a11481005f526004601cfd5b856114eb5763ea553b345f526004601cfd5b865f52826001015480331488331417611516576030600c205461151557634b6e7f185f526004601cfd5b5b8015611523575f84600101555b5085871882188355601c600c206001815403815550855f52601c600c20600181540163ffffffff811661155d576301336cea5f526004601cfd5b80825550508486887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4505050506115988383836134f2565b505050565b6013602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f611604336117e1565b60ff1611611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e9061481a565b60405180910390fd5b8060ff16611654336117e1565b60ff161015611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f90614a60565b60405180910390fd5b8060ff166116a4611413565b6116ae9190614a7e565b7f00000000000000000000000000000000000000000000000000000000000003341015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170790614afb565b60405180910390fd5b80600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff1661176b9190614b19565b92506101000a81548160ff021916908360ff160217905550611790338260ff166134f7565b3373ffffffffffffffffffffffffffffffffffffffff167f30603f56befad35715d530ed1090c153118f6822d031c1e03fc5bc0e3f308089426040516117d69190614178565b60405180910390a250565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166118859190614952565b9050919050565b61189461367b565b80600690816118a39190614cea565b5050565b5f6007600a9054906101000a900461ffff1661ffff16600760089054906101000a900461ffff1661ffff16600760069054906101000a900461ffff1661ffff16600760049054906101000a900461ffff1661ffff16600760029054906101000a900461ffff1661ffff16611919611413565b6119239190614a7e565b61192d9190614a7e565b6119379190614a7e565b6119419190614a7e565b61194b9190614a7e565b905090565b6015602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60085442106119cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c390614e03565b60405180910390fd5b5f6119d633611368565b60ff1611611a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1090614e6b565b60405180910390fd5b600760109054906101000a900461ffff1661ffff166001600760069054906101000a900461ffff16611a4b9190614865565b61ffff161115611a90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8790614ed3565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff160217905550611b063360105f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f263f38b7218c24f51b965c0b6593d85c8dccaefbb20333808a8543f59874b6db4260105f9054906101000a900461ffff16604051611b5d929190614902565b60405180910390a260105f81819054906101000a900461ffff1680929190611b8490614929565b91906101000a81548161ffff021916908361ffff160217905550506007600681819054906101000a900461ffff1680929190611bbf90614929565b91906101000a81548161ffff021916908361ffff16021790555050565b611be7838383611461565b611bf082613702565b15611c1057611c0f83838360405180602001604052805f81525061370c565b5b505050565b600760049054906101000a900461ffff1681565b5f60155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660155f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611ccd9190614952565b9050919050565b5f60135f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660135f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611d789190614952565b9050919050565b600d602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f611dc182613799565b905080611dd55763ceea21b65f526004601cfd5b919050565b6007600a9054906101000a900461ffff1681565b60068054611dfb906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054611e27906149b3565b8015611e725780601f10611e4957610100808354040283529160200191611e72565b820191905f5260205f20905b815481529060010190602001808311611e5557829003601f168201915b505050505081565b5f81611e8d57638f4eb6045f526004601cfd5b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f5263ffffffff601c600c2054169050919050565b611ecf61367b565b611ed85f6137d7565b565b6008544210611f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1590614f3b565b60405180910390fd5b5f611f2833611c29565b60ff1611611f6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f629061481a565b60405180910390fd5b8060ff16611f7833611c29565b60ff161015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff166007600a9054906101000a900461ffff16611ff09190614865565b61ffff161115612035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202c90614fa3565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156120535761205261423e565b5b6040519080825280602002602001820160405280156120815781602001602082028036833780820191505090505b5090508160155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166120df9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff1610156121e2576121243360145f9054906101000a900461ffff1661ffff16613420565b60145f9054906101000a900461ffff16828260ff168151811061214a57612149614fc1565b5b602002602001019061ffff16908161ffff168152505060145f81819054906101000a900461ffff168092919061217f90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600a81819054906101000a900461ffff16809291906121ba90614929565b91906101000a81548161ffff021916908361ffff1602179055505080806001019150506120f9565b503373ffffffffffffffffffffffffffffffffffffffff167f9a7729d96d93ef9a9153e2274fdbdf5c747b943e4279957ad6f7cf8ced687b27428360405161222b9291906150a5565b60405180910390a25050565b61223f61367b565b5f5b828290508110156122d857600160115f85858581811061226457612263614fc1565b5b90506020020160208101906122799190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612241565b505050565b600760149054906101000a900461ffff1681565b6122f961367b565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f1935050505015801561235d573d5f803e3d5ffd5b50565b60085442106123a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239b9061511d565b60405180910390fd5b5f6123ae336111b4565b60ff16116123f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e89061481a565b60405180910390fd5b8060ff166123fe336111b4565b60ff161015612442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243990614a60565b60405180910390fd5b6007600e9054906101000a900461ffff1661ffff168160ff16600760049054906101000a900461ffff166124769190614865565b61ffff1611156124bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b290615185565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156124d9576124d861423e565b5b6040519080825280602002602001820160405280156125075781602001602082028036833780820191505090505b50905081600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166125659190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff161015612668576125aa33600e5f9054906101000a900461ffff1661ffff16613420565b600e5f9054906101000a900461ffff16828260ff16815181106125d0576125cf614fc1565b5b602002602001019061ffff16908161ffff1681525050600e5f81819054906101000a900461ffff168092919061260590614929565b91906101000a81548161ffff021916908361ffff160217905550506007600481819054906101000a900461ffff168092919061264090614929565b91906101000a81548161ffff021916908361ffff16021790555050808060010191505061257f565b503373ffffffffffffffffffffffffffffffffffffffff167f8623fb7c4a27402c7d1eed0c33dbc59d1c2c0b397dd45db820a50b3ce3a67c9542836040516126b19291906150a5565b60405180910390a25050565b5f600d5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166127619190614952565b9050919050565b60075f9054906101000a900461ffff1681565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6007600c9054906101000a900461ffff1681565b600760089054906101000a900461ffff1681565b6060600380546127ff906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461282b906149b3565b80156128765780601f1061284d57610100808354040283529160200191612876565b820191905f5260205f20905b81548152906001019060200180831161285957829003601f168201915b5050505050905090565b61288861367b565b8181905084849050146128d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c790615213565b60405180910390fd5b5f5b8484905081101561298f578282828181106128f0576128ef614fc1565b5b9050602002016020810190612905919061420b565b600f5f87878581811061291b5761291a614fc1565b5b90506020020160208101906129309190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506128d2565b5050505050565b801515905081601c52670a5a2e7a00000000600852335f52806030600c2055805f528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa35050565b600760069054906101000a900461ffff1681565b612a0561367b565b818190508484905014612a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a4490615213565b60405180910390fd5b5f5b84849050811015612b2757828282818110612a6d57612a6c614fc1565b5b9050602002016020810190612a82919061420b565b600b5f878785818110612a9857612a97614fc1565b5b9050602002016020810190612aad9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f8282829054906101000a900460ff16612b029190614b19565b92506101000a81548160ff021916908360ff1602179055508080600101915050612a4f565b5050505050565b612b3661367b565b818190508484905014612b7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b7590615213565b60405180910390fd5b5f5b84849050811015612c3d57828282818110612b9e57612b9d614fc1565b5b9050602002016020810190612bb3919061420b565b600d5f878785818110612bc957612bc8614fc1565b5b9050602002016020810190612bde9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612b80565b5050505050565b612c4f858585611461565b612c5884613702565b15612cad57612cac85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505061370c565b5b5050505050565b612cbc61367b565b5f5b82829050811015612d5557600160135f858585818110612ce157612ce0614fc1565b5b9050602002016020810190612cf69190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612cbe565b505050565b6008544210612d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d959061527b565b60405180910390fd5b5f612da8336126bd565b60ff1611612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de29061481a565b60405180910390fd5b8060ff16612df8336126bd565b60ff161015612e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff16600760029054906101000a900461ffff16612e709190614865565b61ffff161115612eb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eac906152e3565b60405180910390fd5b5f8160ff1667ffffffffffffffff811115612ed357612ed261423e565b5b604051908082528060200260200182016040528015612f015781602001602082028036833780820191505090505b50905081600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff16612f5f9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff16101561306257612fa433600c5f9054906101000a900461ffff1661ffff16613420565b600c5f9054906101000a900461ffff16828260ff1681518110612fca57612fc9614fc1565b5b602002602001019061ffff16908161ffff1681525050600c5f81819054906101000a900461ffff1680929190612fff90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600281819054906101000a900461ffff168092919061303a90614929565b91906101000a81548161ffff021916908361ffff160217905550508080600101915050612f79565b503373ffffffffffffffffffffffffffffffffffffffff167f217c0dc2383a06fa566bfc4a8dbe3281dc6a3642e0e56927edfdf03d8efbdf6042836040516130ab9291906150a5565b60405180910390a25050565b60606130c28261389a565b613101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130f89061534b565b60405180910390fd5b5f61310a6138d5565b90505f8151116131285760405180602001604052805f815250613153565b8061313284613965565b6040516020016131439291906153a3565b6040516020818303038152906040525b915050919050565b5f6131658261389a565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000033481565b60055481565b61319e61367b565b5f5b8484905081101561325d578282828181106131be576131bd614fc1565b5b90506020020160208101906131d3919061420b565b60155f8787858181106131e9576131e8614fc1565b5b90506020020160208101906131fe9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506131a0565b5050505050565b5f60c061327083613a2f565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050919050565b6011602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b600b602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f81601c52670a5a2e7a00000000600852825f526030600c2054905092915050565b600760109054906101000a900461ffff1681565b61334561367b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036133b5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016133ac9190614112565b60405180910390fd5b6133be816137d7565b50565b6133c961367b565b80600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600760129054906101000a900461ffff1681565b613439828260405180602001604052805f815250613a67565b5050565b5f1960601c82811692508381169350815f52837f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f208201820180548216806134935763ceea21b65f526004601cfd5b8086148615176134b857805f526030600c20546134b757634b6e7f185f526004601cfd5b5b8482600101558385827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4505050505050565b505050565b505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461355c576040517fd9d552c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8103613595576040517f4600cfe900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060055410156135d1576040517f7775abdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051806020016040528042446040516020016135f09291906153e6565b604051602081830303815290604052805190602001205f1c81525090505f60055490505f5b83811015613663575f6136318385613a9190919063ffffffff16565b90505f61363e8285613aba565b905061364a8782613b57565b8361365490615411565b93508260010192505050613615565b5061366e8484613c2b565b8060058190555050505050565b613683613c89565b73ffffffffffffffffffffffffffffffffffffffff166136a161277b565b73ffffffffffffffffffffffffffffffffffffffff1614613700576136c4613c89565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016136f79190614112565b60405180910390fd5b565b5f813b9050919050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015613753578060c08401826020870160045afa505b60208360a48301601c86015f8a5af1613778573d15613774573d5f803e3d5ffd5b5f83525b8160e01b8351146137905763d1a57ed65f526004601cfd5b50505050505050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b60601c9050919050565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b9050919050565b6060600680546138e4906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054613910906149b3565b801561395b5780601f106139325761010080835404028352916020019161395b565b820191905f5260205f20905b81548152906001019060200180831161393e57829003601f168201915b5050505050905090565b60605f600161397384613c90565b0190505f8167ffffffffffffffff8111156139915761399061423e565b5b6040519080825280601f01601f1916602001820160405280156139c35781602001600182028036833780820191505090505b5090505f82602001820190505b600115613a24578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613a1957613a18615438565b5b0494505f85036139d0575b819350505050919050565b5f7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c205460201c9050919050565b613a718383613b57565b613a7a83613702565b15613a8c57613a8b5f84848461370c565b5b505050565b5f5b600115613aaf5760208320905080835281825f03068110613a93575b818106905092915050565b5f8060045f8581526020019081526020015f205490505f600184613ade91906149e3565b90505f60045f8381526020019081526020015f205490505f8314613b025782613b04565b855b9350818614613b32575f8114613b1a5780613b1c565b815b60045f8881526020019081526020015f20819055505b5f8114613b4e5760045f8381526020019081526020015f205f90555b50505092915050565b613b625f83836134ed565b8160601b60601c915081613b7d5763ea553b345f526004601cfd5b805f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f208101810180548060601b15613bc45763c991cbb15f526004601cfd5b8381178255835f52601c600c20600181540163ffffffff8116613bee576301336cea5f526004601cfd5b808255505082845f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45050613c275f83836134f2565b5050565b5f613c3583613264565b90505f8282613c449190615465565b90505f613c5085613a2f565b9050613c82858277ffffffffffffffffffffffffffffffffffffffffffffffff1660c08563ffffffff16901b17613de1565b5050505050565b5f33905090565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613cec577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613ce257613ce1615438565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613d29576d04ee2d6d415b85acef81000000008381613d1f57613d1e615438565b5b0492506020810190505b662386f26fc100008310613d5857662386f26fc100008381613d4e57613d4d615438565b5b0492506010810190505b6305f5e1008310613d81576305f5e1008381613d7757613d76615438565b5b0492506008810190505b6127108310613da6576127108381613d9c57613d9b615438565b5b0492506004810190505b60648310613dc95760648381613dbf57613dbe615438565b5b0492506002810190505b600a8310613dd8576001810190505b80915050919050565b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c2080548060201c831860201b8118825550505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613e5c82613e33565b9050919050565b613e6c81613e52565b8114613e76575f80fd5b50565b5f81359050613e8781613e63565b92915050565b5f60208284031215613ea257613ea1613e2b565b5b5f613eaf84828501613e79565b91505092915050565b5f60ff82169050919050565b613ecd81613eb8565b82525050565b5f604082019050613ee65f830185613ec4565b613ef36020830184613ec4565b9392505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f2e81613efa565b8114613f38575f80fd5b50565b5f81359050613f4981613f25565b92915050565b5f60208284031215613f6457613f63613e2b565b5b5f613f7184828501613f3b565b91505092915050565b5f8115159050919050565b613f8e81613f7a565b82525050565b5f602082019050613fa75f830184613f85565b92915050565b5f602082019050613fc05f830184613ec4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613ffd578082015181840152602081019050613fe2565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61402282613fc6565b61402c8185613fd0565b935061403c818560208601613fe0565b61404581614008565b840191505092915050565b5f6020820190508181035f8301526140688184614018565b905092915050565b5f61ffff82169050919050565b61408681614070565b82525050565b5f60208201905061409f5f83018461407d565b92915050565b5f819050919050565b6140b7816140a5565b81146140c1575f80fd5b50565b5f813590506140d2816140ae565b92915050565b5f602082840312156140ed576140ec613e2b565b5b5f6140fa848285016140c4565b91505092915050565b61410c81613e52565b82525050565b5f6020820190506141255f830184614103565b92915050565b5f806040838503121561414157614140613e2b565b5b5f61414e85828601613e79565b925050602061415f858286016140c4565b9150509250929050565b614172816140a5565b82525050565b5f60208201905061418b5f830184614169565b92915050565b5f805f606084860312156141a8576141a7613e2b565b5b5f6141b586828701613e79565b93505060206141c686828701613e79565b92505060406141d7868287016140c4565b9150509250925092565b6141ea81613eb8565b81146141f4575f80fd5b50565b5f81359050614205816141e1565b92915050565b5f602082840312156142205761421f613e2b565b5b5f61422d848285016141f7565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61427482614008565b810181811067ffffffffffffffff821117156142935761429261423e565b5b80604052505050565b5f6142a5613e22565b90506142b1828261426b565b919050565b5f67ffffffffffffffff8211156142d0576142cf61423e565b5b6142d982614008565b9050602081019050919050565b828183375f83830152505050565b5f614306614301846142b6565b61429c565b9050828152602081018484840111156143225761432161423a565b5b61432d8482856142e6565b509392505050565b5f82601f83011261434957614348614236565b5b81356143598482602086016142f4565b91505092915050565b5f6020828403121561437757614376613e2b565b5b5f82013567ffffffffffffffff81111561439457614393613e2f565b5b6143a084828501614335565b91505092915050565b5f80fd5b5f80fd5b5f8083601f8401126143c6576143c5614236565b5b8235905067ffffffffffffffff8111156143e3576143e26143a9565b5b6020830191508360208202830111156143ff576143fe6143ad565b5b9250929050565b5f806020838503121561441c5761441b613e2b565b5b5f83013567ffffffffffffffff81111561443957614438613e2f565b5b614445858286016143b1565b92509250509250929050565b5f61445b82613e33565b9050919050565b61446b81614451565b82525050565b5f6020820190506144845f830184614462565b92915050565b5f8083601f84011261449f5761449e614236565b5b8235905067ffffffffffffffff8111156144bc576144bb6143a9565b5b6020830191508360208202830111156144d8576144d76143ad565b5b9250929050565b5f805f80604085870312156144f7576144f6613e2b565b5b5f85013567ffffffffffffffff81111561451457614513613e2f565b5b614520878288016143b1565b9450945050602085013567ffffffffffffffff81111561454357614542613e2f565b5b61454f8782880161448a565b925092505092959194509250565b61456681613f7a565b8114614570575f80fd5b50565b5f813590506145818161455d565b92915050565b5f806040838503121561459d5761459c613e2b565b5b5f6145aa85828601613e79565b92505060206145bb85828601614573565b9150509250929050565b5f8083601f8401126145da576145d9614236565b5b8235905067ffffffffffffffff8111156145f7576145f66143a9565b5b602083019150836001820283011115614613576146126143ad565b5b9250929050565b5f805f805f6080868803121561463357614632613e2b565b5b5f61464088828901613e79565b955050602061465188828901613e79565b9450506040614662888289016140c4565b935050606086013567ffffffffffffffff81111561468357614682613e2f565b5b61468f888289016145c5565b92509250509295509295909350565b5f63ffffffff82169050919050565b6146b68161469e565b82525050565b5f6020820190506146cf5f8301846146ad565b92915050565b5f80604083850312156146eb576146ea613e2b565b5b5f6146f885828601613e79565b925050602061470985828601613e79565b9150509250929050565b61471c81614451565b8114614726575f80fd5b50565b5f8135905061473781614713565b92915050565b5f6020828403121561475257614751613e2b565b5b5f61475f84828501614729565b91505092915050565b7f4a75646765206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f61479c601083613fd0565b91506147a782614768565b602082019050919050565b5f6020820190508181035f8301526147c981614790565b9050919050565b7f4e6f7420656c696769626c6500000000000000000000000000000000000000005f82015250565b5f614804600c83613fd0565b915061480f826147d0565b602082019050919050565b5f6020820190508181035f830152614831816147f8565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61486f82614070565b915061487a83614070565b9250828201905061ffff81111561489457614893614838565b5b92915050565b7f4d617820737570706c79206a75646765206578636565640000000000000000005f82015250565b5f6148ce601783613fd0565b91506148d98261489a565b602082019050919050565b5f6020820190508181035f8301526148fb816148c2565b9050919050565b5f6040820190506149155f830185614169565b614922602083018461407d565b9392505050565b5f61493382614070565b915061ffff820361494757614946614838565b5b600182019050919050565b5f61495c82613eb8565b915061496783613eb8565b9250828203905060ff8111156149805761497f614838565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806149ca57607f821691505b6020821081036149dd576149dc614986565b5b50919050565b5f6149ed826140a5565b91506149f8836140a5565b9250828203905081811115614a1057614a0f614838565b5b92915050565b7f4e6f7420656e6f75676820636c61696d61626c6520746f6b656e7300000000005f82015250565b5f614a4a601b83613fd0565b9150614a5582614a16565b602082019050919050565b5f6020820190508181035f830152614a7781614a3e565b9050919050565b5f614a88826140a5565b9150614a93836140a5565b9250828201905080821115614aab57614aaa614838565b5b92915050565b7f537570706c79206c696d697420657863656564000000000000000000000000005f82015250565b5f614ae5601383613fd0565b9150614af082614ab1565b602082019050919050565b5f6020820190508181035f830152614b1281614ad9565b9050919050565b5f614b2382613eb8565b9150614b2e83613eb8565b9250828201905060ff811115614b4757614b46614838565b5b92915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614ba97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614b6e565b614bb38683614b6e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f614bee614be9614be4846140a5565b614bcb565b6140a5565b9050919050565b5f819050919050565b614c0783614bd4565b614c1b614c1382614bf5565b848454614b7a565b825550505050565b5f90565b614c2f614c23565b614c3a818484614bfe565b505050565b5b81811015614c5d57614c525f82614c27565b600181019050614c40565b5050565b601f821115614ca257614c7381614b4d565b614c7c84614b5f565b81016020851015614c8b578190505b614c9f614c9785614b5f565b830182614c3f565b50505b505050565b5f82821c905092915050565b5f614cc25f1984600802614ca7565b1980831691505092915050565b5f614cda8383614cb3565b9150826002028217905092915050565b614cf382613fc6565b67ffffffffffffffff811115614d0c57614d0b61423e565b5b614d1682546149b3565b614d21828285614c61565b5f60209050601f831160018114614d52575f8415614d40578287015190505b614d4a8582614ccf565b865550614db1565b601f198416614d6086614b4d565b5f5b82811015614d8757848901518255600182019150602085019450602081019050614d62565b86831015614da45784890151614da0601f891682614cb3565b8355505b6001600288020188555050505b505050505050565b7f477561726469616e206d696e7420636c6f7365000000000000000000000000005f82015250565b5f614ded601383613fd0565b9150614df882614db9565b602082019050919050565b5f6020820190508181035f830152614e1a81614de1565b9050919050565b7f4e6f2067697665776179000000000000000000000000000000000000000000005f82015250565b5f614e55600a83613fd0565b9150614e6082614e21565b602082019050919050565b5f6020820190508181035f830152614e8281614e49565b9050919050565b7f4d617820737570706c7920677561726469616e206578636565640000000000005f82015250565b5f614ebd601a83613fd0565b9150614ec882614e89565b602082019050919050565b5f6020820190508181035f830152614eea81614eb1565b9050919050565b7f5768616c65206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f614f25601083613fd0565b9150614f3082614ef1565b602082019050919050565b5f6020820190508181035f830152614f5281614f19565b9050919050565b7f4d617820737570706c79207768616c65206578636565640000000000000000005f82015250565b5f614f8d601783613fd0565b9150614f9882614f59565b602082019050919050565b5f6020820190508181035f830152614fba81614f81565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61502081614070565b82525050565b5f6150318383615017565b60208301905092915050565b5f602082019050919050565b5f61505382614fee565b61505d8185614ff8565b935061506883615008565b805f5b8381101561509857815161507f8882615026565b975061508a8361503d565b92505060018101905061506b565b5085935050505092915050565b5f6040820190506150b85f830185614169565b81810360208301526150ca8184615049565b90509392505050565b7f486f6e6f72617279206d696e7420636c6f7365000000000000000000000000005f82015250565b5f615107601383613fd0565b9150615112826150d3565b602082019050919050565b5f6020820190508181035f830152615134816150fb565b9050919050565b7f4d617820737570706c7920686f6e6f72617279206578636565640000000000005f82015250565b5f61516f601a83613fd0565b915061517a8261513b565b602082019050919050565b5f6020820190508181035f83015261519c81615163565b9050919050565b7f4e62206164647265737320616e64206e62207175616e746974696573206d75735f8201527f7420626520657175616c00000000000000000000000000000000000000000000602082015250565b5f6151fd602a83613fd0565b9150615208826151a3565b604082019050919050565b5f6020820190508181035f83015261522a816151f1565b9050919050565b7f436f756e63696c206d696e7420636c6f736500000000000000000000000000005f82015250565b5f615265601283613fd0565b915061527082615231565b602082019050919050565b5f6020820190508181035f83015261529281615259565b9050919050565b7f4d617820737570706c7920636f756e63696c20657863656564000000000000005f82015250565b5f6152cd601983613fd0565b91506152d882615299565b602082019050919050565b5f6020820190508181035f8301526152fa816152c1565b9050919050565b7f756e6b6e6f7720746f6b656e00000000000000000000000000000000000000005f82015250565b5f615335600c83613fd0565b915061534082615301565b602082019050919050565b5f6020820190508181035f83015261536281615329565b9050919050565b5f81905092915050565b5f61537d82613fc6565b6153878185615369565b9350615397818560208601613fe0565b80840191505092915050565b5f6153ae8285615373565b91506153ba8284615373565b91508190509392505050565b5f819050919050565b6153e06153db826140a5565b6153c6565b82525050565b5f6153f182856153cf565b60208201915061540182846153cf565b6020820191508190509392505050565b5f61541b826140a5565b91505f820361542d5761542c614838565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61546f8261469e565b915061547a8361469e565b9250828201905063ffffffff81111561549657615495614838565b5b9291505056fea2646970667358221220e90b78fd1e48f9522ce04e38979dd9b18bffed2f6a6e775afd6152c433fa750964736f6c63430008170033

Deployed Bytecode Sourcemap

123205:10171:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124464:56;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;41940:383;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131766:500;;;;;;;;;;;;;:::i;:::-;;126696:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119787:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123379:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34991:553;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35847:121;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;127218:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119665:114;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123832:44;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123622:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37675:3015;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124866:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;123883:71;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127783:464;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126345:166;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125528:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126154:183;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125058:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;130995:534;;;;;;;;;;;;;:::i;:::-;;40764:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123419:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126876:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127047;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124262:55;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;33819:341;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123539:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123308:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34310:541;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23319:103;;;;;;;;;;;;;:::i;:::-;;132546:827;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;130760:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123748:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125290:108;;;:::i;:::-;;129888:864;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126519:169;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123336:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22644:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123961:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123579:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123501:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119895:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;129500:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36595:713;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123460:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127398:377;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;128255:378;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;41482:244;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;131537:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;128641:851;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;125748:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126041:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119406:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119367:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;132274:264;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120007:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124668:56;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;124083:54;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;36062:389;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123665:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23577:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;125406:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123708:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124464:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;41940:383::-;42016:11;42126;42121:3;42117:21;42293:10;42290:1;42287:17;42273:10;42270:1;42267:17;42254:10;42251:1;42248:17;42245:40;42242:63;42232:73;;42093:223;41940:383;;;:::o;131766:500::-;131833:16;;131815:15;:34;131807:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;131918:1;131889:26;131904:10;131889:14;:26::i;:::-;:30;;;131881:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;131976:14;;;;;;;;;;;131955:35;;131971:1;131955:13;;;;;;;;;;;:17;;;;:::i;:::-;:35;;;;131947:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;132066:1;132029:14;:26;132044:10;132029:26;;;;;;;;;;;;;;;:34;;;:38;;;;;;;;;;;;;;;;;;132078:43;132088:10;132100:20;;;;;;;;;;;132078:43;;:9;:43::i;:::-;132149:10;132137:62;;;132161:15;132178:20;;;;;;;;;;;132137:62;;;;;;;:::i;:::-;;;;;;;;132210:20;;:22;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;132243:13;;:15;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;131766:500::o;126696:172::-;126768:5;126827:17;:25;126845:6;126827:25;;;;;;;;;;;;;;;:33;;;;;;;;;;;;126793:17;:25;126811:6;126793:25;;;;;;;;;;;;;;;:31;;;;;;;;;;;;:67;;;;:::i;:::-;126786:74;;126696:172;;;:::o;119787:100::-;119841:13;119874:5;119867:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119787:100;:::o;123379:33::-;;;;;;;;;;;;;:::o;34991:553::-;35053:14;35161:2;35155:4;35148:16;35191:24;35185:4;35178:38;35283:4;35277;35267:21;35263:2;35259:30;35255:2;35251:39;35336:13;35330:20;35326:2;35322:29;35318:2;35314:38;35304:170;;35386:10;35380:4;35373:24;35454:4;35448;35441:18;35304:170;35511:13;35508:1;35504:21;35498:28;35488:38;;35133:404;34991:553;;;:::o;35847:121::-;35927:33;35936:10;35948:7;35957:2;35927:8;:33::i;:::-;35847:121;;:::o;127218:172::-;127290:5;127349:17;:25;127367:6;127349:25;;;;;;;;;;;;;;;:33;;;;;;;;;;;;127315:17;:25;127333:6;127315:25;;;;;;;;;;;;;;;:31;;;;;;;;;;;;:67;;;;:::i;:::-;127308:74;;127218:172;;;:::o;119665:114::-;119717:7;119756:15;;119744:9;:27;;;;:::i;:::-;119737:34;;119665:114;:::o;123832:44::-;;;;:::o;123622:36::-;;;;;;;;;;;;;:::o;37675:3015::-;37769:34;37790:4;37796:2;37800;37769:20;:34::i;:::-;37953:1;37949:6;37945:2;37941:15;37998:4;37982:14;37978:25;37970:33;;38043:2;38027:14;38023:23;38017:29;;38110:2;38104:4;38097:16;38169:8;38143:24;38140:38;38134:4;38127:52;38246:4;38240;38230:21;38226:2;38222:30;38218:2;38214:39;38296:13;38290:20;38357:15;38341:14;38337:36;38484:4;38477:5;38474:15;38467:5;38463:27;38453:335;;38521:5;38511:149;;38564:10;38558:4;38551:24;38636:4;38630;38623:18;38511:149;38691:10;38685:4;38678:24;38768:4;38762;38755:18;38453:335;38860:2;38850:138;;38896:10;38890:4;38883:24;38968:4;38962;38955:18;38850:138;39090:4;39084;39077:18;39149:13;39146:1;39142:21;39136:28;39297:15;39287:8;39284:29;39277:4;39267:8;39264:18;39261:53;39251:293;;39371:4;39365;39355:21;39349:28;39339:186;;39419:10;39413:4;39406:24;39497:4;39491;39484:18;39339:186;39251:293;39617:15;39614:55;;;39665:1;39649:13;39646:1;39642:21;39635:32;39614:55;39058:626;39790:2;39784:4;39780:13;39763:15;39759:35;39744:13;39737:58;39912:4;39906;39896:21;39987:1;39969:15;39963:22;39959:30;39942:15;39935:55;39854:151;40094:2;40088:4;40081:16;40152:4;40146;40136:21;40228:1;40212:13;40206:20;40202:28;40283:20;40262:19;40258:46;40248:195;;40342:10;40336:4;40329:24;40419:4;40413;40406:18;40248:195;40483:19;40468:13;40461:42;40062:456;;40625:2;40621;40615:4;40588:25;40582:4;40576;40571:57;37867:2772;;;;40649:33;40669:4;40675:2;40679;40649:19;:33::i;:::-;37675:3015;;;:::o;124866:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;123883:71::-;;;;;;;;;;;;;:::o;127783:464::-;127880:1;127850:27;127866:10;127850:15;:27::i;:::-;:31;;;127842:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;127948:11;127917:42;;:27;127933:10;127917:15;:27::i;:::-;:42;;;;127909:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;128039:11;128023:27;;:13;:11;:13::i;:::-;:27;;;;:::i;:::-;128010:9;:40;;128002:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;128124:11;128085:15;:27;128101:10;128085:27;;;;;;;;;;;;;;;:35;;;:50;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;128146:36;128158:10;128170:11;128146:36;;:11;:36::i;:::-;128211:10;128198:41;;;128223:15;128198:41;;;;;;:::i;:::-;;;;;;;;127783:464;:::o;126345:166::-;126415:5;126472:15;:23;126488:6;126472:23;;;;;;;;;;;;;;;:31;;;;;;;;;;;;126440:15;:23;126456:6;126440:23;;;;;;;;;;;;;;;:29;;;;;;;;;;;;:63;;;;:::i;:::-;126433:70;;126345:166;;;:::o;125528:105::-;22530:13;:11;:13::i;:::-;125614:11:::1;125604:7;:21;;;;;;:::i;:::-;;125528:105:::0;:::o;126154:183::-;126202:7;126316:13;;;;;;;;;;;126228:101;;126300:13;;;;;;;;;;;126228:85;;126281:16;;;;;;;;;;;126228:69;;126262:16;;;;;;;;;;;126228:50;;126244:15;;;;;;;;;;;126228:31;;:13;:11;:13::i;:::-;:31;;;;:::i;:::-;:50;;;;:::i;:::-;:69;;;;:::i;:::-;:85;;;;:::i;:::-;:101;;;;:::i;:::-;126221:108;;126154:183;:::o;125058:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;130995:534::-;131065:16;;131047:15;:34;131039:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;131156:1;131124:29;131142:10;131124:17;:29::i;:::-;:33;;;131116:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;131215:17;;;;;;;;;;;131191:41;;131210:1;131191:16;;;;;;;;;;;:20;;;;:::i;:::-;:41;;;;131183:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;131314:1;131274:17;:29;131292:10;131274:29;;;;;;;;;;;;;;;:37;;;:41;;;;;;;;;;;;;;;;;;131326:46;131336:10;131348:23;;;;;;;;;;;131326:46;;:9;:46::i;:::-;131403:10;131388:68;;;131415:15;131432:23;;;;;;;;;;;131388:68;;;;;;;:::i;:::-;;;;;;;;131467:23;;:25;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;131503:16;;:18;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;130995:534::o;40764:201::-;40862:26;40875:4;40881:2;40885;40862:12;:26::i;:::-;40903:12;40912:2;40903:8;:12::i;:::-;40899:58;;;40917:40;40940:4;40946:2;40950;40917:40;;;;;;;;;;;;:22;:40::i;:::-;40899:58;40764:201;;;:::o;123419:34::-;;;;;;;;;;;;;:::o;126876:163::-;126945:5;127001:14;:22;127016:6;127001:22;;;;;;;;;;;;;;;:30;;;;;;;;;;;;126970:14;:22;126985:6;126970:22;;;;;;;;;;;;;;;:28;;;;;;;;;;;;:61;;;;:::i;:::-;126963:68;;126876:163;;;:::o;127047:::-;127116:5;127172:14;:22;127187:6;127172:22;;;;;;;;;;;;;;;:30;;;;;;;;;;;;127141:14;:22;127156:6;127141:22;;;;;;;;;;;;;;;:28;;;;;;;;;;;;:61;;;;:::i;:::-;127134:68;;127047:163;;;:::o;124262:55::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;33819:341::-;33877:14;33913:12;33922:2;33913:8;:12::i;:::-;33904:21;;34014:6;34004:138;;34054:10;34048:4;34041:24;34122:4;34116;34109:18;34004:138;33819:341;;;:::o;123539:31::-;;;;;;;;;;;;;:::o;123308:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;34310:541::-;34373:14;34533:5;34523:146;;34572:10;34566:4;34559:24;34649:4;34643;34636:18;34523:146;34696:24;34690:4;34683:38;34748:5;34742:4;34735:19;34812:20;34804:4;34798;34788:21;34782:28;34778:55;34768:65;;34310:541;;;:::o;23319:103::-;22530:13;:11;:13::i;:::-;23384:30:::1;23411:1;23384:18;:30::i;:::-;23319:103::o:0;132546:827::-;132630:16;;132612:15;:34;132604:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;132715:1;132686:26;132701:10;132686:14;:26::i;:::-;:30;;;132678:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;132782:11;132752:41;;:26;132767:10;132752:14;:26::i;:::-;:41;;;;132744:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;132875:16;;;;;;;;;;;132844:47;;132860:11;132844:27;;:13;;;;;;;;;;;:27;;;;:::i;:::-;:47;;;;132836:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;132930:31;132977:11;132964:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;132930:59;;133038:11;133000:14;:26;133015:10;133000:26;;;;;;;;;;;;;;;:34;;;:49;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;133065:7;133060:233;133082:11;133078:15;;:1;:15;;;133060:233;;;133115:43;133125:10;133137:20;;;;;;;;;;;133115:43;;:9;:43::i;:::-;133194:20;;;;;;;;;;;133173:15;133189:1;133173:18;;;;;;;;;;:::i;:::-;;;;;;;:41;;;;;;;;;;;133229:20;;:22;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;133266:13;;:15;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;133095:3;;;;;;;133060:233;;;;133320:10;133308:57;;;133332:15;133349;133308:57;;;;;;;:::i;:::-;;;;;;;;132593:780;132546:827;:::o;130760:227::-;22530:13;:11;:13::i;:::-;130861:6:::1;130856:124;130877:15;;:22;;130873:1;:26;130856:124;;;130967:1;130921:17;:37;130939:15;;130955:1;130939:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;130921:37;;;;;;;;;;;;;;;:43;;;:47;;;;;;;;;;;;;;;;;;130901:3;;;;;;;130856:124;;;;130760:227:::0;;:::o;123748:33::-;;;;;;;;;;;;;:::o;125290:108::-;22530:13;:11;:13::i;:::-;125349:9:::1;;;;;;;;;;;:18;;:41;125368:21;125349:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;125290:108::o:0;129888:864::-;129975:16;;129957:15;:34;129949:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;130066:1;130034:29;130052:10;130034:17;:29::i;:::-;:33;;;130026:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;130136:11;130103:44;;:29;130121:10;130103:17;:29::i;:::-;:44;;;;130095:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;130232:17;;;;;;;;;;;130198:51;;130217:11;130198:30;;:16;;;;;;;;;;;:30;;;;:::i;:::-;:51;;;;130190:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;130291:31;130338:11;130325:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;130291:59;;130402:11;130361:17;:29;130379:10;130361:29;;;;;;;;;;;;;;;:37;;;:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;130429:7;130424:245;130446:11;130442:15;;:1;:15;;;130424:245;;;130479:46;130489:10;130501:23;;;;;;;;;;;130479:46;;:9;:46::i;:::-;130561:23;;;;;;;;;;;130540:15;130556:1;130540:18;;;;;;;;;;:::i;:::-;;;;;;;:44;;;;;;;;;;;130599:23;;:25;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;130639:16;;:18;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;130459:3;;;;;;;130424:245;;;;130699:10;130684:60;;;130711:15;130728;130684:60;;;;;;;:::i;:::-;;;;;;;;129938:814;129888:864;:::o;126519:169::-;126590:5;126648:16;:24;126665:6;126648:24;;;;;;;;;;;;;;;:32;;;;;;;;;;;;126615:16;:24;126632:6;126615:24;;;;;;;;;;;;;;;:30;;;;;;;;;;;;:65;;;;:::i;:::-;126608:72;;126519:169;;;:::o;123336:34::-;;;;;;;;;;;;;:::o;22644:87::-;22690:7;22717:6;;;;;;;;;;;22710:13;;22644:87;:::o;123961:32::-;;;;;;;;;;;;;:::o;123579:36::-;;;;;;;;;;;;;:::o;123501:31::-;;;;;;;;;;;;;:::o;119895:104::-;119951:13;119984:7;119977:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119895:104;:::o;129500:380::-;22530:13;:11;:13::i;:::-;129660:11:::1;;:18;;129634:15;;:22;;:44;129626:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;129741:6;129736:137;129757:15;;:22;;129753:1;:26;129736:137;;;129847:11;;129859:1;129847:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;129801:17;:37;129819:15;;129835:1;129819:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;129801:37;;;;;;;;;;;;;;;:43;;;:60;;;;;;;;;;;;;;;;;;129781:3;;;;;;;129736:137;;;;129500:380:::0;;;;:::o;36595:713::-;36810:10;36803:18;36796:26;36782:40;;36917:8;36911:4;36904:22;36953:31;36947:4;36940:45;37012:8;37006:4;36999:22;37065:10;37058:4;37052;37042:21;37035:41;37148:10;37142:4;37135:24;37265:8;37261:2;37257:17;37253:2;37249:26;37239:8;37204:33;37198:4;37192;37173:117;36595:713;;:::o;123460:34::-;;;;;;;;;;;;;:::o;127398:377::-;22530:13;:11;:13::i;:::-;127556:11:::1;;:18;;127530:15;;:22;;:44;127522:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;127637:6;127632:136;127653:15;;:22;;127649:1;:26;127632:136;;;127742:11;;127754:1;127742:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;127697:15;:35;127713:15;;127729:1;127713:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;127697:35;;;;;;;;;;;;;;;:41;;;:59;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;127677:3;;;;;;;127632:136;;;;127398:377:::0;;;;:::o;128255:378::-;22530:13;:11;:13::i;:::-;128414:11:::1;;:18;;128388:15;;:22;;:44;128380:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;128495:6;128490:136;128511:15;;:22;;128507:1;:26;128490:136;;;128600:11;;128612:1;128600:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;128555:16;:36;128572:15;;128588:1;128572:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;128555:36;;;;;;;;;;;;;;;:42;;;:59;;;;;;;;;;;;;;;;;;128535:3;;;;;;;128490:136;;;;128255:378:::0;;;;:::o;41482:244::-;41621:26;41634:4;41640:2;41644;41621:12;:26::i;:::-;41662:12;41671:2;41662:8;:12::i;:::-;41658:60;;;41676:42;41699:4;41705:2;41709;41713:4;;41676:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;:42::i;:::-;41658:60;41482:244;;;;;:::o;131537:221::-;22530:13;:11;:13::i;:::-;131635:6:::1;131630:121;131651:15;;:22;;131647:1;:26;131630:121;;;131738:1;131695:14;:34;131710:15;;131726:1;131710:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;131695:34;;;;;;;;;;;;;;;:40;;;:44;;;;;;;;;;;;;;;;;;131675:3;;;;;;;131630:121;;;;131537:221:::0;;:::o;128641:851::-;128727:16;;128709:15;:34;128701:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;128816:1;128785:28;128802:10;128785:16;:28::i;:::-;:32;;;128777:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;128885:11;128853:43;;:28;128870:10;128853:16;:28::i;:::-;:43;;;;128845:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;128980:16;;;;;;;;;;;128947:49;;128965:11;128947:29;;:15;;;;;;;;;;;:29;;;;:::i;:::-;:49;;;;128939:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;129037:31;129084:11;129071:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129037:59;;129147:11;129107:16;:28;129124:10;129107:28;;;;;;;;;;;;;;;:36;;;:51;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;129174:7;129169:241;129191:11;129187:15;;:1;:15;;;129169:241;;;129224:45;129234:10;129246:22;;;;;;;;;;;129224:45;;:9;:45::i;:::-;129305:22;;;;;;;;;;;129284:15;129300:1;129284:18;;;;;;;;;;:::i;:::-;;;;;;;:43;;;;;;;;;;;129342:22;;:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;129381:15;;:17;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;129204:3;;;;;;;129169:241;;;;129439:10;129425:59;;;129451:15;129468;129425:59;;;;;;;:::i;:::-;;;;;;;;128690:802;128641:851;:::o;125748:285::-;125821:13;125855:16;125863:7;125855;:16::i;:::-;125847:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;125899:17;125919:10;:8;:10::i;:::-;125899:30;;125967:1;125953:3;125947:17;:21;:78;;;;;;;;;;;;;;;;;125995:3;126000:18;:7;:16;:18::i;:::-;125978:41;;;;;;;;;:::i;:::-;;;;;;;;;;;;;125947:78;125940:85;;;125748:285;;;:::o;126041:105::-;126098:4;126122:16;126130:7;126122;:16::i;:::-;126115:23;;126041:105;;;:::o;119406:34::-;;;:::o;119367:30::-;;;;:::o;132274:264::-;22530:13;:11;:13::i;:::-;132402:6:::1;132397:134;132418:15;;:22;;132414:1;:26;132397:134;;;132505:11;;132517:1;132505:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;132462;:34;132477:15;;132493:1;132477:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;132462:34;;;;;;;;;;;;;;;:40;;;:57;;;;;;;;;;;;;;;;;;132442:3;;;;;;;132397:134;;;;132274:264:::0;;;;:::o;120007:138::-;120074:6;120133:3;120107:22;120122:6;120107:14;:22::i;:::-;:29;;;;120093:44;;120007:138;;;:::o;124668:56::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;124083:54::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;36062:389::-;36170:11;36280:8;36274:4;36267:22;36316:31;36310:4;36303:45;36375:5;36369:4;36362:19;36427:4;36421;36411:21;36405:28;36395:38;;36062:389;;;;:::o;123665:36::-;;;;;;;;;;;;;:::o;23577:220::-;22530:13;:11;:13::i;:::-;23682:1:::1;23662:22;;:8;:22;;::::0;23658:93:::1;;23736:1;23708:31;;;;;;;;;;;:::i;:::-;;;;;;;;23658:93;23761:28;23780:8;23761:18;:28::i;:::-;23577:220:::0;:::o;125406:114::-;22530:13;:11;:13::i;:::-;125499::::1;125487:9;;:25;;;;;;;;;;;;;;;;;;125406:114:::0;:::o;123708:33::-;;;;;;;;;;;;;:::o;48390:100::-;48461:21;48471:2;48475;48461:21;;;;;;;;;;;;:9;:21::i;:::-;48390:100;;:::o;54490:1438::-;54672:1;54668:6;54664:2;54660:15;54720:7;54704:14;54700:28;54689:39;;54768:2;54752:14;54748:23;54742:29;;54839:2;54833:4;54826:16;54898:2;54872:24;54869:32;54863:4;54856:46;54969:4;54963;54953:21;54949:2;54945:30;54941:2;54937:39;55029:13;55023:20;55007:14;55003:41;55116:5;55106:137;;55155:10;55149:4;55142:24;55223:4;55217;55210:18;55106:137;55421:5;55417:2;55414:13;55409:2;55402:10;55399:29;55389:286;;55462:5;55456:4;55449:19;55518:4;55512;55502:21;55496:28;55486:174;;55562:10;55556:4;55549:24;55636:4;55630;55623:18;55486:174;55389:286;55786:7;55770:13;55767:1;55763:21;55756:38;55907:2;55898:7;55891:5;55864:25;55858:4;55852;55847:63;54586:1335;;;54490:1438;;;:::o;63240:87::-;;;;:::o;63427:86::-;;;;:::o;120153:939::-;120252:9;120238:23;;:10;:23;;;120234:57;;120270:21;;;;;;;;;;;;;;120234:57;120320:1;120306:10;:15;120302:53;;120330:25;;;;;;;;;;;;;;120302:53;120388:10;120370:15;;:28;120366:67;;;120407:26;;;;;;;;;;;;;;120366:67;120446:24;120473:109;;;;;;;;120535:15;120552:16;120504:75;;;;;;;;;:::i;:::-;;;;;;;;;;;;;120494:86;;;;;;120486:95;;120473:109;;;120446:136;;120595:30;120628:15;;120595:48;;120661:9;120656:319;120676:10;120672:1;:14;120656:319;;;120705:19;120727:36;120740:22;120727:4;:12;;:36;;;;:::i;:::-;120705:58;;120780:15;120798:61;120823:11;120836:22;120798:24;:61::i;:::-;120780:79;;120876:18;120882:2;120886:7;120876:5;:18::i;:::-;120911:24;;;;:::i;:::-;;;120959:3;;;;;120690:285;;120656:319;;;;120987:46;121010:2;121021:10;120987:22;:46::i;:::-;121062:22;121044:15;:40;;;;120223:869;;120153:939;;:::o;22809:166::-;22880:12;:10;:12::i;:::-;22869:23;;:7;:5;:7::i;:::-;:23;;;22865:103;;22943:12;:10;:12::i;:::-;22916:40;;;;;;;;;;;:::i;:::-;;;;;;;;22865:103;22809:166::o;63870:217::-;63921:11;64035:1;64023:14;64013:24;;63870:217;;;:::o;64250:1416::-;64485:4;64479:11;64536:10;64570:24;64567:1;64560:35;64630:8;64623:4;64620:1;64616:12;64609:30;64739:4;64735:2;64731:13;64727:2;64723:22;64716:4;64713:1;64709:12;64702:44;64781:2;64774:4;64771:1;64767:12;64760:24;64819:4;64812;64809:1;64805:12;64798:26;64853:4;64847:11;64893:1;64886:4;64883:1;64879:12;64872:23;64912:1;64909:71;;;64975:1;64968:4;64965:1;64961:12;64958:1;64951:4;64945;64941:15;64938:1;64931:5;64920:57;64916:62;64909:71;65094:4;65091:1;65084:4;65081:1;65077:12;65070:4;65067:1;65063:12;65060:1;65056:2;65049:5;65044:55;65034:351;;65123:16;65120:220;;;65252:16;65246:4;65240;65225:44;65304:16;65298:4;65291:30;65120:220;65368:1;65365;65358:12;65034:351;65479:24;65474:3;65470:34;65466:1;65460:8;65457:48;65447:201;;65539:10;65533:4;65526:24;65628:4;65622;65615:18;65447:201;64421:1238;;;64250:1416;;;;:::o;43118:330::-;43179:14;43287:2;43281:4;43274:16;43317:24;43311:4;43304:38;43420:4;43414;43404:21;43400:2;43396:30;43392:2;43388:39;43382:46;43378:2;43374:55;43370:2;43366:64;43356:74;;43118:330;;;:::o;23957:191::-;24031:16;24050:6;;;;;;;;;;;24031:25;;24076:8;24067:6;;:17;;;;;;;;;;;;;;;;;;24131:8;24100:40;;24121:8;24100:40;;;;;;;;;;;;24020:128;23957:191;:::o;42662:317::-;42722:11;42827:2;42821:4;42814:16;42857:24;42851:4;42844:38;42952:4;42946;42936:21;42932:2;42928:30;42924:2;42920:39;42914:46;42910:2;42906:55;42896:65;;42662:317;;;:::o;125641:99::-;125692:13;125725:7;125718:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;125641:99;:::o;17528:718::-;17584:13;17635:14;17672:1;17652:17;17663:5;17652:10;:17::i;:::-;:21;17635:38;;17688:20;17722:6;17711:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17688:41;;17744:11;17873:6;17869:2;17865:15;17857:6;17853:28;17846:35;;17910:290;17917:4;17910:290;;;17942:5;;;;;;;;18084:10;18079:2;18072:5;18068:14;18063:32;18058:3;18050:46;18142:2;18133:11;;;;;;:::i;:::-;;;;;18176:1;18167:5;:10;17910:290;18163:21;17910:290;18221:6;18214:13;;;;;17528:718;;;:::o;43984:308::-;44047:14;44155:24;44149:4;44142:38;44207:5;44201:4;44194:19;44267:4;44261;44251:21;44245:28;44241:2;44237:37;44227:47;;43984:308;;;:::o;48855:188::-;48945:13;48951:2;48955;48945:5;:13::i;:::-;48973:12;48982:2;48973:8;:12::i;:::-;48969:66;;;48987:48;49018:1;49022:2;49026;49030:4;48987:22;:48::i;:::-;48969:66;48855:188;;;:::o;68123:419::-;68196:14;68291:191;68298:1;68291:191;;;68348:4;68342;68332:21;68322:31;;68384:6;68378:4;68371:20;68449:5;68441;68438:1;68434:13;68430:25;68422:6;68419:37;68291:191;68409:58;68291:191;68518:5;68510:6;68506:18;68496:28;;68123:419;;;;:::o;121662:636::-;121778:14;121810:18;121831:16;:28;121848:10;121831:28;;;;;;;;;;;;121810:49;;121870:17;121918:1;121890:25;:29;;;;:::i;:::-;121870:49;;121930:22;121955:16;:27;121972:9;121955:27;;;;;;;;;;;;121930:52;;122018:1;122004:10;:15;:41;;122035:10;122004:41;;;122022:10;122004:41;121995:50;;122076:9;122062:10;:23;122058:135;;122151:1;122133:14;:19;:48;;122167:14;122133:48;;;122155:9;122133:48;122102:16;:28;122119:10;122102:28;;;;;;;;;;;:79;;;;122058:135;122227:1;122209:14;:19;122205:86;;122252:16;:27;122269:9;122252:27;;;;;;;;;;;122245:34;;;122205:86;121799:499;;;121662:636;;;;:::o;46643:1686::-;46710:40;46739:1;46743:2;46747;46710:20;:40::i;:::-;46888:2;46884;46880:11;46876:2;46872:20;46866:26;;46964:2;46954:138;;47000:10;46994:4;46987:24;47072:4;47066;47059:18;46954:138;47156:2;47150:4;47143:16;47186:24;47180:4;47173:38;47278:4;47272;47262:21;47258:2;47254:30;47250:2;47246:39;47328:13;47322:20;47415:15;47411:2;47407:24;47404:149;;;47464:10;47458:4;47451:24;47533:4;47527;47520:18;47404:149;47644:2;47627:15;47624:23;47609:13;47602:46;47742:2;47736:4;47729:16;47798:4;47792;47782:21;47870:1;47856:11;47850:18;47846:26;47923:20;47904:17;47900:44;47890:193;;47982:10;47976:4;47969:24;48059:4;48053;48046:18;47890:193;48121:17;48108:11;48101:38;47710:444;;48258:2;48254;48251:1;48224:25;48218:4;48212;48207:54;46814:1458;;48282:39;48310:1;48314:2;48318;48282:19;:39::i;:::-;46643:1686;;:::o;122729:390::-;122813:16;122832:20;122845:6;122832:12;:20::i;:::-;122813:39;;122863:23;122908:8;122889:9;:28;;;;:::i;:::-;122863:54;;122928:15;122946:22;122961:6;122946:14;:22::i;:::-;122928:40;;122981:130;123010:6;123091:7;123075:25;;123068:3;123047:16;123039:25;;:32;;123031:69;122981:14;:130::i;:::-;122802:317;;;122729:390;;:::o;20760:98::-;20813:7;20840:10;20833:17;;20760:98;:::o;12590:948::-;12643:7;12663:14;12680:1;12663:18;;12730:8;12721:5;:17;12717:106;;12768:8;12759:17;;;;;;:::i;:::-;;;;;12805:2;12795:12;;;;12717:106;12850:8;12841:5;:17;12837:106;;12888:8;12879:17;;;;;;:::i;:::-;;;;;12925:2;12915:12;;;;12837:106;12970:8;12961:5;:17;12957:106;;13008:8;12999:17;;;;;;:::i;:::-;;;;;13045:2;13035:12;;;;12957:106;13090:7;13081:5;:16;13077:103;;13127:7;13118:16;;;;;;:::i;:::-;;;;;13163:1;13153:11;;;;13077:103;13207:7;13198:5;:16;13194:103;;13244:7;13235:16;;;;;;:::i;:::-;;;;;13280:1;13270:11;;;;13194:103;13324:7;13315:5;:16;13311:103;;13361:7;13352:16;;;;;;:::i;:::-;;;;;13397:1;13387:11;;;;13311:103;13441:7;13432:5;:16;13428:68;;13479:1;13469:11;;;;13428:68;13524:6;13517:13;;;12590:948;;;:::o;44548:416::-;44704:24;44698:4;44691:38;44756:5;44750:4;44743:19;44811:4;44805;44795:21;44850:11;44844:18;44935:6;44931:2;44927:15;44920:5;44916:27;44912:2;44908:36;44900:6;44896:49;44883:11;44876:70;44676:281;;44548:416;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:329::-;900:6;949:2;937:9;928:7;924:23;920:32;917:119;;;955:79;;:::i;:::-;917:119;1075:1;1100:53;1145:7;1136:6;1125:9;1121:22;1100:53;:::i;:::-;1090:63;;1046:117;841:329;;;;:::o;1176:86::-;1211:7;1251:4;1244:5;1240:16;1229:27;;1176:86;;;:::o;1268:112::-;1351:22;1367:5;1351:22;:::i;:::-;1346:3;1339:35;1268:112;;:::o;1386:316::-;1499:4;1537:2;1526:9;1522:18;1514:26;;1550:67;1614:1;1603:9;1599:17;1590:6;1550:67;:::i;:::-;1627:68;1691:2;1680:9;1676:18;1667:6;1627:68;:::i;:::-;1386:316;;;;;:::o;1708:149::-;1744:7;1784:66;1777:5;1773:78;1762:89;;1708:149;;;:::o;1863:120::-;1935:23;1952:5;1935:23;:::i;:::-;1928:5;1925:34;1915:62;;1973:1;1970;1963:12;1915:62;1863:120;:::o;1989:137::-;2034:5;2072:6;2059:20;2050:29;;2088:32;2114:5;2088:32;:::i;:::-;1989:137;;;;:::o;2132:327::-;2190:6;2239:2;2227:9;2218:7;2214:23;2210:32;2207:119;;;2245:79;;:::i;:::-;2207:119;2365:1;2390:52;2434:7;2425:6;2414:9;2410:22;2390:52;:::i;:::-;2380:62;;2336:116;2132:327;;;;:::o;2465:90::-;2499:7;2542:5;2535:13;2528:21;2517:32;;2465:90;;;:::o;2561:109::-;2642:21;2657:5;2642:21;:::i;:::-;2637:3;2630:34;2561:109;;:::o;2676:210::-;2763:4;2801:2;2790:9;2786:18;2778:26;;2814:65;2876:1;2865:9;2861:17;2852:6;2814:65;:::i;:::-;2676:210;;;;:::o;2892:214::-;2981:4;3019:2;3008:9;3004:18;2996:26;;3032:67;3096:1;3085:9;3081:17;3072:6;3032:67;:::i;:::-;2892:214;;;;:::o;3112:99::-;3164:6;3198:5;3192:12;3182:22;;3112:99;;;:::o;3217:169::-;3301:11;3335:6;3330:3;3323:19;3375:4;3370:3;3366:14;3351:29;;3217:169;;;;:::o;3392:246::-;3473:1;3483:113;3497:6;3494:1;3491:13;3483:113;;;3582:1;3577:3;3573:11;3567:18;3563:1;3558:3;3554:11;3547:39;3519:2;3516:1;3512:10;3507:15;;3483:113;;;3630:1;3621:6;3616:3;3612:16;3605:27;3454:184;3392:246;;;:::o;3644:102::-;3685:6;3736:2;3732:7;3727:2;3720:5;3716:14;3712:28;3702:38;;3644:102;;;:::o;3752:377::-;3840:3;3868:39;3901:5;3868:39;:::i;:::-;3923:71;3987:6;3982:3;3923:71;:::i;:::-;3916:78;;4003:65;4061:6;4056:3;4049:4;4042:5;4038:16;4003:65;:::i;:::-;4093:29;4115:6;4093:29;:::i;:::-;4088:3;4084:39;4077:46;;3844:285;3752:377;;;;:::o;4135:313::-;4248:4;4286:2;4275:9;4271:18;4263:26;;4335:9;4329:4;4325:20;4321:1;4310:9;4306:17;4299:47;4363:78;4436:4;4427:6;4363:78;:::i;:::-;4355:86;;4135:313;;;;:::o;4454:89::-;4490:7;4530:6;4523:5;4519:18;4508:29;;4454:89;;;:::o;4549:115::-;4634:23;4651:5;4634:23;:::i;:::-;4629:3;4622:36;4549:115;;:::o;4670:218::-;4761:4;4799:2;4788:9;4784:18;4776:26;;4812:69;4878:1;4867:9;4863:17;4854:6;4812:69;:::i;:::-;4670:218;;;;:::o;4894:77::-;4931:7;4960:5;4949:16;;4894:77;;;:::o;4977:122::-;5050:24;5068:5;5050:24;:::i;:::-;5043:5;5040:35;5030:63;;5089:1;5086;5079:12;5030:63;4977:122;:::o;5105:139::-;5151:5;5189:6;5176:20;5167:29;;5205:33;5232:5;5205:33;:::i;:::-;5105:139;;;;:::o;5250:329::-;5309:6;5358:2;5346:9;5337:7;5333:23;5329:32;5326:119;;;5364:79;;:::i;:::-;5326:119;5484:1;5509:53;5554:7;5545:6;5534:9;5530:22;5509:53;:::i;:::-;5499:63;;5455:117;5250:329;;;;:::o;5585:118::-;5672:24;5690:5;5672:24;:::i;:::-;5667:3;5660:37;5585:118;;:::o;5709:222::-;5802:4;5840:2;5829:9;5825:18;5817:26;;5853:71;5921:1;5910:9;5906:17;5897:6;5853:71;:::i;:::-;5709:222;;;;:::o;5937:474::-;6005:6;6013;6062:2;6050:9;6041:7;6037:23;6033:32;6030:119;;;6068:79;;:::i;:::-;6030:119;6188:1;6213:53;6258:7;6249:6;6238:9;6234:22;6213:53;:::i;:::-;6203:63;;6159:117;6315:2;6341:53;6386:7;6377:6;6366:9;6362:22;6341:53;:::i;:::-;6331:63;;6286:118;5937:474;;;;;:::o;6417:118::-;6504:24;6522:5;6504:24;:::i;:::-;6499:3;6492:37;6417:118;;:::o;6541:222::-;6634:4;6672:2;6661:9;6657:18;6649:26;;6685:71;6753:1;6742:9;6738:17;6729:6;6685:71;:::i;:::-;6541:222;;;;:::o;6769:619::-;6846:6;6854;6862;6911:2;6899:9;6890:7;6886:23;6882:32;6879:119;;;6917:79;;:::i;:::-;6879:119;7037:1;7062:53;7107:7;7098:6;7087:9;7083:22;7062:53;:::i;:::-;7052:63;;7008:117;7164:2;7190:53;7235:7;7226:6;7215:9;7211:22;7190:53;:::i;:::-;7180:63;;7135:118;7292:2;7318:53;7363:7;7354:6;7343:9;7339:22;7318:53;:::i;:::-;7308:63;;7263:118;6769:619;;;;;:::o;7394:118::-;7465:22;7481:5;7465:22;:::i;:::-;7458:5;7455:33;7445:61;;7502:1;7499;7492:12;7445:61;7394:118;:::o;7518:135::-;7562:5;7600:6;7587:20;7578:29;;7616:31;7641:5;7616:31;:::i;:::-;7518:135;;;;:::o;7659:325::-;7716:6;7765:2;7753:9;7744:7;7740:23;7736:32;7733:119;;;7771:79;;:::i;:::-;7733:119;7891:1;7916:51;7959:7;7950:6;7939:9;7935:22;7916:51;:::i;:::-;7906:61;;7862:115;7659:325;;;;:::o;7990:117::-;8099:1;8096;8089:12;8113:117;8222:1;8219;8212:12;8236:180;8284:77;8281:1;8274:88;8381:4;8378:1;8371:15;8405:4;8402:1;8395:15;8422:281;8505:27;8527:4;8505:27;:::i;:::-;8497:6;8493:40;8635:6;8623:10;8620:22;8599:18;8587:10;8584:34;8581:62;8578:88;;;8646:18;;:::i;:::-;8578:88;8686:10;8682:2;8675:22;8465:238;8422:281;;:::o;8709:129::-;8743:6;8770:20;;:::i;:::-;8760:30;;8799:33;8827:4;8819:6;8799:33;:::i;:::-;8709:129;;;:::o;8844:308::-;8906:4;8996:18;8988:6;8985:30;8982:56;;;9018:18;;:::i;:::-;8982:56;9056:29;9078:6;9056:29;:::i;:::-;9048:37;;9140:4;9134;9130:15;9122:23;;8844:308;;;:::o;9158:146::-;9255:6;9250:3;9245;9232:30;9296:1;9287:6;9282:3;9278:16;9271:27;9158:146;;;:::o;9310:425::-;9388:5;9413:66;9429:49;9471:6;9429:49;:::i;:::-;9413:66;:::i;:::-;9404:75;;9502:6;9495:5;9488:21;9540:4;9533:5;9529:16;9578:3;9569:6;9564:3;9560:16;9557:25;9554:112;;;9585:79;;:::i;:::-;9554:112;9675:54;9722:6;9717:3;9712;9675:54;:::i;:::-;9394:341;9310:425;;;;;:::o;9755:340::-;9811:5;9860:3;9853:4;9845:6;9841:17;9837:27;9827:122;;9868:79;;:::i;:::-;9827:122;9985:6;9972:20;10010:79;10085:3;10077:6;10070:4;10062:6;10058:17;10010:79;:::i;:::-;10001:88;;9817:278;9755:340;;;;:::o;10101:509::-;10170:6;10219:2;10207:9;10198:7;10194:23;10190:32;10187:119;;;10225:79;;:::i;:::-;10187:119;10373:1;10362:9;10358:17;10345:31;10403:18;10395:6;10392:30;10389:117;;;10425:79;;:::i;:::-;10389:117;10530:63;10585:7;10576:6;10565:9;10561:22;10530:63;:::i;:::-;10520:73;;10316:287;10101:509;;;;:::o;10616:117::-;10725:1;10722;10715:12;10739:117;10848:1;10845;10838:12;10879:568;10952:8;10962:6;11012:3;11005:4;10997:6;10993:17;10989:27;10979:122;;11020:79;;:::i;:::-;10979:122;11133:6;11120:20;11110:30;;11163:18;11155:6;11152:30;11149:117;;;11185:79;;:::i;:::-;11149:117;11299:4;11291:6;11287:17;11275:29;;11353:3;11345:4;11337:6;11333:17;11323:8;11319:32;11316:41;11313:128;;;11360:79;;:::i;:::-;11313:128;10879:568;;;;;:::o;11453:559::-;11539:6;11547;11596:2;11584:9;11575:7;11571:23;11567:32;11564:119;;;11602:79;;:::i;:::-;11564:119;11750:1;11739:9;11735:17;11722:31;11780:18;11772:6;11769:30;11766:117;;;11802:79;;:::i;:::-;11766:117;11915:80;11987:7;11978:6;11967:9;11963:22;11915:80;:::i;:::-;11897:98;;;;11693:312;11453:559;;;;;:::o;12018:104::-;12063:7;12092:24;12110:5;12092:24;:::i;:::-;12081:35;;12018:104;;;:::o;12128:142::-;12231:32;12257:5;12231:32;:::i;:::-;12226:3;12219:45;12128:142;;:::o;12276:254::-;12385:4;12423:2;12412:9;12408:18;12400:26;;12436:87;12520:1;12509:9;12505:17;12496:6;12436:87;:::i;:::-;12276:254;;;;:::o;12551:566::-;12622:8;12632:6;12682:3;12675:4;12667:6;12663:17;12659:27;12649:122;;12690:79;;:::i;:::-;12649:122;12803:6;12790:20;12780:30;;12833:18;12825:6;12822:30;12819:117;;;12855:79;;:::i;:::-;12819:117;12969:4;12961:6;12957:17;12945:29;;13023:3;13015:4;13007:6;13003:17;12993:8;12989:32;12986:41;12983:128;;;13030:79;;:::i;:::-;12983:128;12551:566;;;;;:::o;13123:930::-;13243:6;13251;13259;13267;13316:2;13304:9;13295:7;13291:23;13287:32;13284:119;;;13322:79;;:::i;:::-;13284:119;13470:1;13459:9;13455:17;13442:31;13500:18;13492:6;13489:30;13486:117;;;13522:79;;:::i;:::-;13486:117;13635:80;13707:7;13698:6;13687:9;13683:22;13635:80;:::i;:::-;13617:98;;;;13413:312;13792:2;13781:9;13777:18;13764:32;13823:18;13815:6;13812:30;13809:117;;;13845:79;;:::i;:::-;13809:117;13958:78;14028:7;14019:6;14008:9;14004:22;13958:78;:::i;:::-;13940:96;;;;13735:311;13123:930;;;;;;;:::o;14059:116::-;14129:21;14144:5;14129:21;:::i;:::-;14122:5;14119:32;14109:60;;14165:1;14162;14155:12;14109:60;14059:116;:::o;14181:133::-;14224:5;14262:6;14249:20;14240:29;;14278:30;14302:5;14278:30;:::i;:::-;14181:133;;;;:::o;14320:468::-;14385:6;14393;14442:2;14430:9;14421:7;14417:23;14413:32;14410:119;;;14448:79;;:::i;:::-;14410:119;14568:1;14593:53;14638:7;14629:6;14618:9;14614:22;14593:53;:::i;:::-;14583:63;;14539:117;14695:2;14721:50;14763:7;14754:6;14743:9;14739:22;14721:50;:::i;:::-;14711:60;;14666:115;14320:468;;;;;:::o;14807:552::-;14864:8;14874:6;14924:3;14917:4;14909:6;14905:17;14901:27;14891:122;;14932:79;;:::i;:::-;14891:122;15045:6;15032:20;15022:30;;15075:18;15067:6;15064:30;15061:117;;;15097:79;;:::i;:::-;15061:117;15211:4;15203:6;15199:17;15187:29;;15265:3;15257:4;15249:6;15245:17;15235:8;15231:32;15228:41;15225:128;;;15272:79;;:::i;:::-;15225:128;14807:552;;;;;:::o;15365:963::-;15462:6;15470;15478;15486;15494;15543:3;15531:9;15522:7;15518:23;15514:33;15511:120;;;15550:79;;:::i;:::-;15511:120;15670:1;15695:53;15740:7;15731:6;15720:9;15716:22;15695:53;:::i;:::-;15685:63;;15641:117;15797:2;15823:53;15868:7;15859:6;15848:9;15844:22;15823:53;:::i;:::-;15813:63;;15768:118;15925:2;15951:53;15996:7;15987:6;15976:9;15972:22;15951:53;:::i;:::-;15941:63;;15896:118;16081:2;16070:9;16066:18;16053:32;16112:18;16104:6;16101:30;16098:117;;;16134:79;;:::i;:::-;16098:117;16247:64;16303:7;16294:6;16283:9;16279:22;16247:64;:::i;:::-;16229:82;;;;16024:297;15365:963;;;;;;;;:::o;16334:93::-;16370:7;16410:10;16403:5;16399:22;16388:33;;16334:93;;;:::o;16433:115::-;16518:23;16535:5;16518:23;:::i;:::-;16513:3;16506:36;16433:115;;:::o;16554:218::-;16645:4;16683:2;16672:9;16668:18;16660:26;;16696:69;16762:1;16751:9;16747:17;16738:6;16696:69;:::i;:::-;16554:218;;;;:::o;16778:474::-;16846:6;16854;16903:2;16891:9;16882:7;16878:23;16874:32;16871:119;;;16909:79;;:::i;:::-;16871:119;17029:1;17054:53;17099:7;17090:6;17079:9;17075:22;17054:53;:::i;:::-;17044:63;;17000:117;17156:2;17182:53;17227:7;17218:6;17207:9;17203:22;17182:53;:::i;:::-;17172:63;;17127:118;16778:474;;;;;:::o;17258:138::-;17339:32;17365:5;17339:32;:::i;:::-;17332:5;17329:43;17319:71;;17386:1;17383;17376:12;17319:71;17258:138;:::o;17402:155::-;17456:5;17494:6;17481:20;17472:29;;17510:41;17545:5;17510:41;:::i;:::-;17402:155;;;;:::o;17563:345::-;17630:6;17679:2;17667:9;17658:7;17654:23;17650:32;17647:119;;;17685:79;;:::i;:::-;17647:119;17805:1;17830:61;17883:7;17874:6;17863:9;17859:22;17830:61;:::i;:::-;17820:71;;17776:125;17563:345;;;;:::o;17914:166::-;18054:18;18050:1;18042:6;18038:14;18031:42;17914:166;:::o;18086:366::-;18228:3;18249:67;18313:2;18308:3;18249:67;:::i;:::-;18242:74;;18325:93;18414:3;18325:93;:::i;:::-;18443:2;18438:3;18434:12;18427:19;;18086:366;;;:::o;18458:419::-;18624:4;18662:2;18651:9;18647:18;18639:26;;18711:9;18705:4;18701:20;18697:1;18686:9;18682:17;18675:47;18739:131;18865:4;18739:131;:::i;:::-;18731:139;;18458:419;;;:::o;18883:162::-;19023:14;19019:1;19011:6;19007:14;19000:38;18883:162;:::o;19051:366::-;19193:3;19214:67;19278:2;19273:3;19214:67;:::i;:::-;19207:74;;19290:93;19379:3;19290:93;:::i;:::-;19408:2;19403:3;19399:12;19392:19;;19051:366;;;:::o;19423:419::-;19589:4;19627:2;19616:9;19612:18;19604:26;;19676:9;19670:4;19666:20;19662:1;19651:9;19647:17;19640:47;19704:131;19830:4;19704:131;:::i;:::-;19696:139;;19423:419;;;:::o;19848:180::-;19896:77;19893:1;19886:88;19993:4;19990:1;19983:15;20017:4;20014:1;20007:15;20034:193;20073:3;20092:19;20109:1;20092:19;:::i;:::-;20087:24;;20125:19;20142:1;20125:19;:::i;:::-;20120:24;;20167:1;20164;20160:9;20153:16;;20190:6;20185:3;20182:15;20179:41;;;20200:18;;:::i;:::-;20179:41;20034:193;;;;:::o;20233:173::-;20373:25;20369:1;20361:6;20357:14;20350:49;20233:173;:::o;20412:366::-;20554:3;20575:67;20639:2;20634:3;20575:67;:::i;:::-;20568:74;;20651:93;20740:3;20651:93;:::i;:::-;20769:2;20764:3;20760:12;20753:19;;20412:366;;;:::o;20784:419::-;20950:4;20988:2;20977:9;20973:18;20965:26;;21037:9;21031:4;21027:20;21023:1;21012:9;21008:17;21001:47;21065:131;21191:4;21065:131;:::i;:::-;21057:139;;20784:419;;;:::o;21209:328::-;21328:4;21366:2;21355:9;21351:18;21343:26;;21379:71;21447:1;21436:9;21432:17;21423:6;21379:71;:::i;:::-;21460:70;21526:2;21515:9;21511:18;21502:6;21460:70;:::i;:::-;21209:328;;;;;:::o;21543:171::-;21581:3;21604:23;21621:5;21604:23;:::i;:::-;21595:32;;21649:6;21642:5;21639:17;21636:43;;21659:18;;:::i;:::-;21636:43;21706:1;21699:5;21695:13;21688:20;;21543:171;;;:::o;21720:191::-;21758:4;21778:18;21794:1;21778:18;:::i;:::-;21773:23;;21810:18;21826:1;21810:18;:::i;:::-;21805:23;;21852:1;21849;21845:9;21837:17;;21876:4;21870;21867:14;21864:40;;;21884:18;;:::i;:::-;21864:40;21720:191;;;;:::o;21917:180::-;21965:77;21962:1;21955:88;22062:4;22059:1;22052:15;22086:4;22083:1;22076:15;22103:320;22147:6;22184:1;22178:4;22174:12;22164:22;;22231:1;22225:4;22221:12;22252:18;22242:81;;22308:4;22300:6;22296:17;22286:27;;22242:81;22370:2;22362:6;22359:14;22339:18;22336:38;22333:84;;22389:18;;:::i;:::-;22333:84;22154:269;22103:320;;;:::o;22429:194::-;22469:4;22489:20;22507:1;22489:20;:::i;:::-;22484:25;;22523:20;22541:1;22523:20;:::i;:::-;22518:25;;22567:1;22564;22560:9;22552:17;;22591:1;22585:4;22582:11;22579:37;;;22596:18;;:::i;:::-;22579:37;22429:194;;;;:::o;22629:177::-;22769:29;22765:1;22757:6;22753:14;22746:53;22629:177;:::o;22812:366::-;22954:3;22975:67;23039:2;23034:3;22975:67;:::i;:::-;22968:74;;23051:93;23140:3;23051:93;:::i;:::-;23169:2;23164:3;23160:12;23153:19;;22812:366;;;:::o;23184:419::-;23350:4;23388:2;23377:9;23373:18;23365:26;;23437:9;23431:4;23427:20;23423:1;23412:9;23408:17;23401:47;23465:131;23591:4;23465:131;:::i;:::-;23457:139;;23184:419;;;:::o;23609:191::-;23649:3;23668:20;23686:1;23668:20;:::i;:::-;23663:25;;23702:20;23720:1;23702:20;:::i;:::-;23697:25;;23745:1;23742;23738:9;23731:16;;23766:3;23763:1;23760:10;23757:36;;;23773:18;;:::i;:::-;23757:36;23609:191;;;;:::o;23806:169::-;23946:21;23942:1;23934:6;23930:14;23923:45;23806:169;:::o;23981:366::-;24123:3;24144:67;24208:2;24203:3;24144:67;:::i;:::-;24137:74;;24220:93;24309:3;24220:93;:::i;:::-;24338:2;24333:3;24329:12;24322:19;;23981:366;;;:::o;24353:419::-;24519:4;24557:2;24546:9;24542:18;24534:26;;24606:9;24600:4;24596:20;24592:1;24581:9;24577:17;24570:47;24634:131;24760:4;24634:131;:::i;:::-;24626:139;;24353:419;;;:::o;24778:188::-;24816:3;24835:18;24851:1;24835:18;:::i;:::-;24830:23;;24867:18;24883:1;24867:18;:::i;:::-;24862:23;;24908:1;24905;24901:9;24894:16;;24931:4;24926:3;24923:13;24920:39;;;24939:18;;:::i;:::-;24920:39;24778:188;;;;:::o;24972:141::-;25021:4;25044:3;25036:11;;25067:3;25064:1;25057:14;25101:4;25098:1;25088:18;25080:26;;24972:141;;;:::o;25119:93::-;25156:6;25203:2;25198;25191:5;25187:14;25183:23;25173:33;;25119:93;;;:::o;25218:107::-;25262:8;25312:5;25306:4;25302:16;25281:37;;25218:107;;;;:::o;25331:393::-;25400:6;25450:1;25438:10;25434:18;25473:97;25503:66;25492:9;25473:97;:::i;:::-;25591:39;25621:8;25610:9;25591:39;:::i;:::-;25579:51;;25663:4;25659:9;25652:5;25648:21;25639:30;;25712:4;25702:8;25698:19;25691:5;25688:30;25678:40;;25407:317;;25331:393;;;;;:::o;25730:60::-;25758:3;25779:5;25772:12;;25730:60;;;:::o;25796:142::-;25846:9;25879:53;25897:34;25906:24;25924:5;25906:24;:::i;:::-;25897:34;:::i;:::-;25879:53;:::i;:::-;25866:66;;25796:142;;;:::o;25944:75::-;25987:3;26008:5;26001:12;;25944:75;;;:::o;26025:269::-;26135:39;26166:7;26135:39;:::i;:::-;26196:91;26245:41;26269:16;26245:41;:::i;:::-;26237:6;26230:4;26224:11;26196:91;:::i;:::-;26190:4;26183:105;26101:193;26025:269;;;:::o;26300:73::-;26345:3;26300:73;:::o;26379:189::-;26456:32;;:::i;:::-;26497:65;26555:6;26547;26541:4;26497:65;:::i;:::-;26432:136;26379:189;;:::o;26574:186::-;26634:120;26651:3;26644:5;26641:14;26634:120;;;26705:39;26742:1;26735:5;26705:39;:::i;:::-;26678:1;26671:5;26667:13;26658:22;;26634:120;;;26574:186;;:::o;26766:543::-;26867:2;26862:3;26859:11;26856:446;;;26901:38;26933:5;26901:38;:::i;:::-;26985:29;27003:10;26985:29;:::i;:::-;26975:8;26971:44;27168:2;27156:10;27153:18;27150:49;;;27189:8;27174:23;;27150:49;27212:80;27268:22;27286:3;27268:22;:::i;:::-;27258:8;27254:37;27241:11;27212:80;:::i;:::-;26871:431;;26856:446;26766:543;;;:::o;27315:117::-;27369:8;27419:5;27413:4;27409:16;27388:37;;27315:117;;;;:::o;27438:169::-;27482:6;27515:51;27563:1;27559:6;27551:5;27548:1;27544:13;27515:51;:::i;:::-;27511:56;27596:4;27590;27586:15;27576:25;;27489:118;27438:169;;;;:::o;27612:295::-;27688:4;27834:29;27859:3;27853:4;27834:29;:::i;:::-;27826:37;;27896:3;27893:1;27889:11;27883:4;27880:21;27872:29;;27612:295;;;;:::o;27912:1395::-;28029:37;28062:3;28029:37;:::i;:::-;28131:18;28123:6;28120:30;28117:56;;;28153:18;;:::i;:::-;28117:56;28197:38;28229:4;28223:11;28197:38;:::i;:::-;28282:67;28342:6;28334;28328:4;28282:67;:::i;:::-;28376:1;28400:4;28387:17;;28432:2;28424:6;28421:14;28449:1;28444:618;;;;29106:1;29123:6;29120:77;;;29172:9;29167:3;29163:19;29157:26;29148:35;;29120:77;29223:67;29283:6;29276:5;29223:67;:::i;:::-;29217:4;29210:81;29079:222;28414:887;;28444:618;28496:4;28492:9;28484:6;28480:22;28530:37;28562:4;28530:37;:::i;:::-;28589:1;28603:208;28617:7;28614:1;28611:14;28603:208;;;28696:9;28691:3;28687:19;28681:26;28673:6;28666:42;28747:1;28739:6;28735:14;28725:24;;28794:2;28783:9;28779:18;28766:31;;28640:4;28637:1;28633:12;28628:17;;28603:208;;;28839:6;28830:7;28827:19;28824:179;;;28897:9;28892:3;28888:19;28882:26;28940:48;28982:4;28974:6;28970:17;28959:9;28940:48;:::i;:::-;28932:6;28925:64;28847:156;28824:179;29049:1;29045;29037:6;29033:14;29029:22;29023:4;29016:36;28451:611;;;28414:887;;28004:1303;;;27912:1395;;:::o;29313:169::-;29453:21;29449:1;29441:6;29437:14;29430:45;29313:169;:::o;29488:366::-;29630:3;29651:67;29715:2;29710:3;29651:67;:::i;:::-;29644:74;;29727:93;29816:3;29727:93;:::i;:::-;29845:2;29840:3;29836:12;29829:19;;29488:366;;;:::o;29860:419::-;30026:4;30064:2;30053:9;30049:18;30041:26;;30113:9;30107:4;30103:20;30099:1;30088:9;30084:17;30077:47;30141:131;30267:4;30141:131;:::i;:::-;30133:139;;29860:419;;;:::o;30285:160::-;30425:12;30421:1;30413:6;30409:14;30402:36;30285:160;:::o;30451:366::-;30593:3;30614:67;30678:2;30673:3;30614:67;:::i;:::-;30607:74;;30690:93;30779:3;30690:93;:::i;:::-;30808:2;30803:3;30799:12;30792:19;;30451:366;;;:::o;30823:419::-;30989:4;31027:2;31016:9;31012:18;31004:26;;31076:9;31070:4;31066:20;31062:1;31051:9;31047:17;31040:47;31104:131;31230:4;31104:131;:::i;:::-;31096:139;;30823:419;;;:::o;31248:176::-;31388:28;31384:1;31376:6;31372:14;31365:52;31248:176;:::o;31430:366::-;31572:3;31593:67;31657:2;31652:3;31593:67;:::i;:::-;31586:74;;31669:93;31758:3;31669:93;:::i;:::-;31787:2;31782:3;31778:12;31771:19;;31430:366;;;:::o;31802:419::-;31968:4;32006:2;31995:9;31991:18;31983:26;;32055:9;32049:4;32045:20;32041:1;32030:9;32026:17;32019:47;32083:131;32209:4;32083:131;:::i;:::-;32075:139;;31802:419;;;:::o;32227:166::-;32367:18;32363:1;32355:6;32351:14;32344:42;32227:166;:::o;32399:366::-;32541:3;32562:67;32626:2;32621:3;32562:67;:::i;:::-;32555:74;;32638:93;32727:3;32638:93;:::i;:::-;32756:2;32751:3;32747:12;32740:19;;32399:366;;;:::o;32771:419::-;32937:4;32975:2;32964:9;32960:18;32952:26;;33024:9;33018:4;33014:20;33010:1;32999:9;32995:17;32988:47;33052:131;33178:4;33052:131;:::i;:::-;33044:139;;32771:419;;;:::o;33196:173::-;33336:25;33332:1;33324:6;33320:14;33313:49;33196:173;:::o;33375:366::-;33517:3;33538:67;33602:2;33597:3;33538:67;:::i;:::-;33531:74;;33614:93;33703:3;33614:93;:::i;:::-;33732:2;33727:3;33723:12;33716:19;;33375:366;;;:::o;33747:419::-;33913:4;33951:2;33940:9;33936:18;33928:26;;34000:9;33994:4;33990:20;33986:1;33975:9;33971:17;33964:47;34028:131;34154:4;34028:131;:::i;:::-;34020:139;;33747:419;;;:::o;34172:180::-;34220:77;34217:1;34210:88;34317:4;34314:1;34307:15;34341:4;34338:1;34331:15;34358:113;34424:6;34458:5;34452:12;34442:22;;34358:113;;;:::o;34477:183::-;34575:11;34609:6;34604:3;34597:19;34649:4;34644:3;34640:14;34625:29;;34477:183;;;;:::o;34666:131::-;34732:4;34755:3;34747:11;;34785:4;34780:3;34776:14;34768:22;;34666:131;;;:::o;34803:105::-;34878:23;34895:5;34878:23;:::i;:::-;34873:3;34866:36;34803:105;;:::o;34914:175::-;34981:10;35002:44;35042:3;35034:6;35002:44;:::i;:::-;35078:4;35073:3;35069:14;35055:28;;34914:175;;;;:::o;35095:112::-;35164:4;35196;35191:3;35187:14;35179:22;;35095:112;;;:::o;35241:724::-;35358:3;35387:53;35434:5;35387:53;:::i;:::-;35456:85;35534:6;35529:3;35456:85;:::i;:::-;35449:92;;35565:55;35614:5;35565:55;:::i;:::-;35643:7;35674:1;35659:281;35684:6;35681:1;35678:13;35659:281;;;35760:6;35754:13;35787:61;35844:3;35829:13;35787:61;:::i;:::-;35780:68;;35871:59;35923:6;35871:59;:::i;:::-;35861:69;;35719:221;35706:1;35703;35699:9;35694:14;;35659:281;;;35663:14;35956:3;35949:10;;35363:602;;;35241:724;;;;:::o;35971:479::-;36140:4;36178:2;36167:9;36163:18;36155:26;;36191:71;36259:1;36248:9;36244:17;36235:6;36191:71;:::i;:::-;36309:9;36303:4;36299:20;36294:2;36283:9;36279:18;36272:48;36337:106;36438:4;36429:6;36337:106;:::i;:::-;36329:114;;35971:479;;;;;:::o;36456:169::-;36596:21;36592:1;36584:6;36580:14;36573:45;36456:169;:::o;36631:366::-;36773:3;36794:67;36858:2;36853:3;36794:67;:::i;:::-;36787:74;;36870:93;36959:3;36870:93;:::i;:::-;36988:2;36983:3;36979:12;36972:19;;36631:366;;;:::o;37003:419::-;37169:4;37207:2;37196:9;37192:18;37184:26;;37256:9;37250:4;37246:20;37242:1;37231:9;37227:17;37220:47;37284:131;37410:4;37284:131;:::i;:::-;37276:139;;37003:419;;;:::o;37428:176::-;37568:28;37564:1;37556:6;37552:14;37545:52;37428:176;:::o;37610:366::-;37752:3;37773:67;37837:2;37832:3;37773:67;:::i;:::-;37766:74;;37849:93;37938:3;37849:93;:::i;:::-;37967:2;37962:3;37958:12;37951:19;;37610:366;;;:::o;37982:419::-;38148:4;38186:2;38175:9;38171:18;38163:26;;38235:9;38229:4;38225:20;38221:1;38210:9;38206:17;38199:47;38263:131;38389:4;38263:131;:::i;:::-;38255:139;;37982:419;;;:::o;38407:229::-;38547:34;38543:1;38535:6;38531:14;38524:58;38616:12;38611:2;38603:6;38599:15;38592:37;38407:229;:::o;38642:366::-;38784:3;38805:67;38869:2;38864:3;38805:67;:::i;:::-;38798:74;;38881:93;38970:3;38881:93;:::i;:::-;38999:2;38994:3;38990:12;38983:19;;38642:366;;;:::o;39014:419::-;39180:4;39218:2;39207:9;39203:18;39195:26;;39267:9;39261:4;39257:20;39253:1;39242:9;39238:17;39231:47;39295:131;39421:4;39295:131;:::i;:::-;39287:139;;39014:419;;;:::o;39439:168::-;39579:20;39575:1;39567:6;39563:14;39556:44;39439:168;:::o;39613:366::-;39755:3;39776:67;39840:2;39835:3;39776:67;:::i;:::-;39769:74;;39852:93;39941:3;39852:93;:::i;:::-;39970:2;39965:3;39961:12;39954:19;;39613:366;;;:::o;39985:419::-;40151:4;40189:2;40178:9;40174:18;40166:26;;40238:9;40232:4;40228:20;40224:1;40213:9;40209:17;40202:47;40266:131;40392:4;40266:131;:::i;:::-;40258:139;;39985:419;;;:::o;40410:175::-;40550:27;40546:1;40538:6;40534:14;40527:51;40410:175;:::o;40591:366::-;40733:3;40754:67;40818:2;40813:3;40754:67;:::i;:::-;40747:74;;40830:93;40919:3;40830:93;:::i;:::-;40948:2;40943:3;40939:12;40932:19;;40591:366;;;:::o;40963:419::-;41129:4;41167:2;41156:9;41152:18;41144:26;;41216:9;41210:4;41206:20;41202:1;41191:9;41187:17;41180:47;41244:131;41370:4;41244:131;:::i;:::-;41236:139;;40963:419;;;:::o;41388:162::-;41528:14;41524:1;41516:6;41512:14;41505:38;41388:162;:::o;41556:366::-;41698:3;41719:67;41783:2;41778:3;41719:67;:::i;:::-;41712:74;;41795:93;41884:3;41795:93;:::i;:::-;41913:2;41908:3;41904:12;41897:19;;41556:366;;;:::o;41928:419::-;42094:4;42132:2;42121:9;42117:18;42109:26;;42181:9;42175:4;42171:20;42167:1;42156:9;42152:17;42145:47;42209:131;42335:4;42209:131;:::i;:::-;42201:139;;41928:419;;;:::o;42353:148::-;42455:11;42492:3;42477:18;;42353:148;;;;:::o;42507:390::-;42613:3;42641:39;42674:5;42641:39;:::i;:::-;42696:89;42778:6;42773:3;42696:89;:::i;:::-;42689:96;;42794:65;42852:6;42847:3;42840:4;42833:5;42829:16;42794:65;:::i;:::-;42884:6;42879:3;42875:16;42868:23;;42617:280;42507:390;;;;:::o;42903:435::-;43083:3;43105:95;43196:3;43187:6;43105:95;:::i;:::-;43098:102;;43217:95;43308:3;43299:6;43217:95;:::i;:::-;43210:102;;43329:3;43322:10;;42903:435;;;;;:::o;43344:79::-;43383:7;43412:5;43401:16;;43344:79;;;:::o;43429:157::-;43534:45;43554:24;43572:5;43554:24;:::i;:::-;43534:45;:::i;:::-;43529:3;43522:58;43429:157;;:::o;43592:397::-;43732:3;43747:75;43818:3;43809:6;43747:75;:::i;:::-;43847:2;43842:3;43838:12;43831:19;;43860:75;43931:3;43922:6;43860:75;:::i;:::-;43960:2;43955:3;43951:12;43944:19;;43980:3;43973:10;;43592:397;;;;;:::o;43995:171::-;44034:3;44057:24;44075:5;44057:24;:::i;:::-;44048:33;;44103:4;44096:5;44093:15;44090:41;;44111:18;;:::i;:::-;44090:41;44158:1;44151:5;44147:13;44140:20;;43995:171;;;:::o;44172:180::-;44220:77;44217:1;44210:88;44317:4;44314:1;44307:15;44341:4;44338:1;44331:15;44358:197;44397:3;44416:19;44433:1;44416:19;:::i;:::-;44411:24;;44449:19;44466:1;44449:19;:::i;:::-;44444:24;;44491:1;44488;44484:9;44477:16;;44514:10;44509:3;44506:19;44503:45;;;44528:18;;:::i;:::-;44503:45;44358:197;;;;:::o

Swarm Source

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