ETH Price: $3,316.23 (-1.70%)
Gas: 2 Gwei

Token

Astro Tales (ASTRO)
 

Overview

Max Total Supply

1,776 ASTRO

Holders

559

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 ASTRO
0x904b51bb63581043e498d8637b6c28738b89bfa4
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:
ASTRO

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-09
*/

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

library EnumerableSet {

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

    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

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

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

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

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

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

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

    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}


interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

    modifier onlyAllowedOperator() virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}

contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}


library MerkleProof {
  
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
       
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}


library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

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

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

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

    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

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

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

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

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


abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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


abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

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

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

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

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


library Address {
    
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

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

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}


interface IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


abstract contract ERC165 is IERC165 {
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

interface IERC721 is IERC165 {
    
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    function balanceOf(address owner) external view returns (uint256 balance);
    function ownerOf(uint256 tokenId) external view returns (address owner);
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;
    function approve(address to, uint256 tokenId) external;
    function setApprovalForAll(address operator, bool _approved) external;
    function getApproved(uint256 tokenId) external view returns (address operator);
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}


interface IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}


contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

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

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
        _safeTransfer(from, to, tokenId, data);
    }

    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _ownerOf(tokenId) != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

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

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId, 1);

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

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

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}
}

error AllWhiteBagFull();
error AllBagFull();

contract ASTRO is ERC721, Ownable, DefaultOperatorFilterer {

    using Strings for uint256;
    uint private supply;

    bytes32 public merkleRoot;

    string public uriPrefix = "";
    string public uriSuffix = ".json";
    
    uint256 public pCost = 0.0088 ether;
    uint256 public wCost = 0.004 ether;

    uint256 public maxSupply = 5555;  
    
    uint public whitelistWalletLimit;   //as per requirement , whitelist user can mint from both sides
    uint public publicWalletLimit;

    bool public whitelistMintEnabled = false;
    bool public publicMintEnabled = false;

    mapping (address => uint256) public NftBagPb;
    mapping (address => uint256) public NftBagWL;

    constructor(uint _MaxPWallet,uint _MaxWWallet) ERC721("Astro Tales", "ASTRO") {
        setPublicwalletLimit(_MaxPWallet);
        setWhitewalletLimit(_MaxWWallet);
    }

     modifier mintCompliance(uint256 _mintAmount) {
        require(totalSupply() + _mintAmount <= maxSupply, "Max supply exceeded!");
        _;
    }

    modifier pmintPriceCompliance(uint256 _mintAmount) {
        require(msg.value >= pCost * _mintAmount, "Insufficient funds!");
        _;
    }

    modifier wmintPriceCompliance(uint256 _mintAmount) {
        require(msg.value >= wCost * _mintAmount, "Insufficient funds!");
        _;
    }

    function whitelistMint(bytes32[] calldata _merkleProof,uint256 _mintAmount) public payable mintCompliance(_mintAmount) wmintPriceCompliance(_mintAmount) {
        require(whitelistMintEnabled,"Whitelist Mint Paused!!");
        require(tx.origin == msg.sender,"Error: Invalid Caller!");
        require(_mintAmount <= whitelistWalletLimit, "Invalid mint amount!");
        address account = msg.sender;
        if(NftBagWL[account] + _mintAmount > whitelistWalletLimit) {
            revert AllWhiteBagFull();
        }
        bytes32 leaf = keccak256(abi.encodePacked(account));
        require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), "Invalid proof!");
        mint(account, _mintAmount);
        NftBagWL[account] += _mintAmount;
    }

    function publicMint(uint256 _mintAmount) public payable mintCompliance(_mintAmount) pmintPriceCompliance(_mintAmount) {
        require(publicMintEnabled,"Public Mint Paused!!");
        require(tx.origin == msg.sender,"Error: Invalid Caller!");
        require(_mintAmount <= publicWalletLimit, "Invalid mint amount!");
        address account = msg.sender;
        if(NftBagPb[account] + _mintAmount > publicWalletLimit) {
            revert AllBagFull();
        }
        mint(account, _mintAmount);
        NftBagPb[account] += _mintAmount;
    }

    function mintTeam(address _adr, uint256 _mintAmount) public mintCompliance(_mintAmount) onlyOwner {
        mint(_adr, _mintAmount);
    }

    function mint(address _user, uint _unit) internal {
        for (uint256 i = 0; i < _unit; i++) {
            _safeMint(_user, supply);
            supply = supply + 1;    //coz nft start with zero index
        }
    }

    function walletOfOwner(address _owner)
        public
        view
        returns (uint256[] memory)
    {
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);
        uint256 currentTokenId = 0;
        uint256 ownedTokenIndex = 0;

        while (ownedTokenIndex < ownerTokenCount && currentTokenId <= totalSupply()) {
            address currentTokenOwner = ownerOf(currentTokenId);

            if (currentTokenOwner == _owner) {
                ownedTokenIds[ownedTokenIndex] = currentTokenId;

                ownedTokenIndex++;
            }

            currentTokenId++;
        }

        return ownedTokenIds;
    }

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

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

    function enableDisableWhitelistMint(bool _status) public onlyOwner {
        whitelistMintEnabled = _status;
    }

    function enableDisablePublicMint(bool _status) public onlyOwner {
        publicMintEnabled = _status;
    }

    function setPsaleCost(uint256 _newcost) public onlyOwner {
        pCost = _newcost;
    }

    function setWsaleCost(uint256 _newcost) public onlyOwner {
        wCost = _newcost;
    }

    function setWhitewalletLimit(uint _value) public onlyOwner {
        whitelistWalletLimit = _value;
    }

    function setPublicwalletLimit(uint _value) public onlyOwner {
        publicWalletLimit = _value;
    }

    function setUriPrefix(string memory _uriPrefix) public onlyOwner {
        uriPrefix = _uriPrefix;
    }

    function setUriSuffix(string memory _uriSuffix) public onlyOwner {
        uriSuffix = _uriSuffix;
    }

    function setMerkleRoot(bytes32 _merkleRoot) public onlyOwner {
        merkleRoot = _merkleRoot;
    }
    
    function totalSupply() public view returns (uint) {
        return supply;
    }

    function withdraw() public onlyOwner {
        (bool os, ) = payable(owner()).call{value: address(this).balance}('');
        require(os);
    }

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

    // -------------------------  Opensea Royality Filter  -----------------------

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

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

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

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_MaxPWallet","type":"uint256"},{"internalType":"uint256","name":"_MaxWWallet","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AllBagFull","type":"error"},{"inputs":[],"name":"AllWhiteBagFull","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"NftBagPb","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"NftBagWL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"enableDisablePublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"enableDisableWhitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_adr","type":"address"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mintTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicMintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newcost","type":"uint256"}],"name":"setPsaleCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setPublicwalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriPrefix","type":"string"}],"name":"setUriPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setUriSuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setWhitewalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newcost","type":"uint256"}],"name":"setWsaleCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistMintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260405180602001604052806000815250600990805190602001906200002b929190620005b4565b506040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600a908051906020019062000079929190620005b4565b50661f438daa060000600b55660e35fa931a0000600c556115b3600d556000601060006101000a81548160ff0219169083151502179055506000601060016101000a81548160ff021916908315150217905550348015620000d957600080fd5b5060405162005295380380620052958339818101604052810190620000ff91906200067b565b733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600b81526020017f417374726f2054616c65730000000000000000000000000000000000000000008152506040518060400160405280600581526020017f415354524f00000000000000000000000000000000000000000000000000000081525081600090805190602001906200019a929190620005b4565b508060019080519060200190620001b3929190620005b4565b505050620001d6620001ca620003f760201b60201c565b620003ff60201b60201c565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620003cb57801562000291576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200025792919062000717565b600060405180830381600087803b1580156200027257600080fd5b505af115801562000287573d6000803e3d6000fd5b50505050620003ca565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200034b576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200031192919062000717565b600060405180830381600087803b1580156200032c57600080fd5b505af115801562000341573d6000803e3d6000fd5b50505050620003c9565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620003949190620006fa565b600060405180830381600087803b158015620003af57600080fd5b505af1158015620003c4573d6000803e3d6000fd5b505050505b5b5b5050620003de82620004c560201b60201c565b620003ef81620004df60201b60201c565b505062000862565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620004d5620004f960201b60201c565b80600f8190555050565b620004ef620004f960201b60201c565b80600e8190555050565b62000509620003f760201b60201c565b73ffffffffffffffffffffffffffffffffffffffff166200052f6200058a60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000588576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200057f9062000744565b60405180910390fd5b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b828054620005c290620007b5565b90600052602060002090601f016020900481019282620005e6576000855562000632565b82601f106200060157805160ff191683800117855562000632565b8280016001018555821562000632579182015b828111156200063157825182559160200191906001019062000614565b5b50905062000641919062000645565b5090565b5b808211156200066057600081600090555060010162000646565b5090565b600081519050620006758162000848565b92915050565b600080604083850312156200069557620006946200081a565b5b6000620006a58582860162000664565b9250506020620006b88582860162000664565b9150509250929050565b620006cd8162000777565b82525050565b6000620006e260208362000766565b9150620006ef826200081f565b602082019050919050565b6000602082019050620007116000830184620006c2565b92915050565b60006040820190506200072e6000830185620006c2565b6200073d6020830184620006c2565b9392505050565b600060208201905081810360008301526200075f81620006d3565b9050919050565b600082825260208201905092915050565b600062000784826200078b565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006002820490506001821680620007ce57607f821691505b60208210811415620007e557620007e4620007eb565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6200085381620007ab565b81146200085f57600080fd5b50565b614a2380620008726000396000f3fe60806040526004361061025c5760003560e01c80636caede3d11610144578063b88d4fde116100b6578063d5abeb011161007a578063d5abeb01146108c6578063e0677404146108f1578063e985e9c51461091c578063ef08ebbb14610959578063f2fde38b14610984578063f9dc660d146109ad5761025c565b8063b88d4fde146107d1578063b95ec1ca146107fa578063bb75f98614610837578063c87b56dd14610860578063cfbc0e5c1461089d5761025c565b80638da5cb5b116101085780638da5cb5b146106d557806393f84cfe1461070057806395d89b41146107295780639ed9ec8814610754578063a22cb4651461077d578063abd03596146107a65761025c565b80636caede3d1461060457806370a082311461062f578063715018a61461066c5780637cb64759146106835780637ec4a659146106ac5761025c565b80632db11544116101dd578063545d66cd116101a1578063545d66cd146104e05780635503a0e814610509578063558935921461053457806361d469a61461055f57806362b99ad41461059c5780636352211e146105c75761025c565b80632db115441461041c5780632eb4a7ab146104385780633ccfd60b1461046357806342842e0e1461047a578063438b6300146104a35761025c565b806316ba10e01161022457806316ba10e01461035a57806318160ddd1461038357806322429f4b146103ae57806323b872dd146103d75780632904e6d9146104005761025c565b806301ffc9a71461026157806306fdde031461029e578063081812fc146102c9578063095ea7b3146103065780630f4161aa1461032f575b600080fd5b34801561026d57600080fd5b5061028860048036038101906102839190613614565b6109d6565b6040516102959190613cf3565b60405180910390f35b3480156102aa57600080fd5b506102b3610ab8565b6040516102c09190613d29565b60405180910390f35b3480156102d557600080fd5b506102f060048036038101906102eb91906136b7565b610b4a565b6040516102fd9190613c41565b60405180910390f35b34801561031257600080fd5b5061032d600480360381019061032891906134ed565b610b90565b005b34801561033b57600080fd5b50610344610ca8565b6040516103519190613cf3565b60405180910390f35b34801561036657600080fd5b50610381600480360381019061037c919061366e565b610cbb565b005b34801561038f57600080fd5b50610398610cdd565b6040516103a59190613feb565b60405180910390f35b3480156103ba57600080fd5b506103d560048036038101906103d091906136b7565b610ce7565b005b3480156103e357600080fd5b506103fe60048036038101906103f991906133d7565b610cf9565b005b61041a6004803603810190610415919061352d565b610e14565b005b610436600480360381019061043191906136b7565b61116b565b005b34801561044457600080fd5b5061044d611407565b60405161045a9190613d0e565b60405180910390f35b34801561046f57600080fd5b5061047861140d565b005b34801561048657600080fd5b506104a1600480360381019061049c91906133d7565b611495565b005b3480156104af57600080fd5b506104ca60048036038101906104c5919061336a565b6115b0565b6040516104d79190613cd1565b60405180910390f35b3480156104ec57600080fd5b506105076004803603810190610502919061358d565b6116bb565b005b34801561051557600080fd5b5061051e6116e0565b60405161052b9190613d29565b60405180910390f35b34801561054057600080fd5b5061054961176e565b6040516105569190613feb565b60405180910390f35b34801561056b57600080fd5b506105866004803603810190610581919061336a565b611774565b6040516105939190613feb565b60405180910390f35b3480156105a857600080fd5b506105b161178c565b6040516105be9190613d29565b60405180910390f35b3480156105d357600080fd5b506105ee60048036038101906105e991906136b7565b61181a565b6040516105fb9190613c41565b60405180910390f35b34801561061057600080fd5b506106196118a1565b6040516106269190613cf3565b60405180910390f35b34801561063b57600080fd5b506106566004803603810190610651919061336a565b6118b4565b6040516106639190613feb565b60405180910390f35b34801561067857600080fd5b5061068161196c565b005b34801561068f57600080fd5b506106aa60048036038101906106a591906135e7565b611980565b005b3480156106b857600080fd5b506106d360048036038101906106ce919061366e565b611992565b005b3480156106e157600080fd5b506106ea6119b4565b6040516106f79190613c41565b60405180910390f35b34801561070c57600080fd5b50610727600480360381019061072291906134ed565b6119de565b005b34801561073557600080fd5b5061073e611a4d565b60405161074b9190613d29565b60405180910390f35b34801561076057600080fd5b5061077b600480360381019061077691906136b7565b611adf565b005b34801561078957600080fd5b506107a4600480360381019061079f91906134ad565b611af1565b005b3480156107b257600080fd5b506107bb611b07565b6040516107c89190613feb565b60405180910390f35b3480156107dd57600080fd5b506107f860048036038101906107f3919061342a565b611b0d565b005b34801561080657600080fd5b50610821600480360381019061081c919061336a565b611c2a565b60405161082e9190613feb565b60405180910390f35b34801561084357600080fd5b5061085e6004803603810190610859919061358d565b611c42565b005b34801561086c57600080fd5b50610887600480360381019061088291906136b7565b611c67565b6040516108949190613d29565b60405180910390f35b3480156108a957600080fd5b506108c460048036038101906108bf91906136b7565b611d11565b005b3480156108d257600080fd5b506108db611d23565b6040516108e89190613feb565b60405180910390f35b3480156108fd57600080fd5b50610906611d29565b6040516109139190613feb565b60405180910390f35b34801561092857600080fd5b50610943600480360381019061093e9190613397565b611d2f565b6040516109509190613cf3565b60405180910390f35b34801561096557600080fd5b5061096e611dc3565b60405161097b9190613feb565b60405180910390f35b34801561099057600080fd5b506109ab60048036038101906109a6919061336a565b611dc9565b005b3480156109b957600080fd5b506109d460048036038101906109cf91906136b7565b611e4d565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610aa157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ab15750610ab082611e5f565b5b9050919050565b606060008054610ac7906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054610af3906142cd565b8015610b405780601f10610b1557610100808354040283529160200191610b40565b820191906000526020600020905b815481529060010190602001808311610b2357829003601f168201915b5050505050905090565b6000610b5582611ec9565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b9b8261181a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0390613f2b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c2b611f14565b73ffffffffffffffffffffffffffffffffffffffff161480610c5a5750610c5981610c54611f14565b611d2f565b5b610c99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9090613f6b565b60405180910390fd5b610ca38383611f1c565b505050565b601060019054906101000a900460ff1681565b610cc3611fd5565b80600a9080519060200190610cd99291906130fe565b5050565b6000600754905090565b610cef611fd5565b80600e8190555050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610e04576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610d70929190613c5c565b602060405180830381600087803b158015610d8a57600080fd5b505af1158015610d9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc291906135ba565b610e0357336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610dfa9190613c41565b60405180910390fd5b5b610e0f838383612053565b505050565b80600d5481610e21610cdd565b610e2b9190614129565b1115610e6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6390613f4b565b60405180910390fd5b8180600c54610e7b919061417f565b341015610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490613fcb565b60405180910390fd5b601060009054906101000a900460ff16610f0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0390613f8b565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613fab565b60405180910390fd5b600e54831115610fbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb690613e0b565b60405180910390fd5b6000339050600e5484601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110129190614129565b111561104a576040517f6785caf600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008160405160200161105d9190613be0565b6040516020818303038152906040528051906020012090506110c3878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600854836120b3565b611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f990613d6b565b60405180910390fd5b61110c82866120ca565b84601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461115b9190614129565b9250508190555050505050505050565b80600d5481611178610cdd565b6111829190614129565b11156111c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ba90613f4b565b60405180910390fd5b8180600b546111d2919061417f565b341015611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b90613fcb565b60405180910390fd5b601060019054906101000a900460ff16611263576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125a90613e2b565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146112d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c890613fab565b60405180910390fd5b600f54831115611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130d90613e0b565b60405180910390fd5b6000339050600f5484601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113699190614129565b11156113a1576040517f13bcc66b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ab81856120ca565b83601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113fa9190614129565b9250508190555050505050565b60085481565b611415611fd5565b600061141f6119b4565b73ffffffffffffffffffffffffffffffffffffffff164760405161144290613c2c565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b505090508061149257600080fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156115a0576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b815260040161150c929190613c5c565b602060405180830381600087803b15801561152657600080fd5b505af115801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e91906135ba565b61159f57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016115969190613c41565b60405180910390fd5b5b6115ab83838361210e565b505050565b606060006115bd836118b4565b905060008167ffffffffffffffff8111156115db576115da614459565b5b6040519080825280602002602001820160405280156116095781602001602082028036833780820191505090505b5090506000805b83811080156116265750611622610cdd565b8211155b156116af5760006116368361181a565b90508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561169b57828483815181106116805761167f61442a565b5b602002602001018181525050818061169790614330565b9250505b82806116a690614330565b93505050611610565b82945050505050919050565b6116c3611fd5565b80601060016101000a81548160ff02191690831515021790555050565b600a80546116ed906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054611719906142cd565b80156117665780601f1061173b57610100808354040283529160200191611766565b820191906000526020600020905b81548152906001019060200180831161174957829003601f168201915b505050505081565b600e5481565b60116020528060005260406000206000915090505481565b60098054611799906142cd565b80601f01602080910402602001604051908101604052809291908181526020018280546117c5906142cd565b80156118125780601f106117e757610100808354040283529160200191611812565b820191906000526020600020905b8154815290600101906020018083116117f557829003601f168201915b505050505081565b6000806118268361212e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611898576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188f90613f0b565b60405180910390fd5b80915050919050565b601060009054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191c90613e8b565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611974611fd5565b61197e600061216b565b565b611988611fd5565b8060088190555050565b61199a611fd5565b80600990805190602001906119b09291906130fe565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b80600d54816119eb610cdd565b6119f59190614129565b1115611a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2d90613f4b565b60405180910390fd5b611a3e611fd5565b611a4883836120ca565b505050565b606060018054611a5c906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054611a88906142cd565b8015611ad55780601f10611aaa57610100808354040283529160200191611ad5565b820191906000526020600020905b815481529060010190602001808311611ab857829003601f168201915b5050505050905090565b611ae7611fd5565b80600c8190555050565b611b03611afc611f14565b8383612231565b5050565b600f5481565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611c18576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611b84929190613c5c565b602060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd691906135ba565b611c1757336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611c0e9190613c41565b60405180910390fd5b5b611c248484848461239e565b50505050565b60126020528060005260406000206000915090505481565b611c4a611fd5565b80601060006101000a81548160ff02191690831515021790555050565b6060611c7282612400565b611cb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca890613eeb565b60405180910390fd5b6000611cbb612441565b90506000815111611cdb5760405180602001604052806000815250611d09565b80611ce5846124d3565b600a604051602001611cf993929190613bfb565b6040516020818303038152906040525b915050919050565b611d19611fd5565b80600b8190555050565b600d5481565b600b5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600c5481565b611dd1611fd5565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611e41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3890613dab565b60405180910390fd5b611e4a8161216b565b50565b611e55611fd5565b80600f8190555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611ed281612400565b611f11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0890613f0b565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611f8f8361181a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611fdd611f14565b73ffffffffffffffffffffffffffffffffffffffff16611ffb6119b4565b73ffffffffffffffffffffffffffffffffffffffff1614612051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204890613ecb565b60405180910390fd5b565b61206461205e611f14565b826125ab565b6120a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209a90613d4b565b60405180910390fd5b6120ae838383612640565b505050565b6000826120c0858461293a565b1490509392505050565b60005b81811015612109576120e183600754612990565b60016007546120f09190614129565b600781905550808061210190614330565b9150506120cd565b505050565b61212983838360405180602001604052806000815250611b0d565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156122a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161229790613e6b565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123919190613cf3565b60405180910390a3505050565b6123af6123a9611f14565b836125ab565b6123ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e590613d4b565b60405180910390fd5b6123fa848484846129ae565b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff166124228361212e565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b606060098054612450906142cd565b80601f016020809104026020016040519081016040528092919081815260200182805461247c906142cd565b80156124c95780601f1061249e576101008083540402835291602001916124c9565b820191906000526020600020905b8154815290600101906020018083116124ac57829003601f168201915b5050505050905090565b6060600060016124e284612a0a565b01905060008167ffffffffffffffff81111561250157612500614459565b5b6040519080825280601f01601f1916602001820160405280156125335781602001600182028036833780820191505090505b509050600082602001820190505b6001156125a0578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161258a576125896143cc565b5b049450600085141561259b576125a0565b612541565b819350505050919050565b6000806125b78361181a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125f957506125f88185611d2f565b5b8061263757508373ffffffffffffffffffffffffffffffffffffffff1661261f84610b4a565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166126608261181a565b73ffffffffffffffffffffffffffffffffffffffff16146126b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ad90613dcb565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271d90613e4b565b60405180910390fd5b6127338383836001612b5d565b8273ffffffffffffffffffffffffffffffffffffffff166127538261181a565b73ffffffffffffffffffffffffffffffffffffffff16146127a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a090613dcb565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129358383836001612c83565b505050565b60008082905060005b845181101561298557612970828683815181106129635761296261442a565b5b6020026020010151612c89565b9150808061297d90614330565b915050612943565b508091505092915050565b6129aa828260405180602001604052806000815250612cb4565b5050565b6129b9848484612640565b6129c584848484612d0f565b612a04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129fb90613d8b565b60405180910390fd5b50505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612a68577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a5e57612a5d6143cc565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612aa5576d04ee2d6d415b85acef81000000008381612a9b57612a9a6143cc565b5b0492506020810190505b662386f26fc100008310612ad457662386f26fc100008381612aca57612ac96143cc565b5b0492506010810190505b6305f5e1008310612afd576305f5e1008381612af357612af26143cc565b5b0492506008810190505b6127108310612b22576127108381612b1857612b176143cc565b5b0492506004810190505b60648310612b455760648381612b3b57612b3a6143cc565b5b0492506002810190505b600a8310612b54576001810190505b80915050919050565b6001811115612c7d57600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612bf15780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612be991906141d9565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612c7c5780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612c749190614129565b925050819055505b5b50505050565b50505050565b6000818310612ca157612c9c8284612ea6565b612cac565b612cab8383612ea6565b5b905092915050565b612cbe8383612ebd565b612ccb6000848484612d0f565b612d0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d0190613d8b565b60405180910390fd5b505050565b6000612d308473ffffffffffffffffffffffffffffffffffffffff166130db565b15612e99578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612d59611f14565b8786866040518563ffffffff1660e01b8152600401612d7b9493929190613c85565b602060405180830381600087803b158015612d9557600080fd5b505af1925050508015612dc657506040513d601f19601f82011682018060405250810190612dc39190613641565b60015b612e49573d8060008114612df6576040519150601f19603f3d011682016040523d82523d6000602084013e612dfb565b606091505b50600081511415612e41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3890613d8b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612e9e565b600190505b949350505050565b600082600052816020526040600020905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f2490613eab565b60405180910390fd5b612f3681612400565b15612f76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6d90613deb565b60405180910390fd5b612f84600083836001612b5d565b612f8d81612400565b15612fcd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fc490613deb565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46130d7600083836001612c83565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b82805461310a906142cd565b90600052602060002090601f01602090048101928261312c5760008555613173565b82601f1061314557805160ff1916838001178555613173565b82800160010185558215613173579182015b82811115613172578251825591602001919060010190613157565b5b5090506131809190613184565b5090565b5b8082111561319d576000816000905550600101613185565b5090565b60006131b46131af8461402b565b614006565b9050828152602081018484840111156131d0576131cf614497565b5b6131db84828561428b565b509392505050565b60006131f66131f18461405c565b614006565b90508281526020810184848401111561321257613211614497565b5b61321d84828561428b565b509392505050565b6000813590506132348161497a565b92915050565b60008083601f8401126132505761324f61448d565b5b8235905067ffffffffffffffff81111561326d5761326c614488565b5b60208301915083602082028301111561328957613288614492565b5b9250929050565b60008135905061329f81614991565b92915050565b6000815190506132b481614991565b92915050565b6000813590506132c9816149a8565b92915050565b6000813590506132de816149bf565b92915050565b6000815190506132f3816149bf565b92915050565b600082601f83011261330e5761330d61448d565b5b813561331e8482602086016131a1565b91505092915050565b600082601f83011261333c5761333b61448d565b5b813561334c8482602086016131e3565b91505092915050565b600081359050613364816149d6565b92915050565b6000602082840312156133805761337f6144a1565b5b600061338e84828501613225565b91505092915050565b600080604083850312156133ae576133ad6144a1565b5b60006133bc85828601613225565b92505060206133cd85828601613225565b9150509250929050565b6000806000606084860312156133f0576133ef6144a1565b5b60006133fe86828701613225565b935050602061340f86828701613225565b925050604061342086828701613355565b9150509250925092565b60008060008060808587031215613444576134436144a1565b5b600061345287828801613225565b945050602061346387828801613225565b935050604061347487828801613355565b925050606085013567ffffffffffffffff8111156134955761349461449c565b5b6134a1878288016132f9565b91505092959194509250565b600080604083850312156134c4576134c36144a1565b5b60006134d285828601613225565b92505060206134e385828601613290565b9150509250929050565b60008060408385031215613504576135036144a1565b5b600061351285828601613225565b925050602061352385828601613355565b9150509250929050565b600080600060408486031215613546576135456144a1565b5b600084013567ffffffffffffffff8111156135645761356361449c565b5b6135708682870161323a565b9350935050602061358386828701613355565b9150509250925092565b6000602082840312156135a3576135a26144a1565b5b60006135b184828501613290565b91505092915050565b6000602082840312156135d0576135cf6144a1565b5b60006135de848285016132a5565b91505092915050565b6000602082840312156135fd576135fc6144a1565b5b600061360b848285016132ba565b91505092915050565b60006020828403121561362a576136296144a1565b5b6000613638848285016132cf565b91505092915050565b600060208284031215613657576136566144a1565b5b6000613665848285016132e4565b91505092915050565b600060208284031215613684576136836144a1565b5b600082013567ffffffffffffffff8111156136a2576136a161449c565b5b6136ae84828501613327565b91505092915050565b6000602082840312156136cd576136cc6144a1565b5b60006136db84828501613355565b91505092915050565b60006136f08383613bc2565b60208301905092915050565b6137058161420d565b82525050565b61371c6137178261420d565b614379565b82525050565b600061372d826140b2565b61373781856140e0565b93506137428361408d565b8060005b8381101561377357815161375a88826136e4565b9750613765836140d3565b925050600181019050613746565b5085935050505092915050565b6137898161421f565b82525050565b6137988161422b565b82525050565b60006137a9826140bd565b6137b381856140f1565b93506137c381856020860161429a565b6137cc816144a6565b840191505092915050565b60006137e2826140c8565b6137ec818561410d565b93506137fc81856020860161429a565b613805816144a6565b840191505092915050565b600061381b826140c8565b613825818561411e565b935061383581856020860161429a565b80840191505092915050565b6000815461384e816142cd565b613858818661411e565b945060018216600081146138735760018114613884576138b7565b60ff198316865281860193506138b7565b61388d8561409d565b60005b838110156138af57815481890152600182019150602081019050613890565b838801955050505b50505092915050565b60006138cd602d8361410d565b91506138d8826144c4565b604082019050919050565b60006138f0600e8361410d565b91506138fb82614513565b602082019050919050565b600061391360328361410d565b915061391e8261453c565b604082019050919050565b600061393660268361410d565b91506139418261458b565b604082019050919050565b600061395960258361410d565b9150613964826145da565b604082019050919050565b600061397c601c8361410d565b915061398782614629565b602082019050919050565b600061399f60148361410d565b91506139aa82614652565b602082019050919050565b60006139c260148361410d565b91506139cd8261467b565b602082019050919050565b60006139e560248361410d565b91506139f0826146a4565b604082019050919050565b6000613a0860198361410d565b9150613a13826146f3565b602082019050919050565b6000613a2b60298361410d565b9150613a368261471c565b604082019050919050565b6000613a4e60208361410d565b9150613a598261476b565b602082019050919050565b6000613a7160208361410d565b9150613a7c82614794565b602082019050919050565b6000613a94602f8361410d565b9150613a9f826147bd565b604082019050919050565b6000613ab760188361410d565b9150613ac28261480c565b602082019050919050565b6000613ada60218361410d565b9150613ae582614835565b604082019050919050565b6000613afd600083614102565b9150613b0882614884565b600082019050919050565b6000613b2060148361410d565b9150613b2b82614887565b602082019050919050565b6000613b43603d8361410d565b9150613b4e826148b0565b604082019050919050565b6000613b6660178361410d565b9150613b71826148ff565b602082019050919050565b6000613b8960168361410d565b9150613b9482614928565b602082019050919050565b6000613bac60138361410d565b9150613bb782614951565b602082019050919050565b613bcb81614281565b82525050565b613bda81614281565b82525050565b6000613bec828461370b565b60148201915081905092915050565b6000613c078286613810565b9150613c138285613810565b9150613c1f8284613841565b9150819050949350505050565b6000613c3782613af0565b9150819050919050565b6000602082019050613c5660008301846136fc565b92915050565b6000604082019050613c7160008301856136fc565b613c7e60208301846136fc565b9392505050565b6000608082019050613c9a60008301876136fc565b613ca760208301866136fc565b613cb46040830185613bd1565b8181036060830152613cc6818461379e565b905095945050505050565b60006020820190508181036000830152613ceb8184613722565b905092915050565b6000602082019050613d086000830184613780565b92915050565b6000602082019050613d23600083018461378f565b92915050565b60006020820190508181036000830152613d4381846137d7565b905092915050565b60006020820190508181036000830152613d64816138c0565b9050919050565b60006020820190508181036000830152613d84816138e3565b9050919050565b60006020820190508181036000830152613da481613906565b9050919050565b60006020820190508181036000830152613dc481613929565b9050919050565b60006020820190508181036000830152613de48161394c565b9050919050565b60006020820190508181036000830152613e048161396f565b9050919050565b60006020820190508181036000830152613e2481613992565b9050919050565b60006020820190508181036000830152613e44816139b5565b9050919050565b60006020820190508181036000830152613e64816139d8565b9050919050565b60006020820190508181036000830152613e84816139fb565b9050919050565b60006020820190508181036000830152613ea481613a1e565b9050919050565b60006020820190508181036000830152613ec481613a41565b9050919050565b60006020820190508181036000830152613ee481613a64565b9050919050565b60006020820190508181036000830152613f0481613a87565b9050919050565b60006020820190508181036000830152613f2481613aaa565b9050919050565b60006020820190508181036000830152613f4481613acd565b9050919050565b60006020820190508181036000830152613f6481613b13565b9050919050565b60006020820190508181036000830152613f8481613b36565b9050919050565b60006020820190508181036000830152613fa481613b59565b9050919050565b60006020820190508181036000830152613fc481613b7c565b9050919050565b60006020820190508181036000830152613fe481613b9f565b9050919050565b60006020820190506140006000830184613bd1565b92915050565b6000614010614021565b905061401c82826142ff565b919050565b6000604051905090565b600067ffffffffffffffff82111561404657614045614459565b5b61404f826144a6565b9050602081019050919050565b600067ffffffffffffffff82111561407757614076614459565b5b614080826144a6565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061413482614281565b915061413f83614281565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156141745761417361439d565b5b828201905092915050565b600061418a82614281565b915061419583614281565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141ce576141cd61439d565b5b828202905092915050565b60006141e482614281565b91506141ef83614281565b9250828210156142025761420161439d565b5b828203905092915050565b600061421882614261565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156142b857808201518184015260208101905061429d565b838111156142c7576000848401525b50505050565b600060028204905060018216806142e557607f821691505b602082108114156142f9576142f86143fb565b5b50919050565b614308826144a6565b810181811067ffffffffffffffff8211171561432757614326614459565b5b80604052505050565b600061433b82614281565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561436e5761436d61439d565b5b600182019050919050565b60006143848261438b565b9050919050565b6000614396826144b7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b7f496e76616c69642070726f6f6621000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b7f5075626c6963204d696e74205061757365642121000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b50565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b7f57686974656c697374204d696e74205061757365642121000000000000000000600082015250565b7f4572726f723a20496e76616c69642043616c6c65722100000000000000000000600082015250565b7f496e73756666696369656e742066756e64732100000000000000000000000000600082015250565b6149838161420d565b811461498e57600080fd5b50565b61499a8161421f565b81146149a557600080fd5b50565b6149b18161422b565b81146149bc57600080fd5b50565b6149c881614235565b81146149d357600080fd5b50565b6149df81614281565b81146149ea57600080fd5b5056fea2646970667358221220f5b6a2c698498fc21be5ff20017f188826a9b88c6b712d3b1e89a8056129be3864736f6c6343000807003300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002

Deployed Bytecode

0x60806040526004361061025c5760003560e01c80636caede3d11610144578063b88d4fde116100b6578063d5abeb011161007a578063d5abeb01146108c6578063e0677404146108f1578063e985e9c51461091c578063ef08ebbb14610959578063f2fde38b14610984578063f9dc660d146109ad5761025c565b8063b88d4fde146107d1578063b95ec1ca146107fa578063bb75f98614610837578063c87b56dd14610860578063cfbc0e5c1461089d5761025c565b80638da5cb5b116101085780638da5cb5b146106d557806393f84cfe1461070057806395d89b41146107295780639ed9ec8814610754578063a22cb4651461077d578063abd03596146107a65761025c565b80636caede3d1461060457806370a082311461062f578063715018a61461066c5780637cb64759146106835780637ec4a659146106ac5761025c565b80632db11544116101dd578063545d66cd116101a1578063545d66cd146104e05780635503a0e814610509578063558935921461053457806361d469a61461055f57806362b99ad41461059c5780636352211e146105c75761025c565b80632db115441461041c5780632eb4a7ab146104385780633ccfd60b1461046357806342842e0e1461047a578063438b6300146104a35761025c565b806316ba10e01161022457806316ba10e01461035a57806318160ddd1461038357806322429f4b146103ae57806323b872dd146103d75780632904e6d9146104005761025c565b806301ffc9a71461026157806306fdde031461029e578063081812fc146102c9578063095ea7b3146103065780630f4161aa1461032f575b600080fd5b34801561026d57600080fd5b5061028860048036038101906102839190613614565b6109d6565b6040516102959190613cf3565b60405180910390f35b3480156102aa57600080fd5b506102b3610ab8565b6040516102c09190613d29565b60405180910390f35b3480156102d557600080fd5b506102f060048036038101906102eb91906136b7565b610b4a565b6040516102fd9190613c41565b60405180910390f35b34801561031257600080fd5b5061032d600480360381019061032891906134ed565b610b90565b005b34801561033b57600080fd5b50610344610ca8565b6040516103519190613cf3565b60405180910390f35b34801561036657600080fd5b50610381600480360381019061037c919061366e565b610cbb565b005b34801561038f57600080fd5b50610398610cdd565b6040516103a59190613feb565b60405180910390f35b3480156103ba57600080fd5b506103d560048036038101906103d091906136b7565b610ce7565b005b3480156103e357600080fd5b506103fe60048036038101906103f991906133d7565b610cf9565b005b61041a6004803603810190610415919061352d565b610e14565b005b610436600480360381019061043191906136b7565b61116b565b005b34801561044457600080fd5b5061044d611407565b60405161045a9190613d0e565b60405180910390f35b34801561046f57600080fd5b5061047861140d565b005b34801561048657600080fd5b506104a1600480360381019061049c91906133d7565b611495565b005b3480156104af57600080fd5b506104ca60048036038101906104c5919061336a565b6115b0565b6040516104d79190613cd1565b60405180910390f35b3480156104ec57600080fd5b506105076004803603810190610502919061358d565b6116bb565b005b34801561051557600080fd5b5061051e6116e0565b60405161052b9190613d29565b60405180910390f35b34801561054057600080fd5b5061054961176e565b6040516105569190613feb565b60405180910390f35b34801561056b57600080fd5b506105866004803603810190610581919061336a565b611774565b6040516105939190613feb565b60405180910390f35b3480156105a857600080fd5b506105b161178c565b6040516105be9190613d29565b60405180910390f35b3480156105d357600080fd5b506105ee60048036038101906105e991906136b7565b61181a565b6040516105fb9190613c41565b60405180910390f35b34801561061057600080fd5b506106196118a1565b6040516106269190613cf3565b60405180910390f35b34801561063b57600080fd5b506106566004803603810190610651919061336a565b6118b4565b6040516106639190613feb565b60405180910390f35b34801561067857600080fd5b5061068161196c565b005b34801561068f57600080fd5b506106aa60048036038101906106a591906135e7565b611980565b005b3480156106b857600080fd5b506106d360048036038101906106ce919061366e565b611992565b005b3480156106e157600080fd5b506106ea6119b4565b6040516106f79190613c41565b60405180910390f35b34801561070c57600080fd5b50610727600480360381019061072291906134ed565b6119de565b005b34801561073557600080fd5b5061073e611a4d565b60405161074b9190613d29565b60405180910390f35b34801561076057600080fd5b5061077b600480360381019061077691906136b7565b611adf565b005b34801561078957600080fd5b506107a4600480360381019061079f91906134ad565b611af1565b005b3480156107b257600080fd5b506107bb611b07565b6040516107c89190613feb565b60405180910390f35b3480156107dd57600080fd5b506107f860048036038101906107f3919061342a565b611b0d565b005b34801561080657600080fd5b50610821600480360381019061081c919061336a565b611c2a565b60405161082e9190613feb565b60405180910390f35b34801561084357600080fd5b5061085e6004803603810190610859919061358d565b611c42565b005b34801561086c57600080fd5b50610887600480360381019061088291906136b7565b611c67565b6040516108949190613d29565b60405180910390f35b3480156108a957600080fd5b506108c460048036038101906108bf91906136b7565b611d11565b005b3480156108d257600080fd5b506108db611d23565b6040516108e89190613feb565b60405180910390f35b3480156108fd57600080fd5b50610906611d29565b6040516109139190613feb565b60405180910390f35b34801561092857600080fd5b50610943600480360381019061093e9190613397565b611d2f565b6040516109509190613cf3565b60405180910390f35b34801561096557600080fd5b5061096e611dc3565b60405161097b9190613feb565b60405180910390f35b34801561099057600080fd5b506109ab60048036038101906109a6919061336a565b611dc9565b005b3480156109b957600080fd5b506109d460048036038101906109cf91906136b7565b611e4d565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610aa157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ab15750610ab082611e5f565b5b9050919050565b606060008054610ac7906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054610af3906142cd565b8015610b405780601f10610b1557610100808354040283529160200191610b40565b820191906000526020600020905b815481529060010190602001808311610b2357829003601f168201915b5050505050905090565b6000610b5582611ec9565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b9b8261181a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0390613f2b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c2b611f14565b73ffffffffffffffffffffffffffffffffffffffff161480610c5a5750610c5981610c54611f14565b611d2f565b5b610c99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9090613f6b565b60405180910390fd5b610ca38383611f1c565b505050565b601060019054906101000a900460ff1681565b610cc3611fd5565b80600a9080519060200190610cd99291906130fe565b5050565b6000600754905090565b610cef611fd5565b80600e8190555050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610e04576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610d70929190613c5c565b602060405180830381600087803b158015610d8a57600080fd5b505af1158015610d9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc291906135ba565b610e0357336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610dfa9190613c41565b60405180910390fd5b5b610e0f838383612053565b505050565b80600d5481610e21610cdd565b610e2b9190614129565b1115610e6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6390613f4b565b60405180910390fd5b8180600c54610e7b919061417f565b341015610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490613fcb565b60405180910390fd5b601060009054906101000a900460ff16610f0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0390613f8b565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613fab565b60405180910390fd5b600e54831115610fbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb690613e0b565b60405180910390fd5b6000339050600e5484601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110129190614129565b111561104a576040517f6785caf600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008160405160200161105d9190613be0565b6040516020818303038152906040528051906020012090506110c3878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600854836120b3565b611102576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f990613d6b565b60405180910390fd5b61110c82866120ca565b84601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461115b9190614129565b9250508190555050505050505050565b80600d5481611178610cdd565b6111829190614129565b11156111c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ba90613f4b565b60405180910390fd5b8180600b546111d2919061417f565b341015611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b90613fcb565b60405180910390fd5b601060019054906101000a900460ff16611263576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125a90613e2b565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146112d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c890613fab565b60405180910390fd5b600f54831115611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130d90613e0b565b60405180910390fd5b6000339050600f5484601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113699190614129565b11156113a1576040517f13bcc66b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ab81856120ca565b83601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113fa9190614129565b9250508190555050505050565b60085481565b611415611fd5565b600061141f6119b4565b73ffffffffffffffffffffffffffffffffffffffff164760405161144290613c2c565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b505090508061149257600080fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156115a0576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b815260040161150c929190613c5c565b602060405180830381600087803b15801561152657600080fd5b505af115801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e91906135ba565b61159f57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016115969190613c41565b60405180910390fd5b5b6115ab83838361210e565b505050565b606060006115bd836118b4565b905060008167ffffffffffffffff8111156115db576115da614459565b5b6040519080825280602002602001820160405280156116095781602001602082028036833780820191505090505b5090506000805b83811080156116265750611622610cdd565b8211155b156116af5760006116368361181a565b90508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561169b57828483815181106116805761167f61442a565b5b602002602001018181525050818061169790614330565b9250505b82806116a690614330565b93505050611610565b82945050505050919050565b6116c3611fd5565b80601060016101000a81548160ff02191690831515021790555050565b600a80546116ed906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054611719906142cd565b80156117665780601f1061173b57610100808354040283529160200191611766565b820191906000526020600020905b81548152906001019060200180831161174957829003601f168201915b505050505081565b600e5481565b60116020528060005260406000206000915090505481565b60098054611799906142cd565b80601f01602080910402602001604051908101604052809291908181526020018280546117c5906142cd565b80156118125780601f106117e757610100808354040283529160200191611812565b820191906000526020600020905b8154815290600101906020018083116117f557829003601f168201915b505050505081565b6000806118268361212e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611898576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188f90613f0b565b60405180910390fd5b80915050919050565b601060009054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191c90613e8b565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611974611fd5565b61197e600061216b565b565b611988611fd5565b8060088190555050565b61199a611fd5565b80600990805190602001906119b09291906130fe565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b80600d54816119eb610cdd565b6119f59190614129565b1115611a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2d90613f4b565b60405180910390fd5b611a3e611fd5565b611a4883836120ca565b505050565b606060018054611a5c906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054611a88906142cd565b8015611ad55780601f10611aaa57610100808354040283529160200191611ad5565b820191906000526020600020905b815481529060010190602001808311611ab857829003601f168201915b5050505050905090565b611ae7611fd5565b80600c8190555050565b611b03611afc611f14565b8383612231565b5050565b600f5481565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611c18576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611b84929190613c5c565b602060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd691906135ba565b611c1757336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611c0e9190613c41565b60405180910390fd5b5b611c248484848461239e565b50505050565b60126020528060005260406000206000915090505481565b611c4a611fd5565b80601060006101000a81548160ff02191690831515021790555050565b6060611c7282612400565b611cb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca890613eeb565b60405180910390fd5b6000611cbb612441565b90506000815111611cdb5760405180602001604052806000815250611d09565b80611ce5846124d3565b600a604051602001611cf993929190613bfb565b6040516020818303038152906040525b915050919050565b611d19611fd5565b80600b8190555050565b600d5481565b600b5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600c5481565b611dd1611fd5565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611e41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3890613dab565b60405180910390fd5b611e4a8161216b565b50565b611e55611fd5565b80600f8190555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611ed281612400565b611f11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0890613f0b565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611f8f8361181a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611fdd611f14565b73ffffffffffffffffffffffffffffffffffffffff16611ffb6119b4565b73ffffffffffffffffffffffffffffffffffffffff1614612051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204890613ecb565b60405180910390fd5b565b61206461205e611f14565b826125ab565b6120a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209a90613d4b565b60405180910390fd5b6120ae838383612640565b505050565b6000826120c0858461293a565b1490509392505050565b60005b81811015612109576120e183600754612990565b60016007546120f09190614129565b600781905550808061210190614330565b9150506120cd565b505050565b61212983838360405180602001604052806000815250611b0d565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156122a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161229790613e6b565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123919190613cf3565b60405180910390a3505050565b6123af6123a9611f14565b836125ab565b6123ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e590613d4b565b60405180910390fd5b6123fa848484846129ae565b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff166124228361212e565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b606060098054612450906142cd565b80601f016020809104026020016040519081016040528092919081815260200182805461247c906142cd565b80156124c95780601f1061249e576101008083540402835291602001916124c9565b820191906000526020600020905b8154815290600101906020018083116124ac57829003601f168201915b5050505050905090565b6060600060016124e284612a0a565b01905060008167ffffffffffffffff81111561250157612500614459565b5b6040519080825280601f01601f1916602001820160405280156125335781602001600182028036833780820191505090505b509050600082602001820190505b6001156125a0578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161258a576125896143cc565b5b049450600085141561259b576125a0565b612541565b819350505050919050565b6000806125b78361181a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125f957506125f88185611d2f565b5b8061263757508373ffffffffffffffffffffffffffffffffffffffff1661261f84610b4a565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166126608261181a565b73ffffffffffffffffffffffffffffffffffffffff16146126b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ad90613dcb565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271d90613e4b565b60405180910390fd5b6127338383836001612b5d565b8273ffffffffffffffffffffffffffffffffffffffff166127538261181a565b73ffffffffffffffffffffffffffffffffffffffff16146127a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a090613dcb565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129358383836001612c83565b505050565b60008082905060005b845181101561298557612970828683815181106129635761296261442a565b5b6020026020010151612c89565b9150808061297d90614330565b915050612943565b508091505092915050565b6129aa828260405180602001604052806000815250612cb4565b5050565b6129b9848484612640565b6129c584848484612d0f565b612a04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129fb90613d8b565b60405180910390fd5b50505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612a68577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a5e57612a5d6143cc565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612aa5576d04ee2d6d415b85acef81000000008381612a9b57612a9a6143cc565b5b0492506020810190505b662386f26fc100008310612ad457662386f26fc100008381612aca57612ac96143cc565b5b0492506010810190505b6305f5e1008310612afd576305f5e1008381612af357612af26143cc565b5b0492506008810190505b6127108310612b22576127108381612b1857612b176143cc565b5b0492506004810190505b60648310612b455760648381612b3b57612b3a6143cc565b5b0492506002810190505b600a8310612b54576001810190505b80915050919050565b6001811115612c7d57600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612bf15780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612be991906141d9565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612c7c5780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612c749190614129565b925050819055505b5b50505050565b50505050565b6000818310612ca157612c9c8284612ea6565b612cac565b612cab8383612ea6565b5b905092915050565b612cbe8383612ebd565b612ccb6000848484612d0f565b612d0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d0190613d8b565b60405180910390fd5b505050565b6000612d308473ffffffffffffffffffffffffffffffffffffffff166130db565b15612e99578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612d59611f14565b8786866040518563ffffffff1660e01b8152600401612d7b9493929190613c85565b602060405180830381600087803b158015612d9557600080fd5b505af1925050508015612dc657506040513d601f19601f82011682018060405250810190612dc39190613641565b60015b612e49573d8060008114612df6576040519150601f19603f3d011682016040523d82523d6000602084013e612dfb565b606091505b50600081511415612e41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3890613d8b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612e9e565b600190505b949350505050565b600082600052816020526040600020905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f2490613eab565b60405180910390fd5b612f3681612400565b15612f76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6d90613deb565b60405180910390fd5b612f84600083836001612b5d565b612f8d81612400565b15612fcd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fc490613deb565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46130d7600083836001612c83565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b82805461310a906142cd565b90600052602060002090601f01602090048101928261312c5760008555613173565b82601f1061314557805160ff1916838001178555613173565b82800160010185558215613173579182015b82811115613172578251825591602001919060010190613157565b5b5090506131809190613184565b5090565b5b8082111561319d576000816000905550600101613185565b5090565b60006131b46131af8461402b565b614006565b9050828152602081018484840111156131d0576131cf614497565b5b6131db84828561428b565b509392505050565b60006131f66131f18461405c565b614006565b90508281526020810184848401111561321257613211614497565b5b61321d84828561428b565b509392505050565b6000813590506132348161497a565b92915050565b60008083601f8401126132505761324f61448d565b5b8235905067ffffffffffffffff81111561326d5761326c614488565b5b60208301915083602082028301111561328957613288614492565b5b9250929050565b60008135905061329f81614991565b92915050565b6000815190506132b481614991565b92915050565b6000813590506132c9816149a8565b92915050565b6000813590506132de816149bf565b92915050565b6000815190506132f3816149bf565b92915050565b600082601f83011261330e5761330d61448d565b5b813561331e8482602086016131a1565b91505092915050565b600082601f83011261333c5761333b61448d565b5b813561334c8482602086016131e3565b91505092915050565b600081359050613364816149d6565b92915050565b6000602082840312156133805761337f6144a1565b5b600061338e84828501613225565b91505092915050565b600080604083850312156133ae576133ad6144a1565b5b60006133bc85828601613225565b92505060206133cd85828601613225565b9150509250929050565b6000806000606084860312156133f0576133ef6144a1565b5b60006133fe86828701613225565b935050602061340f86828701613225565b925050604061342086828701613355565b9150509250925092565b60008060008060808587031215613444576134436144a1565b5b600061345287828801613225565b945050602061346387828801613225565b935050604061347487828801613355565b925050606085013567ffffffffffffffff8111156134955761349461449c565b5b6134a1878288016132f9565b91505092959194509250565b600080604083850312156134c4576134c36144a1565b5b60006134d285828601613225565b92505060206134e385828601613290565b9150509250929050565b60008060408385031215613504576135036144a1565b5b600061351285828601613225565b925050602061352385828601613355565b9150509250929050565b600080600060408486031215613546576135456144a1565b5b600084013567ffffffffffffffff8111156135645761356361449c565b5b6135708682870161323a565b9350935050602061358386828701613355565b9150509250925092565b6000602082840312156135a3576135a26144a1565b5b60006135b184828501613290565b91505092915050565b6000602082840312156135d0576135cf6144a1565b5b60006135de848285016132a5565b91505092915050565b6000602082840312156135fd576135fc6144a1565b5b600061360b848285016132ba565b91505092915050565b60006020828403121561362a576136296144a1565b5b6000613638848285016132cf565b91505092915050565b600060208284031215613657576136566144a1565b5b6000613665848285016132e4565b91505092915050565b600060208284031215613684576136836144a1565b5b600082013567ffffffffffffffff8111156136a2576136a161449c565b5b6136ae84828501613327565b91505092915050565b6000602082840312156136cd576136cc6144a1565b5b60006136db84828501613355565b91505092915050565b60006136f08383613bc2565b60208301905092915050565b6137058161420d565b82525050565b61371c6137178261420d565b614379565b82525050565b600061372d826140b2565b61373781856140e0565b93506137428361408d565b8060005b8381101561377357815161375a88826136e4565b9750613765836140d3565b925050600181019050613746565b5085935050505092915050565b6137898161421f565b82525050565b6137988161422b565b82525050565b60006137a9826140bd565b6137b381856140f1565b93506137c381856020860161429a565b6137cc816144a6565b840191505092915050565b60006137e2826140c8565b6137ec818561410d565b93506137fc81856020860161429a565b613805816144a6565b840191505092915050565b600061381b826140c8565b613825818561411e565b935061383581856020860161429a565b80840191505092915050565b6000815461384e816142cd565b613858818661411e565b945060018216600081146138735760018114613884576138b7565b60ff198316865281860193506138b7565b61388d8561409d565b60005b838110156138af57815481890152600182019150602081019050613890565b838801955050505b50505092915050565b60006138cd602d8361410d565b91506138d8826144c4565b604082019050919050565b60006138f0600e8361410d565b91506138fb82614513565b602082019050919050565b600061391360328361410d565b915061391e8261453c565b604082019050919050565b600061393660268361410d565b91506139418261458b565b604082019050919050565b600061395960258361410d565b9150613964826145da565b604082019050919050565b600061397c601c8361410d565b915061398782614629565b602082019050919050565b600061399f60148361410d565b91506139aa82614652565b602082019050919050565b60006139c260148361410d565b91506139cd8261467b565b602082019050919050565b60006139e560248361410d565b91506139f0826146a4565b604082019050919050565b6000613a0860198361410d565b9150613a13826146f3565b602082019050919050565b6000613a2b60298361410d565b9150613a368261471c565b604082019050919050565b6000613a4e60208361410d565b9150613a598261476b565b602082019050919050565b6000613a7160208361410d565b9150613a7c82614794565b602082019050919050565b6000613a94602f8361410d565b9150613a9f826147bd565b604082019050919050565b6000613ab760188361410d565b9150613ac28261480c565b602082019050919050565b6000613ada60218361410d565b9150613ae582614835565b604082019050919050565b6000613afd600083614102565b9150613b0882614884565b600082019050919050565b6000613b2060148361410d565b9150613b2b82614887565b602082019050919050565b6000613b43603d8361410d565b9150613b4e826148b0565b604082019050919050565b6000613b6660178361410d565b9150613b71826148ff565b602082019050919050565b6000613b8960168361410d565b9150613b9482614928565b602082019050919050565b6000613bac60138361410d565b9150613bb782614951565b602082019050919050565b613bcb81614281565b82525050565b613bda81614281565b82525050565b6000613bec828461370b565b60148201915081905092915050565b6000613c078286613810565b9150613c138285613810565b9150613c1f8284613841565b9150819050949350505050565b6000613c3782613af0565b9150819050919050565b6000602082019050613c5660008301846136fc565b92915050565b6000604082019050613c7160008301856136fc565b613c7e60208301846136fc565b9392505050565b6000608082019050613c9a60008301876136fc565b613ca760208301866136fc565b613cb46040830185613bd1565b8181036060830152613cc6818461379e565b905095945050505050565b60006020820190508181036000830152613ceb8184613722565b905092915050565b6000602082019050613d086000830184613780565b92915050565b6000602082019050613d23600083018461378f565b92915050565b60006020820190508181036000830152613d4381846137d7565b905092915050565b60006020820190508181036000830152613d64816138c0565b9050919050565b60006020820190508181036000830152613d84816138e3565b9050919050565b60006020820190508181036000830152613da481613906565b9050919050565b60006020820190508181036000830152613dc481613929565b9050919050565b60006020820190508181036000830152613de48161394c565b9050919050565b60006020820190508181036000830152613e048161396f565b9050919050565b60006020820190508181036000830152613e2481613992565b9050919050565b60006020820190508181036000830152613e44816139b5565b9050919050565b60006020820190508181036000830152613e64816139d8565b9050919050565b60006020820190508181036000830152613e84816139fb565b9050919050565b60006020820190508181036000830152613ea481613a1e565b9050919050565b60006020820190508181036000830152613ec481613a41565b9050919050565b60006020820190508181036000830152613ee481613a64565b9050919050565b60006020820190508181036000830152613f0481613a87565b9050919050565b60006020820190508181036000830152613f2481613aaa565b9050919050565b60006020820190508181036000830152613f4481613acd565b9050919050565b60006020820190508181036000830152613f6481613b13565b9050919050565b60006020820190508181036000830152613f8481613b36565b9050919050565b60006020820190508181036000830152613fa481613b59565b9050919050565b60006020820190508181036000830152613fc481613b7c565b9050919050565b60006020820190508181036000830152613fe481613b9f565b9050919050565b60006020820190506140006000830184613bd1565b92915050565b6000614010614021565b905061401c82826142ff565b919050565b6000604051905090565b600067ffffffffffffffff82111561404657614045614459565b5b61404f826144a6565b9050602081019050919050565b600067ffffffffffffffff82111561407757614076614459565b5b614080826144a6565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061413482614281565b915061413f83614281565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156141745761417361439d565b5b828201905092915050565b600061418a82614281565b915061419583614281565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141ce576141cd61439d565b5b828202905092915050565b60006141e482614281565b91506141ef83614281565b9250828210156142025761420161439d565b5b828203905092915050565b600061421882614261565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156142b857808201518184015260208101905061429d565b838111156142c7576000848401525b50505050565b600060028204905060018216806142e557607f821691505b602082108114156142f9576142f86143fb565b5b50919050565b614308826144a6565b810181811067ffffffffffffffff8211171561432757614326614459565b5b80604052505050565b600061433b82614281565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561436e5761436d61439d565b5b600182019050919050565b60006143848261438b565b9050919050565b6000614396826144b7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b7f496e76616c69642070726f6f6621000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b7f5075626c6963204d696e74205061757365642121000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b50565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b7f57686974656c697374204d696e74205061757365642121000000000000000000600082015250565b7f4572726f723a20496e76616c69642043616c6c65722100000000000000000000600082015250565b7f496e73756666696369656e742066756e64732100000000000000000000000000600082015250565b6149838161420d565b811461498e57600080fd5b50565b61499a8161421f565b81146149a557600080fd5b50565b6149b18161422b565b81146149bc57600080fd5b50565b6149c881614235565b81146149d357600080fd5b50565b6149df81614281565b81146149ea57600080fd5b5056fea2646970667358221220f5b6a2c698498fc21be5ff20017f188826a9b88c6b712d3b1e89a8056129be3864736f6c63430008070033

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

00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002

-----Decoded View---------------
Arg [0] : _MaxPWallet (uint256): 2
Arg [1] : _MaxWWallet (uint256): 2

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


Deployed Bytecode Sourcemap

57927:6318:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43216:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44144:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45656:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45174:416;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58490:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63001:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63231:82;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62659:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63680:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59287:763;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60058:561;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58055:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63321:147;;;;;;;;;;;;;:::i;:::-;;63845:165;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61007:723;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62341:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58124:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58301:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58536:44;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58089:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43854:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58443:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43585:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32934:103;;;;;;;;;;;;;:::i;:::-;;63115:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62887:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32286:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60627:140;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44313:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62559:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45899:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58405:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64018:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58587:44;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62217:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61738:471;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62459:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58255:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58170:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46125:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58212:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33192:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62774:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43216:305;43318:4;43370:25;43355:40;;;:11;:40;;;;:105;;;;43427:33;43412:48;;;:11;:48;;;;43355:105;:158;;;;43477:36;43501:11;43477:23;:36::i;:::-;43355:158;43335:178;;43216:305;;;:::o;44144:100::-;44198:13;44231:5;44224:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44144:100;:::o;45656:171::-;45732:7;45752:23;45767:7;45752:14;:23::i;:::-;45795:15;:24;45811:7;45795:24;;;;;;;;;;;;;;;;;;;;;45788:31;;45656:171;;;:::o;45174:416::-;45255:13;45271:23;45286:7;45271:14;:23::i;:::-;45255:39;;45319:5;45313:11;;:2;:11;;;;45305:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;45413:5;45397:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;45422:37;45439:5;45446:12;:10;:12::i;:::-;45422:16;:37::i;:::-;45397:62;45375:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;45561:21;45570:2;45574:7;45561:8;:21::i;:::-;45244:346;45174:416;;:::o;58490:37::-;;;;;;;;;;;;;:::o;63001:106::-;32172:13;:11;:13::i;:::-;63089:10:::1;63077:9;:22;;;;;;;;;;;;:::i;:::-;;63001:106:::0;:::o;63231:82::-;63275:4;63299:6;;63292:13;;63231:82;:::o;62659:107::-;32172:13;:11;:13::i;:::-;62752:6:::1;62729:20;:29;;;;62659:107:::0;:::o;63680:157::-;10693:1;9519:42;10647:43;;;:47;10643:225;;;9519:42;10716:40;;;10765:4;10772:10;10716:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10711:146;;10830:10;10811:30;;;;;;;;;;;:::i;:::-;;;;;;;;10711:146;10643:225;63792:37:::1;63811:4;63817:2;63821:7;63792:18;:37::i;:::-;63680:157:::0;;;:::o;59287:763::-;59393:11;58917:9;;58902:11;58886:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;58878:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;59427:11:::1;59224;59216:5;;:19;;;;:::i;:::-;59203:9;:32;;59195:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;59459:20:::2;;;;;;;;;;;59451:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;59538:10;59525:23;;:9;:23;;;59517:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;59608:20;;59593:11;:35;;59585:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;59664:15;59682:10;59664:28;;59740:20;;59726:11;59706:8;:17;59715:7;59706:17;;;;;;;;;;;;;;;;:31;;;;:::i;:::-;:54;59703:110;;;59784:17;;;;;;;;;;;;;;59703:110;59823:12;59865:7;59848:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;59838:36;;;;;;59823:51;;59893:50;59912:12;;59893:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59926:10;;59938:4;59893:18;:50::i;:::-;59885:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;59973:26;59978:7;59987:11;59973:4;:26::i;:::-;60031:11;60010:8;:17;60019:7;60010:17;;;;;;;;;;;;;;;;:32;;;;;;;:::i;:::-;;;;;;;;59440:610;;58962:1:::1;59287:763:::0;;;;:::o;60058:561::-;60129:11;58917:9;;58902:11;58886:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;58878:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;60163:11:::1;59070;59062:5;;:19;;;;:::i;:::-;59049:9;:32;;59041:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;60195:17:::2;;;;;;;;;;;60187:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;60268:10;60255:23;;:9;:23;;;60247:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;60338:17;;60323:11;:32;;60315:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;60391:15;60409:10;60391:28;;60467:17;;60453:11;60433:8;:17;60442:7;60433:17;;;;;;;;;;;;;;;;:31;;;;:::i;:::-;:51;60430:102;;;60508:12;;;;;;;;;;;;;;60430:102;60542:26;60547:7;60556:11;60542:4;:26::i;:::-;60600:11;60579:8;:17;60588:7;60579:17;;;;;;;;;;;;;;;;:32;;;;;;;:::i;:::-;;;;;;;;60176:443;58962:1:::1;60058:561:::0;;:::o;58055:25::-;;;;:::o;63321:147::-;32172:13;:11;:13::i;:::-;63370:7:::1;63391;:5;:7::i;:::-;63383:21;;63412;63383:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63369:69;;;63457:2;63449:11;;;::::0;::::1;;63358:110;63321:147::o:0;63845:165::-;10693:1;9519:42;10647:43;;;:47;10643:225;;;9519:42;10716:40;;;10765:4;10772:10;10716:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10711:146;;10830:10;10811:30;;;;;;;;;;;:::i;:::-;;;;;;;;10711:146;10643:225;63961:41:::1;63984:4;63990:2;63994:7;63961:22;:41::i;:::-;63845:165:::0;;;:::o;61007:723::-;61094:16;61128:23;61154:17;61164:6;61154:9;:17::i;:::-;61128:43;;61182:30;61229:15;61215:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61182:63;;61256:22;61293:23;61333:357;61358:15;61340;:33;:68;;;;;61395:13;:11;:13::i;:::-;61377:14;:31;;61340:68;61333:357;;;61425:25;61453:23;61461:14;61453:7;:23::i;:::-;61425:51;;61518:6;61497:27;;:17;:27;;;61493:153;;;61578:14;61545:13;61559:15;61545:30;;;;;;;;:::i;:::-;;;;;;;:47;;;;;61613:17;;;;;:::i;:::-;;;;61493:153;61662:16;;;;;:::i;:::-;;;;61410:280;61333:357;;;61709:13;61702:20;;;;;;61007:723;;;:::o;62341:110::-;32172:13;:11;:13::i;:::-;62436:7:::1;62416:17;;:27;;;;;;;;;;;;;;;;;;62341:110:::0;:::o;58124:33::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58301:32::-;;;;:::o;58536:44::-;;;;;;;;;;;;;;;;;:::o;58089:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;43854:223::-;43926:7;43946:13;43962:17;43971:7;43962:8;:17::i;:::-;43946:33;;44015:1;43998:19;;:5;:19;;;;43990:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;44064:5;44057:12;;;43854:223;;;:::o;58443:40::-;;;;;;;;;;;;;:::o;43585:207::-;43657:7;43702:1;43685:19;;:5;:19;;;;43677:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;43768:9;:16;43778:5;43768:16;;;;;;;;;;;;;;;;43761:23;;43585:207;;;:::o;32934:103::-;32172:13;:11;:13::i;:::-;32999:30:::1;33026:1;32999:18;:30::i;:::-;32934:103::o:0;63115:104::-;32172:13;:11;:13::i;:::-;63200:11:::1;63187:10;:24;;;;63115:104:::0;:::o;62887:106::-;32172:13;:11;:13::i;:::-;62975:10:::1;62963:9;:22;;;;;;;;;;;;:::i;:::-;;62887:106:::0;:::o;32286:87::-;32332:7;32359:6;;;;;;;;;;;32352:13;;32286:87;:::o;60627:140::-;60702:11;58917:9;;58902:11;58886:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;58878:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;32172:13:::1;:11;:13::i;:::-;60736:23:::2;60741:4;60747:11;60736:4;:23::i;:::-;60627:140:::0;;;:::o;44313:104::-;44369:13;44402:7;44395:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44313:104;:::o;62559:92::-;32172:13;:11;:13::i;:::-;62635:8:::1;62627:5;:16;;;;62559:92:::0;:::o;45899:155::-;45994:52;46013:12;:10;:12::i;:::-;46027:8;46037;45994:18;:52::i;:::-;45899:155;;:::o;58405:29::-;;;;:::o;64018:222::-;10693:1;9519:42;10647:43;;;:47;10643:225;;;9519:42;10716:40;;;10765:4;10772:10;10716:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10711:146;;10830:10;10811:30;;;;;;;;;;;:::i;:::-;;;;;;;;10711:146;10643:225;64185:47:::1;64208:4;64214:2;64218:7;64227:4;64185:22;:47::i;:::-;64018:222:::0;;;;:::o;58587:44::-;;;;;;;;;;;;;;;;;:::o;62217:116::-;32172:13;:11;:13::i;:::-;62318:7:::1;62295:20;;:30;;;;;;;;;;;;;;;;;;62217:116:::0;:::o;61738:471::-;61856:13;61905:16;61913:7;61905;:16::i;:::-;61887:105;;;;;;;;;;;;:::i;:::-;;;;;;;;;62005:28;62036:10;:8;:10::i;:::-;62005:41;;62095:1;62070:14;62064:28;:32;:137;;;;;;;;;;;;;;;;;62136:14;62152:18;:7;:16;:18::i;:::-;62172:9;62119:63;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;62064:137;62057:144;;;61738:471;;;:::o;62459:92::-;32172:13;:11;:13::i;:::-;62535:8:::1;62527:5;:16;;;;62459:92:::0;:::o;58255:31::-;;;;:::o;58170:35::-;;;;:::o;46125:164::-;46222:4;46246:18;:25;46265:5;46246:25;;;;;;;;;;;;;;;:35;46272:8;46246:35;;;;;;;;;;;;;;;;;;;;;;;;;46239:42;;46125:164;;;;:::o;58212:34::-;;;;:::o;33192:201::-;32172:13;:11;:13::i;:::-;33301:1:::1;33281:22;;:8;:22;;;;33273:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;33357:28;33376:8;33357:18;:28::i;:::-;33192:201:::0;:::o;62774:105::-;32172:13;:11;:13::i;:::-;62865:6:::1;62845:17;:26;;;;62774:105:::0;:::o;40656:157::-;40741:4;40780:25;40765:40;;;:11;:40;;;;40758:47;;40656:157;;;:::o;54297:135::-;54379:16;54387:7;54379;:16::i;:::-;54371:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;54297:135;:::o;31500:98::-;31553:7;31580:10;31573:17;;31500:98;:::o;53576:174::-;53678:2;53651:15;:24;53667:7;53651:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;53734:7;53730:2;53696:46;;53705:23;53720:7;53705:14;:23::i;:::-;53696:46;;;;;;;;;;;;53576:174;;:::o;32451:132::-;32526:12;:10;:12::i;:::-;32515:23;;:7;:5;:7::i;:::-;:23;;;32507:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;32451:132::o;46356:335::-;46551:41;46570:12;:10;:12::i;:::-;46584:7;46551:18;:41::i;:::-;46543:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;46655:28;46665:4;46671:2;46675:7;46655:9;:28::i;:::-;46356:335;;;:::o;11155:190::-;11280:4;11333;11304:25;11317:5;11324:4;11304:12;:25::i;:::-;:33;11297:40;;11155:190;;;;;:::o;60775:224::-;60841:9;60836:156;60860:5;60856:1;:9;60836:156;;;60887:24;60897:5;60904:6;;60887:9;:24::i;:::-;60944:1;60935:6;;:10;;;;:::i;:::-;60926:6;:19;;;;60867:3;;;;;:::i;:::-;;;;60836:156;;;;60775:224;;:::o;46762:185::-;46900:39;46917:4;46923:2;46927:7;46900:39;;;;;;;;;;;;:16;:39::i;:::-;46762:185;;;:::o;47775:117::-;47841:7;47868;:16;47876:7;47868:16;;;;;;;;;;;;;;;;;;;;;47861:23;;47775:117;;;:::o;33553:191::-;33627:16;33646:6;;;;;;;;;;;33627:25;;33672:8;33663:6;;:17;;;;;;;;;;;;;;;;;;33727:8;33696:40;;33717:8;33696:40;;;;;;;;;;;;33616:128;33553:191;:::o;53893:315::-;54048:8;54039:17;;:5;:17;;;;54031:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;54135:8;54097:18;:25;54116:5;54097:25;;;;;;;;;;;;;;;:35;54123:8;54097:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;54181:8;54159:41;;54174:5;54159:41;;;54191:8;54159:41;;;;;;:::i;:::-;;;;;;;;53893:315;;;:::o;47018:322::-;47192:41;47211:12;:10;:12::i;:::-;47225:7;47192:18;:41::i;:::-;47184:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;47294:38;47308:4;47314:2;47318:7;47327:4;47294:13;:38::i;:::-;47018:322;;;;:::o;47900:128::-;47965:4;48018:1;47989:31;;:17;47998:7;47989:8;:17::i;:::-;:31;;;;47982:38;;47900:128;;;:::o;63476:110::-;63536:13;63569:9;63562:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63476:110;:::o;29571:716::-;29627:13;29678:14;29715:1;29695:17;29706:5;29695:10;:17::i;:::-;:21;29678:38;;29731:20;29765:6;29754:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29731:41;;29787:11;29916:6;29912:2;29908:15;29900:6;29896:28;29889:35;;29953:288;29960:4;29953:288;;;29985:5;;;;;;;;30127:8;30122:2;30115:5;30111:14;30106:30;30101:3;30093:44;30183:2;30174:11;;;;;;:::i;:::-;;;;;30217:1;30208:5;:10;30204:21;;;30220:5;;30204:21;29953:288;;;30262:6;30255:13;;;;;29571:716;;;:::o;48195:264::-;48288:4;48305:13;48321:23;48336:7;48321:14;:23::i;:::-;48305:39;;48374:5;48363:16;;:7;:16;;;:52;;;;48383:32;48400:5;48407:7;48383:16;:32::i;:::-;48363:52;:87;;;;48443:7;48419:31;;:20;48431:7;48419:11;:20::i;:::-;:31;;;48363:87;48355:96;;;48195:264;;;;:::o;52194:1263::-;52353:4;52326:31;;:23;52341:7;52326:14;:23::i;:::-;:31;;;52318:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;52432:1;52418:16;;:2;:16;;;;52410:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;52488:42;52509:4;52515:2;52519:7;52528:1;52488:20;:42::i;:::-;52660:4;52633:31;;:23;52648:7;52633:14;:23::i;:::-;:31;;;52625:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;52778:15;:24;52794:7;52778:24;;;;;;;;;;;;52771:31;;;;;;;;;;;53273:1;53254:9;:15;53264:4;53254:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;53306:1;53289:9;:13;53299:2;53289:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;53348:2;53329:7;:16;53337:7;53329:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;53387:7;53383:2;53368:27;;53377:4;53368:27;;;;;;;;;;;;53408:41;53428:4;53434:2;53438:7;53447:1;53408:19;:41::i;:::-;52194:1263;;;:::o;11569:296::-;11652:7;11672:20;11695:4;11672:27;;11715:9;11710:118;11734:5;:12;11730:1;:16;11710:118;;;11783:33;11793:12;11807:5;11813:1;11807:8;;;;;;;;:::i;:::-;;;;;;;;11783:9;:33::i;:::-;11768:48;;11748:3;;;;;:::i;:::-;;;;11710:118;;;;11845:12;11838:19;;;11569:296;;;;:::o;48801:110::-;48877:26;48887:2;48891:7;48877:26;;;;;;;;;;;;:9;:26::i;:::-;48801:110;;:::o;47348:313::-;47504:28;47514:4;47520:2;47524:7;47504:9;:28::i;:::-;47551:47;47574:4;47580:2;47584:7;47593:4;47551:22;:47::i;:::-;47543:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;47348:313;;;;:::o;26631:922::-;26684:7;26704:14;26721:1;26704:18;;26771:6;26762:5;:15;26758:102;;26807:6;26798:15;;;;;;:::i;:::-;;;;;26842:2;26832:12;;;;26758:102;26887:6;26878:5;:15;26874:102;;26923:6;26914:15;;;;;;:::i;:::-;;;;;26958:2;26948:12;;;;26874:102;27003:6;26994:5;:15;26990:102;;27039:6;27030:15;;;;;;:::i;:::-;;;;;27074:2;27064:12;;;;26990:102;27119:5;27110;:14;27106:99;;27154:5;27145:14;;;;;;:::i;:::-;;;;;27188:1;27178:11;;;;27106:99;27232:5;27223;:14;27219:99;;27267:5;27258:14;;;;;;:::i;:::-;;;;;27301:1;27291:11;;;;27219:99;27345:5;27336;:14;27332:99;;27380:5;27371:14;;;;;;:::i;:::-;;;;;27414:1;27404:11;;;;27332:99;27458:5;27449;:14;27445:66;;27494:1;27484:11;;;;27445:66;27539:6;27532:13;;;26631:922;;;:::o;56581:410::-;56771:1;56759:9;:13;56755:229;;;56809:1;56793:18;;:4;:18;;;56789:87;;56851:9;56832;:15;56842:4;56832:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;56789:87;56908:1;56894:16;;:2;:16;;;56890:83;;56948:9;56931;:13;56941:2;56931:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;56890:83;56755:229;56581:410;;;;:::o;57713:158::-;;;;;:::o;16775:149::-;16838:7;16869:1;16865;:5;:51;;16896:20;16911:1;16914;16896:14;:20::i;:::-;16865:51;;;16873:20;16888:1;16891;16873:14;:20::i;:::-;16865:51;16858:58;;16775:149;;;;:::o;49138:319::-;49267:18;49273:2;49277:7;49267:5;:18::i;:::-;49318:53;49349:1;49353:2;49357:7;49366:4;49318:22;:53::i;:::-;49296:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;49138:319;;;:::o;54996:853::-;55150:4;55171:15;:2;:13;;;:15::i;:::-;55167:675;;;55223:2;55207:36;;;55244:12;:10;:12::i;:::-;55258:4;55264:7;55273:4;55207:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;55203:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55465:1;55448:6;:13;:18;55444:328;;;55491:60;;;;;;;;;;:::i;:::-;;;;;;;;55444:328;55722:6;55716:13;55707:6;55703:2;55699:15;55692:38;55203:584;55339:41;;;55329:51;;;:6;:51;;;;55322:58;;;;;55167:675;55826:4;55819:11;;54996:853;;;;;;;:::o;16932:268::-;17000:13;17107:1;17101:4;17094:15;17136:1;17130:4;17123:15;17177:4;17171;17161:21;17152:30;;16932:268;;;;:::o;49793:942::-;49887:1;49873:16;;:2;:16;;;;49865:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;49946:16;49954:7;49946;:16::i;:::-;49945:17;49937:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;50008:48;50037:1;50041:2;50045:7;50054:1;50008:20;:48::i;:::-;50155:16;50163:7;50155;:16::i;:::-;50154:17;50146:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;50570:1;50553:9;:13;50563:2;50553:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;50614:2;50595:7;:16;50603:7;50595:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;50659:7;50655:2;50634:33;;50651:1;50634:33;;;;;;;;;;;;50680:47;50708:1;50712:2;50716:7;50725:1;50680:19;:47::i;:::-;49793:942;;:::o;33782:326::-;33842:4;34099:1;34077:7;:19;;;:23;34070:30;;33782:326;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;1003:568::-;1076:8;1086:6;1136:3;1129:4;1121:6;1117:17;1113:27;1103:122;;1144:79;;:::i;:::-;1103:122;1257:6;1244:20;1234:30;;1287:18;1279:6;1276:30;1273:117;;;1309:79;;:::i;:::-;1273:117;1423:4;1415:6;1411:17;1399:29;;1477:3;1469:4;1461:6;1457:17;1447:8;1443:32;1440:41;1437:128;;;1484:79;;:::i;:::-;1437:128;1003:568;;;;;:::o;1577:133::-;1620:5;1658:6;1645:20;1636:29;;1674:30;1698:5;1674:30;:::i;:::-;1577:133;;;;:::o;1716:137::-;1770:5;1801:6;1795:13;1786:22;;1817:30;1841:5;1817:30;:::i;:::-;1716:137;;;;:::o;1859:139::-;1905:5;1943:6;1930:20;1921:29;;1959:33;1986:5;1959:33;:::i;:::-;1859:139;;;;:::o;2004:137::-;2049:5;2087:6;2074:20;2065:29;;2103:32;2129:5;2103:32;:::i;:::-;2004:137;;;;:::o;2147:141::-;2203:5;2234:6;2228:13;2219:22;;2250:32;2276:5;2250:32;:::i;:::-;2147:141;;;;:::o;2307:338::-;2362:5;2411:3;2404:4;2396:6;2392:17;2388:27;2378:122;;2419:79;;:::i;:::-;2378:122;2536:6;2523:20;2561:78;2635:3;2627:6;2620:4;2612:6;2608:17;2561:78;:::i;:::-;2552:87;;2368:277;2307:338;;;;:::o;2665:340::-;2721:5;2770:3;2763:4;2755:6;2751:17;2747:27;2737:122;;2778:79;;:::i;:::-;2737:122;2895:6;2882:20;2920:79;2995:3;2987:6;2980:4;2972:6;2968:17;2920:79;:::i;:::-;2911:88;;2727:278;2665:340;;;;:::o;3011:139::-;3057:5;3095:6;3082:20;3073:29;;3111:33;3138:5;3111:33;:::i;:::-;3011:139;;;;:::o;3156:329::-;3215:6;3264:2;3252:9;3243:7;3239:23;3235:32;3232:119;;;3270:79;;:::i;:::-;3232:119;3390:1;3415:53;3460:7;3451:6;3440:9;3436:22;3415:53;:::i;:::-;3405:63;;3361:117;3156:329;;;;:::o;3491:474::-;3559:6;3567;3616:2;3604:9;3595:7;3591:23;3587:32;3584:119;;;3622:79;;:::i;:::-;3584:119;3742:1;3767:53;3812:7;3803:6;3792:9;3788:22;3767:53;:::i;:::-;3757:63;;3713:117;3869:2;3895:53;3940:7;3931:6;3920:9;3916:22;3895:53;:::i;:::-;3885:63;;3840:118;3491:474;;;;;:::o;3971:619::-;4048:6;4056;4064;4113:2;4101:9;4092:7;4088:23;4084:32;4081:119;;;4119:79;;:::i;:::-;4081:119;4239:1;4264:53;4309:7;4300:6;4289:9;4285:22;4264:53;:::i;:::-;4254:63;;4210:117;4366:2;4392:53;4437:7;4428:6;4417:9;4413:22;4392:53;:::i;:::-;4382:63;;4337:118;4494:2;4520:53;4565:7;4556:6;4545:9;4541:22;4520:53;:::i;:::-;4510:63;;4465:118;3971:619;;;;;:::o;4596:943::-;4691:6;4699;4707;4715;4764:3;4752:9;4743:7;4739:23;4735:33;4732:120;;;4771:79;;:::i;:::-;4732:120;4891:1;4916:53;4961:7;4952:6;4941:9;4937:22;4916:53;:::i;:::-;4906:63;;4862:117;5018:2;5044:53;5089:7;5080:6;5069:9;5065:22;5044:53;:::i;:::-;5034:63;;4989:118;5146:2;5172:53;5217:7;5208:6;5197:9;5193:22;5172:53;:::i;:::-;5162:63;;5117:118;5302:2;5291:9;5287:18;5274:32;5333:18;5325:6;5322:30;5319:117;;;5355:79;;:::i;:::-;5319:117;5460:62;5514:7;5505:6;5494:9;5490:22;5460:62;:::i;:::-;5450:72;;5245:287;4596:943;;;;;;;:::o;5545:468::-;5610:6;5618;5667:2;5655:9;5646:7;5642:23;5638:32;5635:119;;;5673:79;;:::i;:::-;5635:119;5793:1;5818:53;5863:7;5854:6;5843:9;5839:22;5818:53;:::i;:::-;5808:63;;5764:117;5920:2;5946:50;5988:7;5979:6;5968:9;5964:22;5946:50;:::i;:::-;5936:60;;5891:115;5545:468;;;;;:::o;6019:474::-;6087:6;6095;6144:2;6132:9;6123:7;6119:23;6115:32;6112:119;;;6150:79;;:::i;:::-;6112:119;6270:1;6295:53;6340:7;6331:6;6320:9;6316:22;6295:53;:::i;:::-;6285:63;;6241:117;6397:2;6423:53;6468:7;6459:6;6448:9;6444:22;6423:53;:::i;:::-;6413:63;;6368:118;6019:474;;;;;:::o;6499:704::-;6594:6;6602;6610;6659:2;6647:9;6638:7;6634:23;6630:32;6627:119;;;6665:79;;:::i;:::-;6627:119;6813:1;6802:9;6798:17;6785:31;6843:18;6835:6;6832:30;6829:117;;;6865:79;;:::i;:::-;6829:117;6978:80;7050:7;7041:6;7030:9;7026:22;6978:80;:::i;:::-;6960:98;;;;6756:312;7107:2;7133:53;7178:7;7169:6;7158:9;7154:22;7133:53;:::i;:::-;7123:63;;7078:118;6499:704;;;;;:::o;7209:323::-;7265:6;7314:2;7302:9;7293:7;7289:23;7285:32;7282:119;;;7320:79;;:::i;:::-;7282:119;7440:1;7465:50;7507:7;7498:6;7487:9;7483:22;7465:50;:::i;:::-;7455:60;;7411:114;7209:323;;;;:::o;7538:345::-;7605:6;7654:2;7642:9;7633:7;7629:23;7625:32;7622:119;;;7660:79;;:::i;:::-;7622:119;7780:1;7805:61;7858:7;7849:6;7838:9;7834:22;7805:61;:::i;:::-;7795:71;;7751:125;7538:345;;;;:::o;7889:329::-;7948:6;7997:2;7985:9;7976:7;7972:23;7968:32;7965:119;;;8003:79;;:::i;:::-;7965:119;8123:1;8148:53;8193:7;8184:6;8173:9;8169:22;8148:53;:::i;:::-;8138:63;;8094:117;7889:329;;;;:::o;8224:327::-;8282:6;8331:2;8319:9;8310:7;8306:23;8302:32;8299:119;;;8337:79;;:::i;:::-;8299:119;8457:1;8482:52;8526:7;8517:6;8506:9;8502:22;8482:52;:::i;:::-;8472:62;;8428:116;8224:327;;;;:::o;8557:349::-;8626:6;8675:2;8663:9;8654:7;8650:23;8646:32;8643:119;;;8681:79;;:::i;:::-;8643:119;8801:1;8826:63;8881:7;8872:6;8861:9;8857:22;8826:63;:::i;:::-;8816:73;;8772:127;8557:349;;;;:::o;8912:509::-;8981:6;9030:2;9018:9;9009:7;9005:23;9001:32;8998:119;;;9036:79;;:::i;:::-;8998:119;9184:1;9173:9;9169:17;9156:31;9214:18;9206:6;9203:30;9200:117;;;9236:79;;:::i;:::-;9200:117;9341:63;9396:7;9387:6;9376:9;9372:22;9341:63;:::i;:::-;9331:73;;9127:287;8912:509;;;;:::o;9427:329::-;9486:6;9535:2;9523:9;9514:7;9510:23;9506:32;9503:119;;;9541:79;;:::i;:::-;9503:119;9661:1;9686:53;9731:7;9722:6;9711:9;9707:22;9686:53;:::i;:::-;9676:63;;9632:117;9427:329;;;;:::o;9762:179::-;9831:10;9852:46;9894:3;9886:6;9852:46;:::i;:::-;9930:4;9925:3;9921:14;9907:28;;9762:179;;;;:::o;9947:118::-;10034:24;10052:5;10034:24;:::i;:::-;10029:3;10022:37;9947:118;;:::o;10071:157::-;10176:45;10196:24;10214:5;10196:24;:::i;:::-;10176:45;:::i;:::-;10171:3;10164:58;10071:157;;:::o;10264:732::-;10383:3;10412:54;10460:5;10412:54;:::i;:::-;10482:86;10561:6;10556:3;10482:86;:::i;:::-;10475:93;;10592:56;10642:5;10592:56;:::i;:::-;10671:7;10702:1;10687:284;10712:6;10709:1;10706:13;10687:284;;;10788:6;10782:13;10815:63;10874:3;10859:13;10815:63;:::i;:::-;10808:70;;10901:60;10954:6;10901:60;:::i;:::-;10891:70;;10747:224;10734:1;10731;10727:9;10722:14;;10687:284;;;10691:14;10987:3;10980:10;;10388:608;;;10264:732;;;;:::o;11002:109::-;11083:21;11098:5;11083:21;:::i;:::-;11078:3;11071:34;11002:109;;:::o;11117:118::-;11204:24;11222:5;11204:24;:::i;:::-;11199:3;11192:37;11117:118;;:::o;11241:360::-;11327:3;11355:38;11387:5;11355:38;:::i;:::-;11409:70;11472:6;11467:3;11409:70;:::i;:::-;11402:77;;11488:52;11533:6;11528:3;11521:4;11514:5;11510:16;11488:52;:::i;:::-;11565:29;11587:6;11565:29;:::i;:::-;11560:3;11556:39;11549:46;;11331:270;11241:360;;;;:::o;11607:364::-;11695:3;11723:39;11756:5;11723:39;:::i;:::-;11778:71;11842:6;11837:3;11778:71;:::i;:::-;11771:78;;11858:52;11903:6;11898:3;11891:4;11884:5;11880:16;11858:52;:::i;:::-;11935:29;11957:6;11935:29;:::i;:::-;11930:3;11926:39;11919:46;;11699:272;11607:364;;;;:::o;11977:377::-;12083:3;12111:39;12144:5;12111:39;:::i;:::-;12166:89;12248:6;12243:3;12166:89;:::i;:::-;12159:96;;12264:52;12309:6;12304:3;12297:4;12290:5;12286:16;12264:52;:::i;:::-;12341:6;12336:3;12332:16;12325:23;;12087:267;11977:377;;;;:::o;12384:845::-;12487:3;12524:5;12518:12;12553:36;12579:9;12553:36;:::i;:::-;12605:89;12687:6;12682:3;12605:89;:::i;:::-;12598:96;;12725:1;12714:9;12710:17;12741:1;12736:137;;;;12887:1;12882:341;;;;12703:520;;12736:137;12820:4;12816:9;12805;12801:25;12796:3;12789:38;12856:6;12851:3;12847:16;12840:23;;12736:137;;12882:341;12949:38;12981:5;12949:38;:::i;:::-;13009:1;13023:154;13037:6;13034:1;13031:13;13023:154;;;13111:7;13105:14;13101:1;13096:3;13092:11;13085:35;13161:1;13152:7;13148:15;13137:26;;13059:4;13056:1;13052:12;13047:17;;13023:154;;;13206:6;13201:3;13197:16;13190:23;;12889:334;;12703:520;;12491:738;;12384:845;;;;:::o;13235:366::-;13377:3;13398:67;13462:2;13457:3;13398:67;:::i;:::-;13391:74;;13474:93;13563:3;13474:93;:::i;:::-;13592:2;13587:3;13583:12;13576:19;;13235:366;;;:::o;13607:::-;13749:3;13770:67;13834:2;13829:3;13770:67;:::i;:::-;13763:74;;13846:93;13935:3;13846:93;:::i;:::-;13964:2;13959:3;13955:12;13948:19;;13607:366;;;:::o;13979:::-;14121:3;14142:67;14206:2;14201:3;14142:67;:::i;:::-;14135:74;;14218:93;14307:3;14218:93;:::i;:::-;14336:2;14331:3;14327:12;14320:19;;13979:366;;;:::o;14351:::-;14493:3;14514:67;14578:2;14573:3;14514:67;:::i;:::-;14507:74;;14590:93;14679:3;14590:93;:::i;:::-;14708:2;14703:3;14699:12;14692:19;;14351:366;;;:::o;14723:::-;14865:3;14886:67;14950:2;14945:3;14886:67;:::i;:::-;14879:74;;14962:93;15051:3;14962:93;:::i;:::-;15080:2;15075:3;15071:12;15064:19;;14723:366;;;:::o;15095:::-;15237:3;15258:67;15322:2;15317:3;15258:67;:::i;:::-;15251:74;;15334:93;15423:3;15334:93;:::i;:::-;15452:2;15447:3;15443:12;15436:19;;15095:366;;;:::o;15467:::-;15609:3;15630:67;15694:2;15689:3;15630:67;:::i;:::-;15623:74;;15706:93;15795:3;15706:93;:::i;:::-;15824:2;15819:3;15815:12;15808:19;;15467:366;;;:::o;15839:::-;15981:3;16002:67;16066:2;16061:3;16002:67;:::i;:::-;15995:74;;16078:93;16167:3;16078:93;:::i;:::-;16196:2;16191:3;16187:12;16180:19;;15839:366;;;:::o;16211:::-;16353:3;16374:67;16438:2;16433:3;16374:67;:::i;:::-;16367:74;;16450:93;16539:3;16450:93;:::i;:::-;16568:2;16563:3;16559:12;16552:19;;16211:366;;;:::o;16583:::-;16725:3;16746:67;16810:2;16805:3;16746:67;:::i;:::-;16739:74;;16822:93;16911:3;16822:93;:::i;:::-;16940:2;16935:3;16931:12;16924:19;;16583:366;;;:::o;16955:::-;17097:3;17118:67;17182:2;17177:3;17118:67;:::i;:::-;17111:74;;17194:93;17283:3;17194:93;:::i;:::-;17312:2;17307:3;17303:12;17296:19;;16955:366;;;:::o;17327:::-;17469:3;17490:67;17554:2;17549:3;17490:67;:::i;:::-;17483:74;;17566:93;17655:3;17566:93;:::i;:::-;17684:2;17679:3;17675:12;17668:19;;17327:366;;;:::o;17699:::-;17841:3;17862:67;17926:2;17921:3;17862:67;:::i;:::-;17855:74;;17938:93;18027:3;17938:93;:::i;:::-;18056:2;18051:3;18047:12;18040:19;;17699:366;;;:::o;18071:::-;18213:3;18234:67;18298:2;18293:3;18234:67;:::i;:::-;18227:74;;18310:93;18399:3;18310:93;:::i;:::-;18428:2;18423:3;18419:12;18412:19;;18071:366;;;:::o;18443:::-;18585:3;18606:67;18670:2;18665:3;18606:67;:::i;:::-;18599:74;;18682:93;18771:3;18682:93;:::i;:::-;18800:2;18795:3;18791:12;18784:19;;18443:366;;;:::o;18815:::-;18957:3;18978:67;19042:2;19037:3;18978:67;:::i;:::-;18971:74;;19054:93;19143:3;19054:93;:::i;:::-;19172:2;19167:3;19163:12;19156:19;;18815:366;;;:::o;19187:398::-;19346:3;19367:83;19448:1;19443:3;19367:83;:::i;:::-;19360:90;;19459:93;19548:3;19459:93;:::i;:::-;19577:1;19572:3;19568:11;19561:18;;19187:398;;;:::o;19591:366::-;19733:3;19754:67;19818:2;19813:3;19754:67;:::i;:::-;19747:74;;19830:93;19919:3;19830:93;:::i;:::-;19948:2;19943:3;19939:12;19932:19;;19591:366;;;:::o;19963:::-;20105:3;20126:67;20190:2;20185:3;20126:67;:::i;:::-;20119:74;;20202:93;20291:3;20202:93;:::i;:::-;20320:2;20315:3;20311:12;20304:19;;19963:366;;;:::o;20335:::-;20477:3;20498:67;20562:2;20557:3;20498:67;:::i;:::-;20491:74;;20574:93;20663:3;20574:93;:::i;:::-;20692:2;20687:3;20683:12;20676:19;;20335:366;;;:::o;20707:::-;20849:3;20870:67;20934:2;20929:3;20870:67;:::i;:::-;20863:74;;20946:93;21035:3;20946:93;:::i;:::-;21064:2;21059:3;21055:12;21048:19;;20707:366;;;:::o;21079:::-;21221:3;21242:67;21306:2;21301:3;21242:67;:::i;:::-;21235:74;;21318:93;21407:3;21318:93;:::i;:::-;21436:2;21431:3;21427:12;21420:19;;21079:366;;;:::o;21451:108::-;21528:24;21546:5;21528:24;:::i;:::-;21523:3;21516:37;21451:108;;:::o;21565:118::-;21652:24;21670:5;21652:24;:::i;:::-;21647:3;21640:37;21565:118;;:::o;21689:256::-;21801:3;21816:75;21887:3;21878:6;21816:75;:::i;:::-;21916:2;21911:3;21907:12;21900:19;;21936:3;21929:10;;21689:256;;;;:::o;21951:589::-;22176:3;22198:95;22289:3;22280:6;22198:95;:::i;:::-;22191:102;;22310:95;22401:3;22392:6;22310:95;:::i;:::-;22303:102;;22422:92;22510:3;22501:6;22422:92;:::i;:::-;22415:99;;22531:3;22524:10;;21951:589;;;;;;:::o;22546:379::-;22730:3;22752:147;22895:3;22752:147;:::i;:::-;22745:154;;22916:3;22909:10;;22546:379;;;:::o;22931:222::-;23024:4;23062:2;23051:9;23047:18;23039:26;;23075:71;23143:1;23132:9;23128:17;23119:6;23075:71;:::i;:::-;22931:222;;;;:::o;23159:332::-;23280:4;23318:2;23307:9;23303:18;23295:26;;23331:71;23399:1;23388:9;23384:17;23375:6;23331:71;:::i;:::-;23412:72;23480:2;23469:9;23465:18;23456:6;23412:72;:::i;:::-;23159:332;;;;;:::o;23497:640::-;23692:4;23730:3;23719:9;23715:19;23707:27;;23744:71;23812:1;23801:9;23797:17;23788:6;23744:71;:::i;:::-;23825:72;23893:2;23882:9;23878:18;23869:6;23825:72;:::i;:::-;23907;23975:2;23964:9;23960:18;23951:6;23907:72;:::i;:::-;24026:9;24020:4;24016:20;24011:2;24000:9;23996:18;23989:48;24054:76;24125:4;24116:6;24054:76;:::i;:::-;24046:84;;23497:640;;;;;;;:::o;24143:373::-;24286:4;24324:2;24313:9;24309:18;24301:26;;24373:9;24367:4;24363:20;24359:1;24348:9;24344:17;24337:47;24401:108;24504:4;24495:6;24401:108;:::i;:::-;24393:116;;24143:373;;;;:::o;24522:210::-;24609:4;24647:2;24636:9;24632:18;24624:26;;24660:65;24722:1;24711:9;24707:17;24698:6;24660:65;:::i;:::-;24522:210;;;;:::o;24738:222::-;24831:4;24869:2;24858:9;24854:18;24846:26;;24882:71;24950:1;24939:9;24935:17;24926:6;24882:71;:::i;:::-;24738:222;;;;:::o;24966:313::-;25079:4;25117:2;25106:9;25102:18;25094:26;;25166:9;25160:4;25156:20;25152:1;25141:9;25137:17;25130:47;25194:78;25267:4;25258:6;25194:78;:::i;:::-;25186:86;;24966:313;;;;:::o;25285:419::-;25451:4;25489:2;25478:9;25474:18;25466:26;;25538:9;25532:4;25528:20;25524:1;25513:9;25509:17;25502:47;25566:131;25692:4;25566:131;:::i;:::-;25558:139;;25285:419;;;:::o;25710:::-;25876:4;25914:2;25903:9;25899:18;25891:26;;25963:9;25957:4;25953:20;25949:1;25938:9;25934:17;25927:47;25991:131;26117:4;25991:131;:::i;:::-;25983:139;;25710:419;;;:::o;26135:::-;26301:4;26339:2;26328:9;26324:18;26316:26;;26388:9;26382:4;26378:20;26374:1;26363:9;26359:17;26352:47;26416:131;26542:4;26416:131;:::i;:::-;26408:139;;26135:419;;;:::o;26560:::-;26726:4;26764:2;26753:9;26749:18;26741:26;;26813:9;26807:4;26803:20;26799:1;26788:9;26784:17;26777:47;26841:131;26967:4;26841:131;:::i;:::-;26833:139;;26560:419;;;:::o;26985:::-;27151:4;27189:2;27178:9;27174:18;27166:26;;27238:9;27232:4;27228:20;27224:1;27213:9;27209:17;27202:47;27266:131;27392:4;27266:131;:::i;:::-;27258:139;;26985:419;;;:::o;27410:::-;27576:4;27614:2;27603:9;27599:18;27591:26;;27663:9;27657:4;27653:20;27649:1;27638:9;27634:17;27627:47;27691:131;27817:4;27691:131;:::i;:::-;27683:139;;27410:419;;;:::o;27835:::-;28001:4;28039:2;28028:9;28024:18;28016:26;;28088:9;28082:4;28078:20;28074:1;28063:9;28059:17;28052:47;28116:131;28242:4;28116:131;:::i;:::-;28108:139;;27835:419;;;:::o;28260:::-;28426:4;28464:2;28453:9;28449:18;28441:26;;28513:9;28507:4;28503:20;28499:1;28488:9;28484:17;28477:47;28541:131;28667:4;28541:131;:::i;:::-;28533:139;;28260:419;;;:::o;28685:::-;28851:4;28889:2;28878:9;28874:18;28866:26;;28938:9;28932:4;28928:20;28924:1;28913:9;28909:17;28902:47;28966:131;29092:4;28966:131;:::i;:::-;28958:139;;28685:419;;;:::o;29110:::-;29276:4;29314:2;29303:9;29299:18;29291:26;;29363:9;29357:4;29353:20;29349:1;29338:9;29334:17;29327:47;29391:131;29517:4;29391:131;:::i;:::-;29383:139;;29110:419;;;:::o;29535:::-;29701:4;29739:2;29728:9;29724:18;29716:26;;29788:9;29782:4;29778:20;29774:1;29763:9;29759:17;29752:47;29816:131;29942:4;29816:131;:::i;:::-;29808:139;;29535:419;;;:::o;29960:::-;30126:4;30164:2;30153:9;30149:18;30141:26;;30213:9;30207:4;30203:20;30199:1;30188:9;30184:17;30177:47;30241:131;30367:4;30241:131;:::i;:::-;30233:139;;29960:419;;;:::o;30385:::-;30551:4;30589:2;30578:9;30574:18;30566:26;;30638:9;30632:4;30628:20;30624:1;30613:9;30609:17;30602:47;30666:131;30792:4;30666:131;:::i;:::-;30658:139;;30385:419;;;:::o;30810:::-;30976:4;31014:2;31003:9;30999:18;30991:26;;31063:9;31057:4;31053:20;31049:1;31038:9;31034:17;31027:47;31091:131;31217:4;31091:131;:::i;:::-;31083:139;;30810:419;;;:::o;31235:::-;31401:4;31439:2;31428:9;31424:18;31416:26;;31488:9;31482:4;31478:20;31474:1;31463:9;31459:17;31452:47;31516:131;31642:4;31516:131;:::i;:::-;31508:139;;31235:419;;;:::o;31660:::-;31826:4;31864:2;31853:9;31849:18;31841:26;;31913:9;31907:4;31903:20;31899:1;31888:9;31884:17;31877:47;31941:131;32067:4;31941:131;:::i;:::-;31933:139;;31660:419;;;:::o;32085:::-;32251:4;32289:2;32278:9;32274:18;32266:26;;32338:9;32332:4;32328:20;32324:1;32313:9;32309:17;32302:47;32366:131;32492:4;32366:131;:::i;:::-;32358:139;;32085:419;;;:::o;32510:::-;32676:4;32714:2;32703:9;32699:18;32691:26;;32763:9;32757:4;32753:20;32749:1;32738:9;32734:17;32727:47;32791:131;32917:4;32791:131;:::i;:::-;32783:139;;32510:419;;;:::o;32935:::-;33101:4;33139:2;33128:9;33124:18;33116:26;;33188:9;33182:4;33178:20;33174:1;33163:9;33159:17;33152:47;33216:131;33342:4;33216:131;:::i;:::-;33208:139;;32935:419;;;:::o;33360:::-;33526:4;33564:2;33553:9;33549:18;33541:26;;33613:9;33607:4;33603:20;33599:1;33588:9;33584:17;33577:47;33641:131;33767:4;33641:131;:::i;:::-;33633:139;;33360:419;;;:::o;33785:::-;33951:4;33989:2;33978:9;33974:18;33966:26;;34038:9;34032:4;34028:20;34024:1;34013:9;34009:17;34002:47;34066:131;34192:4;34066:131;:::i;:::-;34058:139;;33785:419;;;:::o;34210:222::-;34303:4;34341:2;34330:9;34326:18;34318:26;;34354:71;34422:1;34411:9;34407:17;34398:6;34354:71;:::i;:::-;34210:222;;;;:::o;34438:129::-;34472:6;34499:20;;:::i;:::-;34489:30;;34528:33;34556:4;34548:6;34528:33;:::i;:::-;34438:129;;;:::o;34573:75::-;34606:6;34639:2;34633:9;34623:19;;34573:75;:::o;34654:307::-;34715:4;34805:18;34797:6;34794:30;34791:56;;;34827:18;;:::i;:::-;34791:56;34865:29;34887:6;34865:29;:::i;:::-;34857:37;;34949:4;34943;34939:15;34931:23;;34654:307;;;:::o;34967:308::-;35029:4;35119:18;35111:6;35108:30;35105:56;;;35141:18;;:::i;:::-;35105:56;35179:29;35201:6;35179:29;:::i;:::-;35171:37;;35263:4;35257;35253:15;35245:23;;34967:308;;;:::o;35281:132::-;35348:4;35371:3;35363:11;;35401:4;35396:3;35392:14;35384:22;;35281:132;;;:::o;35419:141::-;35468:4;35491:3;35483:11;;35514:3;35511:1;35504:14;35548:4;35545:1;35535:18;35527:26;;35419:141;;;:::o;35566:114::-;35633:6;35667:5;35661:12;35651:22;;35566:114;;;:::o;35686:98::-;35737:6;35771:5;35765:12;35755:22;;35686:98;;;:::o;35790:99::-;35842:6;35876:5;35870:12;35860:22;;35790:99;;;:::o;35895:113::-;35965:4;35997;35992:3;35988:14;35980:22;;35895:113;;;:::o;36014:184::-;36113:11;36147:6;36142:3;36135:19;36187:4;36182:3;36178:14;36163:29;;36014:184;;;;:::o;36204:168::-;36287:11;36321:6;36316:3;36309:19;36361:4;36356:3;36352:14;36337:29;;36204:168;;;;:::o;36378:147::-;36479:11;36516:3;36501:18;;36378:147;;;;:::o;36531:169::-;36615:11;36649:6;36644:3;36637:19;36689:4;36684:3;36680:14;36665:29;;36531:169;;;;:::o;36706:148::-;36808:11;36845:3;36830:18;;36706:148;;;;:::o;36860:305::-;36900:3;36919:20;36937:1;36919:20;:::i;:::-;36914:25;;36953:20;36971:1;36953:20;:::i;:::-;36948:25;;37107:1;37039:66;37035:74;37032:1;37029:81;37026:107;;;37113:18;;:::i;:::-;37026:107;37157:1;37154;37150:9;37143:16;;36860:305;;;;:::o;37171:348::-;37211:7;37234:20;37252:1;37234:20;:::i;:::-;37229:25;;37268:20;37286:1;37268:20;:::i;:::-;37263:25;;37456:1;37388:66;37384:74;37381:1;37378:81;37373:1;37366:9;37359:17;37355:105;37352:131;;;37463:18;;:::i;:::-;37352:131;37511:1;37508;37504:9;37493:20;;37171:348;;;;:::o;37525:191::-;37565:4;37585:20;37603:1;37585:20;:::i;:::-;37580:25;;37619:20;37637:1;37619:20;:::i;:::-;37614:25;;37658:1;37655;37652:8;37649:34;;;37663:18;;:::i;:::-;37649:34;37708:1;37705;37701:9;37693:17;;37525:191;;;;:::o;37722:96::-;37759:7;37788:24;37806:5;37788:24;:::i;:::-;37777:35;;37722:96;;;:::o;37824:90::-;37858:7;37901:5;37894:13;37887:21;37876:32;;37824:90;;;:::o;37920:77::-;37957:7;37986:5;37975:16;;37920:77;;;:::o;38003:149::-;38039:7;38079:66;38072:5;38068:78;38057:89;;38003:149;;;:::o;38158:126::-;38195:7;38235:42;38228:5;38224:54;38213:65;;38158:126;;;:::o;38290:77::-;38327:7;38356:5;38345:16;;38290:77;;;:::o;38373:154::-;38457:6;38452:3;38447;38434:30;38519:1;38510:6;38505:3;38501:16;38494:27;38373:154;;;:::o;38533:307::-;38601:1;38611:113;38625:6;38622:1;38619:13;38611:113;;;38710:1;38705:3;38701:11;38695:18;38691:1;38686:3;38682:11;38675:39;38647:2;38644:1;38640:10;38635:15;;38611:113;;;38742:6;38739:1;38736:13;38733:101;;;38822:1;38813:6;38808:3;38804:16;38797:27;38733:101;38582:258;38533:307;;;:::o;38846:320::-;38890:6;38927:1;38921:4;38917:12;38907:22;;38974:1;38968:4;38964:12;38995:18;38985:81;;39051:4;39043:6;39039:17;39029:27;;38985:81;39113:2;39105:6;39102:14;39082:18;39079:38;39076:84;;;39132:18;;:::i;:::-;39076:84;38897:269;38846:320;;;:::o;39172:281::-;39255:27;39277:4;39255:27;:::i;:::-;39247:6;39243:40;39385:6;39373:10;39370:22;39349:18;39337:10;39334:34;39331:62;39328:88;;;39396:18;;:::i;:::-;39328:88;39436:10;39432:2;39425:22;39215:238;39172:281;;:::o;39459:233::-;39498:3;39521:24;39539:5;39521:24;:::i;:::-;39512:33;;39567:66;39560:5;39557:77;39554:103;;;39637:18;;:::i;:::-;39554:103;39684:1;39677:5;39673:13;39666:20;;39459:233;;;:::o;39698:100::-;39737:7;39766:26;39786:5;39766:26;:::i;:::-;39755:37;;39698:100;;;:::o;39804:94::-;39843:7;39872:20;39886:5;39872:20;:::i;:::-;39861:31;;39804:94;;;:::o;39904:180::-;39952:77;39949:1;39942:88;40049:4;40046:1;40039:15;40073:4;40070:1;40063:15;40090:180;40138:77;40135:1;40128:88;40235:4;40232:1;40225:15;40259:4;40256:1;40249:15;40276:180;40324:77;40321:1;40314:88;40421:4;40418:1;40411:15;40445:4;40442:1;40435:15;40462:180;40510:77;40507:1;40500:88;40607:4;40604:1;40597:15;40631:4;40628:1;40621:15;40648:180;40696:77;40693:1;40686:88;40793:4;40790:1;40783:15;40817:4;40814:1;40807:15;40834:117;40943:1;40940;40933:12;40957:117;41066:1;41063;41056:12;41080:117;41189:1;41186;41179:12;41203:117;41312:1;41309;41302:12;41326:117;41435:1;41432;41425:12;41449:117;41558:1;41555;41548:12;41572:102;41613:6;41664:2;41660:7;41655:2;41648:5;41644:14;41640:28;41630:38;;41572:102;;;:::o;41680:94::-;41713:8;41761:5;41757:2;41753:14;41732:35;;41680:94;;;:::o;41780:232::-;41920:34;41916:1;41908:6;41904:14;41897:58;41989:15;41984:2;41976:6;41972:15;41965:40;41780:232;:::o;42018:164::-;42158:16;42154:1;42146:6;42142:14;42135:40;42018:164;:::o;42188:237::-;42328:34;42324:1;42316:6;42312:14;42305:58;42397:20;42392:2;42384:6;42380:15;42373:45;42188:237;:::o;42431:225::-;42571:34;42567:1;42559:6;42555:14;42548:58;42640:8;42635:2;42627:6;42623:15;42616:33;42431:225;:::o;42662:224::-;42802:34;42798:1;42790:6;42786:14;42779:58;42871:7;42866:2;42858:6;42854:15;42847:32;42662:224;:::o;42892:178::-;43032:30;43028:1;43020:6;43016:14;43009:54;42892:178;:::o;43076:170::-;43216:22;43212:1;43204:6;43200:14;43193:46;43076:170;:::o;43252:::-;43392:22;43388:1;43380:6;43376:14;43369:46;43252:170;:::o;43428:223::-;43568:34;43564:1;43556:6;43552:14;43545:58;43637:6;43632:2;43624:6;43620:15;43613:31;43428:223;:::o;43657:175::-;43797:27;43793:1;43785:6;43781:14;43774:51;43657:175;:::o;43838:228::-;43978:34;43974:1;43966:6;43962:14;43955:58;44047:11;44042:2;44034:6;44030:15;44023:36;43838:228;:::o;44072:182::-;44212:34;44208:1;44200:6;44196:14;44189:58;44072:182;:::o;44260:::-;44400:34;44396:1;44388:6;44384:14;44377:58;44260:182;:::o;44448:234::-;44588:34;44584:1;44576:6;44572:14;44565:58;44657:17;44652:2;44644:6;44640:15;44633:42;44448:234;:::o;44688:174::-;44828:26;44824:1;44816:6;44812:14;44805:50;44688:174;:::o;44868:220::-;45008:34;45004:1;44996:6;44992:14;44985:58;45077:3;45072:2;45064:6;45060:15;45053:28;44868:220;:::o;45094:114::-;;:::o;45214:170::-;45354:22;45350:1;45342:6;45338:14;45331:46;45214:170;:::o;45390:248::-;45530:34;45526:1;45518:6;45514:14;45507:58;45599:31;45594:2;45586:6;45582:15;45575:56;45390:248;:::o;45644:173::-;45784:25;45780:1;45772:6;45768:14;45761:49;45644:173;:::o;45823:172::-;45963:24;45959:1;45951:6;45947:14;45940:48;45823:172;:::o;46001:169::-;46141:21;46137:1;46129:6;46125:14;46118:45;46001:169;:::o;46176:122::-;46249:24;46267:5;46249:24;:::i;:::-;46242:5;46239:35;46229:63;;46288:1;46285;46278:12;46229:63;46176:122;:::o;46304:116::-;46374:21;46389:5;46374:21;:::i;:::-;46367:5;46364:32;46354:60;;46410:1;46407;46400:12;46354:60;46304:116;:::o;46426:122::-;46499:24;46517:5;46499:24;:::i;:::-;46492:5;46489:35;46479:63;;46538:1;46535;46528:12;46479:63;46426:122;:::o;46554:120::-;46626:23;46643:5;46626:23;:::i;:::-;46619:5;46616:34;46606:62;;46664:1;46661;46654:12;46606:62;46554:120;:::o;46680:122::-;46753:24;46771:5;46753:24;:::i;:::-;46746:5;46743:35;46733:63;;46792:1;46789;46782:12;46733:63;46680:122;:::o

Swarm Source

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