ETH Price: $2,489.27 (-1.14%)

Token

HackerHaiku (HAH)
 

Overview

Max Total Supply

0 HAH

Holders

431

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 HAH
0x3A04e66f6a805f3F0645Beca0a1d4F0024eb70c4
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:
HackerHaiku

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-01-11
*/

// File: Base64.sol



pragma solidity >=0.6.0;

/// @title Base64
/// @author Brecht Devos - <[email protected]>
/// @notice Provides functions for encoding/decoding base64
library Base64 {
    string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    bytes  internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
                                            hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
                                            hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
                                            hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";

    function encode(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return '';

        // load the table into memory
        string memory table = TABLE_ENCODE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
                // read 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // write 4 characters
                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(        input,  0x3F))))
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }

        return result;
    }

    function decode(string memory _data) internal pure returns (bytes memory) {
        bytes memory data = bytes(_data);

        if (data.length == 0) return new bytes(0);
        require(data.length % 4 == 0, "invalid base64 decoder input");

        // load the table into memory
        bytes memory table = TABLE_DECODE;

        // every 4 characters represent 3 bytes
        uint256 decodedLen = (data.length / 4) * 3;

        // add some extra buffer at the end required for the writing
        bytes memory result = new bytes(decodedLen + 32);

        assembly {
            // padding with '='
            let lastBytes := mload(add(data, mload(data)))
            if eq(and(lastBytes, 0xFF), 0x3d) {
                decodedLen := sub(decodedLen, 1)
                if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
                    decodedLen := sub(decodedLen, 1)
                }
            }

            // set the actual output length
            mstore(result, decodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 4 characters at a time
            for {} lt(dataPtr, endPtr) {}
            {
               // read 4 characters
               dataPtr := add(dataPtr, 4)
               let input := mload(dataPtr)

               // write 3 bytes
               let output := add(
                   add(
                       shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
                       shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
                   add(
                       shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
                               and(mload(add(tablePtr, and(        input , 0xFF))), 0xFF)
                    )
                )
                mstore(resultPtr, shl(232, output))
                resultPtr := add(resultPtr, 3)
            }
        }

        return result;
    }
}
// File: @openzeppelin/contracts/utils/math/Math.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                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);
        }
    }
}

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


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

pragma solidity ^0.8.0;


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

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

    /**
     * @dev Converts a `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);
    }
}

// File: VerifySignature.sol


pragma solidity ^0.8.13;


/* Signature Verification

How to Sign and Verify
# Signing
1. Create message to sign
2. Hash the message
3. Sign the hash (off chain, keep your private key secret)

# Verify
1. Recreate hash from the original message
2. Recover signer from signature and hash
3. Compare recovered signer to claimed signer
*/

contract VerifySignature {
    /* 1. Unlock MetaMask account
    ethereum.enable()
    */

    /* 2. Get message hash to sign
    getMessageHash(
        0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C,
        123,
        "coffee and donuts",
        1
    )

    hash = "0xcf36ac4f97dc10d91fc2cbb20d718e94a8cbfe0f82eaedc6a4aa38946fb797cd"
    */
    function getMessageHash(
        address _to,
        uint _amount,
        string memory _message,
        uint _nonce
    ) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(_to, _amount, _message, _nonce));
    }

    /* 3. Sign message hash
    # using browser
    account = "copy paste account of signer here"
    ethereum.request({ method: "personal_sign", params: [account, hash]}).then(console.log)

    # using web3
    web3.personal.sign(hash, web3.eth.defaultAccount, console.log)

    Signature will be different for different accounts
    0x993dab3dd91f5c6dc28e17439be475478f5635c92a56e17e82349d3fb2f166196f466c0b4e0c146f285204f0dcb13e5ae67bc33f4b888ec32dfe0a063e8f3f781b
    */
    function getEthSignedMessageHash(bytes32 _messageHash)
        public
        pure
        returns (bytes32)
    {
        /*
        Signature is produced by signing a keccak256 hash with the following format:
        "\x19Ethereum Signed Message\n" + len(msg) + msg
        */
        return
            keccak256(
                abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash)
            );
    }

    /* 4. Verify signature
    signer = 0xB273216C05A8c0D4F0a4Dd0d7Bae1D2EfFE636dd
    to = 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C
    amount = 123
    message = "coffee and donuts"
    nonce = 1
    signature =
        0x993dab3dd91f5c6dc28e17439be475478f5635c92a56e17e82349d3fb2f166196f466c0b4e0c146f285204f0dcb13e5ae67bc33f4b888ec32dfe0a063e8f3f781b
    */
    function verify(
        address _signer,
        address _to,
        uint _amount,
        string memory _message,
        uint _nonce,
        bytes memory signature
    ) public pure returns (bool) {
        bytes32 messageHash = getMessageHash(_to, _amount, _message, _nonce);
        bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash);

        return recoverSigner(ethSignedMessageHash, signature) == _signer;
    }

    function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature)
        public
        pure
        returns (address)
    {
        (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);

        return ecrecover(_ethSignedMessageHash, v, r, s);
    }

    function splitSignature(bytes memory sig)
        public
        pure
        returns (
            bytes32 r,
            bytes32 s,
            uint8 v
        )
    {
        require(sig.length == 65, "invalid signature length");

        assembly {
            /*
            First 32 bytes stores the length of the signature

            add(sig, 32) = pointer of sig + 32
            effectively, skips first 32 bytes of signature

            mload(p) loads next 32 bytes starting at the memory address p into memory
            */

            // first 32 bytes, after the length prefix
            r := mload(add(sig, 32))
            // second 32 bytes
            s := mload(add(sig, 64))
            // final byte (first byte of the next 32 bytes)
            v := byte(0, mload(add(sig, 96)))
        }

        // implicitly return (r, s, v)
    }

    function stringToEthSignedMessageHash(string memory s) public pure returns (bytes32) {
        bytes memory ss = bytes(s);
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(ss.length), ss));
    }
}

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


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

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions 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);
    }
}

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


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    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;
    }

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

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

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

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: 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);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _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 {}
}

// File: HackerHaiku.sol


pragma solidity ^0.8.13;






contract HackerHaiku is ERC721, Ownable {
    using Strings for uint256;

    // token metadata
    string public constant imagePartOne = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"><style>.h{font-family:Courier New;font-size:10px;fill:#05f228;animation: yg 4s 3.9s infinite;}.fp{font-family:Courier New;font-size:3px;fill:#05f228;}@keyframes yg{0%{fill:yellow;}10%{fill:#305f228;}}</style><rect x="0" y="0" width="200" height="200" fill="black"/><text x="10" y="85" class="h">';
    string public constant imagePartTwo = '</text><text x="10" y="100" class="h">';
    string public constant imagePartThree = '</text><text x="10" y="115" class="h">';
    string public constant imagePartFour = '</text><rect x="3%" y="3%" width="94%" height="94%" fill="none" stroke="#05f228" stroke-width=".5%"/></svg>';
    string public constant description = 'Generative cyberpunk themed haiku mintable via SMS.';
    string public constant tokenName = 'Hacker Haiku';
    string public license = 'CC BY-NC 4.0';
    string public externalUrl = 'https://hackerhaiku.com';

    VerifySignature public verifySignature = new VerifySignature();

    struct Haiku {
        string line1;
        string line2;
        string line3;
    }

    uint Counter;
    address signer;

    mapping(string => uint) public haikus;
    mapping(uint => Haiku) public tokens;

    constructor(address _signer) ERC721("HackerHaiku", "HAH") {
        signer = _signer;
    }

    function mint(
        address _to, 
        string memory _line1, 
        string memory _line2, 
        string memory _line3, 
        bytes32 _ethSignedMessageHash, 
        bytes memory _signature
        ) public payable {
            string memory flatHaiku = string(abi.encodePacked(_line1, _line2, _line3));
            require(haikus[flatHaiku] == 0, "Haiku already claimed.");
            require(Counter <= 1337, "All out.");
            require(verifySignature.recoverSigner(_ethSignedMessageHash, _signature) == signer, "Invalid signature.");
            require(verifySignature.stringToEthSignedMessageHash(flatHaiku) == _ethSignedMessageHash, "Hash and haiku don't match.");

            if (msg.sender != owner()) {
                require(msg.value >= 0.01 ether, "Not enough ETH.");
            }

            Haiku memory haiku = Haiku(_line1, _line2, _line3);

            Counter++;
            haikus[flatHaiku] = Counter;
            tokens[Counter] = haiku;
            payable(owner()).transfer(msg.value);
            _safeMint(_to, Counter);  
    }

    function updateSigner(address _newSigner) external onlyOwner {
        signer = _newSigner;
    }

    function updateExternalUrl(string memory _newExternalUrl) external onlyOwner {
        externalUrl = _newExternalUrl;
    }

    function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
        bytes memory encodedImage = abi.encodePacked('"image": "data:image/svg+xml;base64,', Base64.encode(getSVG(_tokenId)), '",');
        bytes memory encodedHTML = abi.encodePacked('"animation_url": "data:text/html;base64,', Base64.encode(getHTML(_tokenId)), '",');

        string memory json = Base64.encode(
          abi.encodePacked(
            '{"name": "', tokenName, ' #', Strings.toString(_tokenId), '",',
            '"description": "', description, '",',
            encodedImage,
            encodedHTML,
            '"license": "', license, '",'
            '"external_url": "', externalUrl,
            '"}'
          )
        );
        return string(abi.encodePacked('data:application/json;base64,', json));
    }

    function getSVG(uint256 _tokenId) public view returns (bytes memory) {
        require(_exists(_tokenId), "Token doesn't exist.");

        Haiku memory haiku = tokens[_tokenId];
        return abi.encodePacked(
            imagePartOne,  
            haiku.line1,
            imagePartTwo, 
            haiku.line2, 
            imagePartThree, 
            haiku.line3, 
            imagePartFour
            );
    }

    function getHTML(uint256 _tokenId) public view returns (bytes memory) {
        return abi.encodePacked(
            '<!DOCTYPE html><html><head><style>*{margin:0;padding:0}</style></head><body>',
            string(getSVG(_tokenId)),
            '</body></html>'
        );
    }

    receive() external payable { }

    function withdraw() external onlyOwner {
        payable(msg.sender).transfer(address(this).balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"externalUrl","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getHTML","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getSVG","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"haikus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"imagePartFour","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"imagePartOne","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"imagePartThree","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"imagePartTwo","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"license","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"string","name":"_line1","type":"string"},{"internalType":"string","name":"_line2","type":"string"},{"internalType":"string","name":"_line3","type":"string"},{"internalType":"bytes32","name":"_ethSignedMessageHash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","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":"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":"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":[],"name":"tokenName","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"string","name":"line1","type":"string"},{"internalType":"string","name":"line2","type":"string"},{"internalType":"string","name":"line3","type":"string"}],"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":[{"internalType":"string","name":"_newExternalUrl","type":"string"}],"name":"updateExternalUrl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newSigner","type":"address"}],"name":"updateSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"verifySignature","outputs":[{"internalType":"contract VerifySignature","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526040518060400160405280600c81526020017f43432042592d4e4320342e300000000000000000000000000000000000000000815250600790805190602001906200005192919062000315565b506040518060400160405280601781526020017f68747470733a2f2f6861636b65726861696b752e636f6d000000000000000000815250600890805190602001906200009f92919062000315565b50604051620000ae90620003a6565b604051809103906000f080158015620000cb573d6000803e3d6000fd5b50600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200011957600080fd5b50604051620062843803806200628483398181016040528101906200013f91906200043d565b6040518060400160405280600b81526020017f4861636b65724861696b750000000000000000000000000000000000000000008152506040518060400160405280600381526020017f48414800000000000000000000000000000000000000000000000000000000008152508160009080519060200190620001c392919062000315565b508060019080519060200190620001dc92919062000315565b505050620001ff620001f36200024760201b60201c565b6200024f60201b60201c565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050620004d3565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b82805462000323906200049e565b90600052602060002090601f01602090048101928262000347576000855562000393565b82601f106200036257805160ff191683800117855562000393565b8280016001018555821562000393579182015b828111156200039257825182559160200191906001019062000375565b5b509050620003a29190620003b4565b5090565b610f5c806200532883390190565b5b80821115620003cf576000816000905550600101620003b5565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040582620003d8565b9050919050565b6200041781620003f8565b81146200042357600080fd5b50565b60008151905062000437816200040c565b92915050565b600060208284031215620004565762000455620003d3565b5b6000620004668482850162000426565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620004b757607f821691505b602082108103620004cd57620004cc6200046f565b5b50919050565b614e4580620004e36000396000f3fe6080604052600436106101f25760003560e01c80636b87d24c1161010d57806395d89b41116100a0578063b88d4fde1161006f578063b88d4fde146106ef578063be985ac914610718578063c87b56dd14610755578063e985e9c514610792578063f2fde38b146107cf576101f9565b806395d89b4114610635578063a22cb46514610660578063a7ecd37e14610689578063b6640091146106b2576101f9565b80637284e416116100dc5780637284e4161461058b5780637931b3e4146105b65780638da5cb5b146105df5780638fc734841461060a576101f9565b80636b87d24c146104e15780636c02a9311461050c57806370a0823114610537578063715018a614610574576101f9565b80632653f517116101855780634f64b2be116101545780634f64b2be1461040f57806358cd25131461044e5780636352211e1461047957806365902b0a146104b6576101f9565b80632653f517146103795780632dab1e36146103a45780633ccfd60b146103cf57806342842e0e146103e6576101f9565b8063102581d2116101c1578063102581d2146102cc57806314e4354a146103095780631816ee7e1461032557806323b872dd14610350576101f9565b806301ffc9a7146101fe57806306fdde031461023b578063081812fc14610266578063095ea7b3146102a3576101f9565b366101f957005b600080fd5b34801561020a57600080fd5b5061022560048036038101906102209190612ee8565b6107f8565b6040516102329190612f30565b60405180910390f35b34801561024757600080fd5b506102506108da565b60405161025d9190612fe4565b60405180910390f35b34801561027257600080fd5b5061028d6004803603810190610288919061303c565b61096c565b60405161029a91906130aa565b60405180910390f35b3480156102af57600080fd5b506102ca60048036038101906102c591906130f1565b6109b2565b005b3480156102d857600080fd5b506102f360048036038101906102ee919061303c565b610ac9565b6040516103009190613186565b60405180910390f35b610323600480360381019061031e91906133b4565b610afa565b005b34801561033157600080fd5b5061033a610f89565b6040516103479190612fe4565b60405180910390f35b34801561035c57600080fd5b50610377600480360381019061037291906134b1565b610fa5565b005b34801561038557600080fd5b5061038e611005565b60405161039b9190612fe4565b60405180910390f35b3480156103b057600080fd5b506103b9611021565b6040516103c69190612fe4565b60405180910390f35b3480156103db57600080fd5b506103e4611040565b005b3480156103f257600080fd5b5061040d600480360381019061040891906134b1565b611091565b005b34801561041b57600080fd5b506104366004803603810190610431919061303c565b6110b1565b60405161044593929190613504565b60405180910390f35b34801561045a57600080fd5b50610463611273565b60405161047091906135af565b60405180910390f35b34801561048557600080fd5b506104a0600480360381019061049b919061303c565b611299565b6040516104ad91906130aa565b60405180910390f35b3480156104c257600080fd5b506104cb61131f565b6040516104d89190612fe4565b60405180910390f35b3480156104ed57600080fd5b506104f661133b565b6040516105039190612fe4565b60405180910390f35b34801561051857600080fd5b506105216113c9565b60405161052e9190612fe4565b60405180910390f35b34801561054357600080fd5b5061055e600480360381019061055991906135ca565b611402565b60405161056b9190613606565b60405180910390f35b34801561058057600080fd5b506105896114b9565b005b34801561059757600080fd5b506105a06114cd565b6040516105ad9190612fe4565b60405180910390f35b3480156105c257600080fd5b506105dd60048036038101906105d89190613621565b6114e9565b005b3480156105eb57600080fd5b506105f461150b565b60405161060191906130aa565b60405180910390f35b34801561061657600080fd5b5061061f611535565b60405161062c9190612fe4565b60405180910390f35b34801561064157600080fd5b5061064a6115c3565b6040516106579190612fe4565b60405180910390f35b34801561066c57600080fd5b5061068760048036038101906106829190613696565b611655565b005b34801561069557600080fd5b506106b060048036038101906106ab91906135ca565b61166b565b005b3480156106be57600080fd5b506106d960048036038101906106d49190613621565b6116b7565b6040516106e69190613606565b60405180910390f35b3480156106fb57600080fd5b50610716600480360381019061071191906136d6565b6116e5565b005b34801561072457600080fd5b5061073f600480360381019061073a919061303c565b611747565b60405161074c9190613186565b60405180910390f35b34801561076157600080fd5b5061077c6004803603810190610777919061303c565b611a0c565b6040516107899190612fe4565b60405180910390f35b34801561079e57600080fd5b506107b960048036038101906107b49190613759565b611b2f565b6040516107c69190612f30565b60405180910390f35b3480156107db57600080fd5b506107f660048036038101906107f191906135ca565b611bc3565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108c357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108d357506108d282611c46565b5b9050919050565b6060600080546108e9906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054610915906137c8565b80156109625780601f1061093757610100808354040283529160200191610962565b820191906000526020600020905b81548152906001019060200180831161094557829003601f168201915b5050505050905090565b600061097782611cb0565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109bd82611299565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a249061386b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a4c611cfb565b73ffffffffffffffffffffffffffffffffffffffff161480610a7b5750610a7a81610a75611cfb565b611b2f565b5b610aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab1906138fd565b60405180910390fd5b610ac48383611d03565b505050565b6060610ad482611747565b604051602001610ae49190613a3d565b6040516020818303038152906040529050919050565b6000858585604051602001610b1193929190613a6a565b60405160208183030381529060405290506000600c82604051610b349190613a9b565b90815260200160405180910390205414610b83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7a90613afe565b60405180910390fd5b610539600a541115610bca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc190613b6a565b60405180910390fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166397aba7f985856040518363ffffffff1660e01b8152600401610c60929190613b99565b602060405180830381865afa158015610c7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca19190613bde565b73ffffffffffffffffffffffffffffffffffffffff1614610cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cee90613c57565b60405180910390fd5b82600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631de810a1836040518263ffffffff1660e01b8152600401610d539190612fe4565b602060405180830381865afa158015610d70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d949190613c8c565b14610dd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dcb90613d05565b60405180910390fd5b610ddc61150b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e5957662386f26fc10000341015610e58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4f90613d71565b60405180910390fd5b5b60006040518060600160405280888152602001878152602001868152509050600a6000815480929190610e8b90613dc0565b9190505550600a54600c83604051610ea39190613a9b565b90815260200160405180910390208190555080600d6000600a5481526020019081526020016000206000820151816000019080519060200190610ee7929190612dd9565b506020820151816001019080519060200190610f04929190612dd9565b506040820151816002019080519060200190610f21929190612dd9565b50905050610f2d61150b565b73ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015610f72573d6000803e3d6000fd5b50610f7f88600a54611dbc565b5050505050505050565b604051806060016040528060268152602001614d916026913981565b610fb6610fb0611cfb565b82611dda565b610ff5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fec90613e7a565b60405180910390fd5b611000838383611e6f565b505050565b604051806060016040528060268152602001614dea6026913981565b604051806101a001604052806101658152602001614c2c610165913981565b611048612168565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561108e573d6000803e3d6000fd5b50565b6110ac838383604051806020016040528060008152506116e5565b505050565b600d6020528060005260406000206000915090508060000180546110d4906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611100906137c8565b801561114d5780601f106111225761010080835404028352916020019161114d565b820191906000526020600020905b81548152906001019060200180831161113057829003601f168201915b505050505090806001018054611162906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461118e906137c8565b80156111db5780601f106111b0576101008083540402835291602001916111db565b820191906000526020600020905b8154815290600101906020018083116111be57829003601f168201915b5050505050908060020180546111f0906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461121c906137c8565b80156112695780601f1061123e57610100808354040283529160200191611269565b820191906000526020600020905b81548152906001019060200180831161124c57829003601f168201915b5050505050905083565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806112a5836121e6565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130d90613ee6565b60405180910390fd5b80915050919050565b6040518060a00160405280606b8152602001614b81606b913981565b60078054611348906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611374906137c8565b80156113c15780601f10611396576101008083540402835291602001916113c1565b820191906000526020600020905b8154815290600101906020018083116113a457829003601f168201915b505050505081565b6040518060400160405280600c81526020017f4861636b6572204861696b75000000000000000000000000000000000000000081525081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146990613f78565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6114c1612168565b6114cb6000612223565b565b604051806060016040528060338152602001614db76033913981565b6114f1612168565b8060089080519060200190611507929190612dd9565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60088054611542906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461156e906137c8565b80156115bb5780601f10611590576101008083540402835291602001916115bb565b820191906000526020600020905b81548152906001019060200180831161159e57829003601f168201915b505050505081565b6060600180546115d2906137c8565b80601f01602080910402602001604051908101604052809291908181526020018280546115fe906137c8565b801561164b5780601f106116205761010080835404028352916020019161164b565b820191906000526020600020905b81548152906001019060200180831161162e57829003601f168201915b5050505050905090565b611667611660611cfb565b83836122e9565b5050565b611673612168565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600c818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6116f66116f0611cfb565b83611dda565b611735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172c90613e7a565b60405180910390fd5b61174184848484612455565b50505050565b6060611752826124b1565b611791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178890613fe4565b60405180910390fd5b6000600d60008481526020019081526020016000206040518060600160405290816000820180546117c1906137c8565b80601f01602080910402602001604051908101604052809291908181526020018280546117ed906137c8565b801561183a5780601f1061180f5761010080835404028352916020019161183a565b820191906000526020600020905b81548152906001019060200180831161181d57829003601f168201915b50505050508152602001600182018054611853906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461187f906137c8565b80156118cc5780601f106118a1576101008083540402835291602001916118cc565b820191906000526020600020905b8154815290600101906020018083116118af57829003601f168201915b505050505081526020016002820180546118e5906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611911906137c8565b801561195e5780601f106119335761010080835404028352916020019161195e565b820191906000526020600020905b81548152906001019060200180831161194157829003601f168201915b5050505050815250509050604051806101a001604052806101658152602001614c2c61016591398160000151604051806060016040528060268152602001614dea602691398360200151604051806060016040528060268152602001614d916026913985604001516040518060a00160405280606b8152602001614b81606b91396040516020016119f59796959493929190614004565b604051602081830303815290604052915050919050565b60606000611a21611a1c84611747565b6124f2565b604051602001611a319190614127565b60405160208183030381529060405290506000611a55611a5085610ac9565b6124f2565b604051602001611a6591906141c6565b60405160208183030381529060405290506000611b036040518060400160405280600c81526020017f4861636b6572204861696b750000000000000000000000000000000000000000815250611aba8761266a565b604051806060016040528060338152602001614db760339139868660076008604051602001611aef979695949392919061448b565b6040516020818303038152906040526124f2565b905080604051602001611b169190614594565b6040516020818303038152906040529350505050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611bcb612168565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3190614628565b60405180910390fd5b611c4381612223565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611cb9816124b1565b611cf8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cef90613ee6565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611d7683611299565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611dd6828260405180602001604052806000815250612738565b5050565b600080611de683611299565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e285750611e278185611b2f565b5b80611e6657508373ffffffffffffffffffffffffffffffffffffffff16611e4e8461096c565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e8f82611299565b73ffffffffffffffffffffffffffffffffffffffff1614611ee5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611edc906146ba565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611f54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f4b9061474c565b60405180910390fd5b611f618383836001612793565b8273ffffffffffffffffffffffffffffffffffffffff16611f8182611299565b73ffffffffffffffffffffffffffffffffffffffff1614611fd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fce906146ba565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461216383838360016128b9565b505050565b612170611cfb565b73ffffffffffffffffffffffffffffffffffffffff1661218e61150b565b73ffffffffffffffffffffffffffffffffffffffff16146121e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121db906147b8565b60405180910390fd5b565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234e90614824565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516124489190612f30565b60405180910390a3505050565b612460848484611e6f565b61246c848484846128bf565b6124ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124a2906148b6565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff166124d3836121e6565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6060600082510361251457604051806020016040528060008152509050612665565b6000604051806060016040528060408152602001614bec604091399050600060036002855161254391906148d6565b61254d919061495b565b6004612559919061498c565b9050600060208261256a91906148d6565b67ffffffffffffffff811115612583576125826131b2565b5b6040519080825280601f01601f1916602001820160405280156125b55781602001600182028036833780820191505090505b509050818152600183018586518101602084015b81831015612624576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f81168501518253600182019150506125c9565b60038951066001811461263e576002811461264e57612659565b613d3d60f01b6002830352612659565b603d60f81b60018303525b50505050508093505050505b919050565b60606000600161267984612a46565b01905060008167ffffffffffffffff811115612698576126976131b2565b5b6040519080825280601f01601f1916602001820160405280156126ca5781602001600182028036833780820191505090505b509050600082602001820190505b60011561272d578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816127215761272061492c565b5b049450600085036126d8575b819350505050919050565b6127428383612b99565b61274f60008484846128bf565b61278e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612785906148b6565b60405180910390fd5b505050565b60018111156128b357600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146128275780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461281f91906149e6565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146128b25780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546128aa91906148d6565b925050819055505b5b50505050565b50505050565b60006128e08473ffffffffffffffffffffffffffffffffffffffff16612db6565b15612a39578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612909611cfb565b8786866040518563ffffffff1660e01b815260040161292b9493929190614a1a565b6020604051808303816000875af192505050801561296757506040513d601f19601f820116820180604052508101906129649190614a7b565b60015b6129e9573d8060008114612997576040519150601f19603f3d011682016040523d82523d6000602084013e61299c565b606091505b5060008151036129e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d8906148b6565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612a3e565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612aa4577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a9a57612a9961492c565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612ae1576d04ee2d6d415b85acef81000000008381612ad757612ad661492c565b5b0492506020810190505b662386f26fc100008310612b1057662386f26fc100008381612b0657612b0561492c565b5b0492506010810190505b6305f5e1008310612b39576305f5e1008381612b2f57612b2e61492c565b5b0492506008810190505b6127108310612b5e576127108381612b5457612b5361492c565b5b0492506004810190505b60648310612b815760648381612b7757612b7661492c565b5b0492506002810190505b600a8310612b90576001810190505b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bff90614af4565b60405180910390fd5b612c11816124b1565b15612c51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c4890614b60565b60405180910390fd5b612c5f600083836001612793565b612c68816124b1565b15612ca8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9f90614b60565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612db26000838360016128b9565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054612de5906137c8565b90600052602060002090601f016020900481019282612e075760008555612e4e565b82601f10612e2057805160ff1916838001178555612e4e565b82800160010185558215612e4e579182015b82811115612e4d578251825591602001919060010190612e32565b5b509050612e5b9190612e5f565b5090565b5b80821115612e78576000816000905550600101612e60565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ec581612e90565b8114612ed057600080fd5b50565b600081359050612ee281612ebc565b92915050565b600060208284031215612efe57612efd612e86565b5b6000612f0c84828501612ed3565b91505092915050565b60008115159050919050565b612f2a81612f15565b82525050565b6000602082019050612f456000830184612f21565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f85578082015181840152602081019050612f6a565b83811115612f94576000848401525b50505050565b6000601f19601f8301169050919050565b6000612fb682612f4b565b612fc08185612f56565b9350612fd0818560208601612f67565b612fd981612f9a565b840191505092915050565b60006020820190508181036000830152612ffe8184612fab565b905092915050565b6000819050919050565b61301981613006565b811461302457600080fd5b50565b60008135905061303681613010565b92915050565b60006020828403121561305257613051612e86565b5b600061306084828501613027565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061309482613069565b9050919050565b6130a481613089565b82525050565b60006020820190506130bf600083018461309b565b92915050565b6130ce81613089565b81146130d957600080fd5b50565b6000813590506130eb816130c5565b92915050565b6000806040838503121561310857613107612e86565b5b6000613116858286016130dc565b925050602061312785828601613027565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b600061315882613131565b613162818561313c565b9350613172818560208601612f67565b61317b81612f9a565b840191505092915050565b600060208201905081810360008301526131a0818461314d565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6131ea82612f9a565b810181811067ffffffffffffffff82111715613209576132086131b2565b5b80604052505050565b600061321c612e7c565b905061322882826131e1565b919050565b600067ffffffffffffffff821115613248576132476131b2565b5b61325182612f9a565b9050602081019050919050565b82818337600083830152505050565b600061328061327b8461322d565b613212565b90508281526020810184848401111561329c5761329b6131ad565b5b6132a784828561325e565b509392505050565b600082601f8301126132c4576132c36131a8565b5b81356132d484826020860161326d565b91505092915050565b6000819050919050565b6132f0816132dd565b81146132fb57600080fd5b50565b60008135905061330d816132e7565b92915050565b600067ffffffffffffffff82111561332e5761332d6131b2565b5b61333782612f9a565b9050602081019050919050565b600061335761335284613313565b613212565b905082815260208101848484011115613373576133726131ad565b5b61337e84828561325e565b509392505050565b600082601f83011261339b5761339a6131a8565b5b81356133ab848260208601613344565b91505092915050565b60008060008060008060c087890312156133d1576133d0612e86565b5b60006133df89828a016130dc565b965050602087013567ffffffffffffffff811115613400576133ff612e8b565b5b61340c89828a016132af565b955050604087013567ffffffffffffffff81111561342d5761342c612e8b565b5b61343989828a016132af565b945050606087013567ffffffffffffffff81111561345a57613459612e8b565b5b61346689828a016132af565b935050608061347789828a016132fe565b92505060a087013567ffffffffffffffff81111561349857613497612e8b565b5b6134a489828a01613386565b9150509295509295509295565b6000806000606084860312156134ca576134c9612e86565b5b60006134d8868287016130dc565b93505060206134e9868287016130dc565b92505060406134fa86828701613027565b9150509250925092565b6000606082019050818103600083015261351e8186612fab565b905081810360208301526135328185612fab565b905081810360408301526135468184612fab565b9050949350505050565b6000819050919050565b600061357561357061356b84613069565b613550565b613069565b9050919050565b60006135878261355a565b9050919050565b60006135998261357c565b9050919050565b6135a98161358e565b82525050565b60006020820190506135c460008301846135a0565b92915050565b6000602082840312156135e0576135df612e86565b5b60006135ee848285016130dc565b91505092915050565b61360081613006565b82525050565b600060208201905061361b60008301846135f7565b92915050565b60006020828403121561363757613636612e86565b5b600082013567ffffffffffffffff81111561365557613654612e8b565b5b613661848285016132af565b91505092915050565b61367381612f15565b811461367e57600080fd5b50565b6000813590506136908161366a565b92915050565b600080604083850312156136ad576136ac612e86565b5b60006136bb858286016130dc565b92505060206136cc85828601613681565b9150509250929050565b600080600080608085870312156136f0576136ef612e86565b5b60006136fe878288016130dc565b945050602061370f878288016130dc565b935050604061372087828801613027565b925050606085013567ffffffffffffffff81111561374157613740612e8b565b5b61374d87828801613386565b91505092959194509250565b600080604083850312156137705761376f612e86565b5b600061377e858286016130dc565b925050602061378f858286016130dc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806137e057607f821691505b6020821081036137f3576137f2613799565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613855602183612f56565b9150613860826137f9565b604082019050919050565b6000602082019050818103600083015261388481613848565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b60006138e7603d83612f56565b91506138f28261388b565b604082019050919050565b60006020820190508181036000830152613916816138da565b9050919050565b600081905092915050565b7f3c21444f43545950452068746d6c3e3c68746d6c3e3c686561643e3c7374796c60008201527f653e2a7b6d617267696e3a303b70616464696e673a307d3c2f7374796c653e3c60208201527f2f686561643e3c626f64793e0000000000000000000000000000000000000000604082015250565b60006139aa604c8361391d565b91506139b582613928565b604c82019050919050565b60006139cb82612f4b565b6139d5818561391d565b93506139e5818560208601612f67565b80840191505092915050565b7f3c2f626f64793e3c2f68746d6c3e000000000000000000000000000000000000600082015250565b6000613a27600e8361391d565b9150613a32826139f1565b600e82019050919050565b6000613a488261399d565b9150613a5482846139c0565b9150613a5f82613a1a565b915081905092915050565b6000613a7682866139c0565b9150613a8282856139c0565b9150613a8e82846139c0565b9150819050949350505050565b6000613aa782846139c0565b915081905092915050565b7f4861696b7520616c726561647920636c61696d65642e00000000000000000000600082015250565b6000613ae8601683612f56565b9150613af382613ab2565b602082019050919050565b60006020820190508181036000830152613b1781613adb565b9050919050565b7f416c6c206f75742e000000000000000000000000000000000000000000000000600082015250565b6000613b54600883612f56565b9150613b5f82613b1e565b602082019050919050565b60006020820190508181036000830152613b8381613b47565b9050919050565b613b93816132dd565b82525050565b6000604082019050613bae6000830185613b8a565b8181036020830152613bc0818461314d565b90509392505050565b600081519050613bd8816130c5565b92915050565b600060208284031215613bf457613bf3612e86565b5b6000613c0284828501613bc9565b91505092915050565b7f496e76616c6964207369676e61747572652e0000000000000000000000000000600082015250565b6000613c41601283612f56565b9150613c4c82613c0b565b602082019050919050565b60006020820190508181036000830152613c7081613c34565b9050919050565b600081519050613c86816132e7565b92915050565b600060208284031215613ca257613ca1612e86565b5b6000613cb084828501613c77565b91505092915050565b7f4861736820616e64206861696b7520646f6e2774206d617463682e0000000000600082015250565b6000613cef601b83612f56565b9150613cfa82613cb9565b602082019050919050565b60006020820190508181036000830152613d1e81613ce2565b9050919050565b7f4e6f7420656e6f756768204554482e0000000000000000000000000000000000600082015250565b6000613d5b600f83612f56565b9150613d6682613d25565b602082019050919050565b60006020820190508181036000830152613d8a81613d4e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613dcb82613006565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dfd57613dfc613d91565b5b600182019050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e64602d83612f56565b9150613e6f82613e08565b604082019050919050565b60006020820190508181036000830152613e9381613e57565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613ed0601883612f56565b9150613edb82613e9a565b602082019050919050565b60006020820190508181036000830152613eff81613ec3565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f62602983612f56565b9150613f6d82613f06565b604082019050919050565b60006020820190508181036000830152613f9181613f55565b9050919050565b7f546f6b656e20646f65736e27742065786973742e000000000000000000000000600082015250565b6000613fce601483612f56565b9150613fd982613f98565b602082019050919050565b60006020820190508181036000830152613ffd81613fc1565b9050919050565b6000614010828a6139c0565b915061401c82896139c0565b915061402882886139c0565b915061403482876139c0565b915061404082866139c0565b915061404c82856139c0565b915061405882846139c0565b915081905098975050505050505050565b7f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b62617360008201527f6536342c00000000000000000000000000000000000000000000000000000000602082015250565b60006140c560248361391d565b91506140d082614069565b602482019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b600061411160028361391d565b915061411c826140db565b600282019050919050565b6000614132826140b8565b915061413e82846139c0565b915061414982614104565b915081905092915050565b7f22616e696d6174696f6e5f75726c223a2022646174613a746578742f68746d6c60008201527f3b6261736536342c000000000000000000000000000000000000000000000000602082015250565b60006141b060288361391d565b91506141bb82614154565b602882019050919050565b60006141d1826141a3565b91506141dd82846139c0565b91506141e882614104565b915081905092915050565b7f7b226e616d65223a202200000000000000000000000000000000000000000000600082015250565b6000614229600a8361391d565b9150614234826141f3565b600a82019050919050565b7f2023000000000000000000000000000000000000000000000000000000000000600082015250565b600061427560028361391d565b91506142808261423f565b600282019050919050565b7f226465736372697074696f6e223a202200000000000000000000000000000000600082015250565b60006142c160108361391d565b91506142cc8261428b565b601082019050919050565b600081905092915050565b60006142ed82613131565b6142f781856142d7565b9350614307818560208601612f67565b80840191505092915050565b7f226c6963656e7365223a20220000000000000000000000000000000000000000600082015250565b6000614349600c8361391d565b915061435482614313565b600c82019050919050565b60008190508160005260206000209050919050565b60008154614381816137c8565b61438b818661391d565b945060018216600081146143a657600181146143b7576143ea565b60ff198316865281860193506143ea565b6143c08561435f565b60005b838110156143e2578154818901526001820191506020810190506143c3565b838801955050505b50505092915050565b7f222c2265787465726e616c5f75726c223a202200000000000000000000000000600082015250565b600061442960138361391d565b9150614434826143f3565b601382019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b600061447560028361391d565b91506144808261443f565b600282019050919050565b60006144968261421c565b91506144a2828a6139c0565b91506144ad82614268565b91506144b982896139c0565b91506144c482614104565b91506144cf826142b4565b91506144db82886139c0565b91506144e682614104565b91506144f282876142e2565b91506144fe82866142e2565b91506145098261433c565b91506145158285614374565b91506145208261441c565b915061452c8284614374565b915061453782614468565b915081905098975050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061457e601d8361391d565b915061458982614548565b601d82019050919050565b600061459f82614571565b91506145ab82846139c0565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614612602683612f56565b915061461d826145b6565b604082019050919050565b6000602082019050818103600083015261464181614605565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006146a4602583612f56565b91506146af82614648565b604082019050919050565b600060208201905081810360008301526146d381614697565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614736602483612f56565b9150614741826146da565b604082019050919050565b6000602082019050818103600083015261476581614729565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006147a2602083612f56565b91506147ad8261476c565b602082019050919050565b600060208201905081810360008301526147d181614795565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061480e601983612f56565b9150614819826147d8565b602082019050919050565b6000602082019050818103600083015261483d81614801565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006148a0603283612f56565b91506148ab82614844565b604082019050919050565b600060208201905081810360008301526148cf81614893565b9050919050565b60006148e182613006565b91506148ec83613006565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561492157614920613d91565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061496682613006565b915061497183613006565b9250826149815761498061492c565b5b828204905092915050565b600061499782613006565b91506149a283613006565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156149db576149da613d91565b5b828202905092915050565b60006149f182613006565b91506149fc83613006565b925082821015614a0f57614a0e613d91565b5b828203905092915050565b6000608082019050614a2f600083018761309b565b614a3c602083018661309b565b614a4960408301856135f7565b8181036060830152614a5b818461314d565b905095945050505050565b600081519050614a7581612ebc565b92915050565b600060208284031215614a9157614a90612e86565b5b6000614a9f84828501614a66565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614ade602083612f56565b9150614ae982614aa8565b602082019050919050565b60006020820190508181036000830152614b0d81614ad1565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614b4a601c83612f56565b9150614b5582614b14565b602082019050919050565b60006020820190508181036000830152614b7981614b3d565b905091905056fe3c2f746578743e3c7265637420783d2233252220793d223325222077696474683d2239342522206865696768743d22393425222066696c6c3d226e6f6e6522207374726f6b653d222330356632323822207374726f6b652d77696474683d222e3525222f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222076696577426f783d223020302032303020323030223e3c7374796c653e2e687b666f6e742d66616d696c793a436f7572696572204e65773b666f6e742d73697a653a313070783b66696c6c3a233035663232383b616e696d6174696f6e3a20796720347320332e397320696e66696e6974653b7d2e66707b666f6e742d66616d696c793a436f7572696572204e65773b666f6e742d73697a653a3370783b66696c6c3a233035663232383b7d406b65796672616d65732079677b30257b66696c6c3a79656c6c6f773b7d3130257b66696c6c3a23333035663232383b7d7d3c2f7374796c653e3c7265637420783d22302220793d2230222077696474683d2232303022206865696768743d22323030222066696c6c3d22626c61636b222f3e3c7465787420783d2231302220793d2238352220636c6173733d2268223e3c2f746578743e3c7465787420783d2231302220793d223131352220636c6173733d2268223e47656e6572617469766520637962657270756e6b207468656d6564206861696b75206d696e7461626c652076696120534d532e3c2f746578743e3c7465787420783d2231302220793d223130302220636c6173733d2268223ea2646970667358221220c6d25413f6da329dea5448d072ab6d153c34a947a634f8b1ecb059a7157958ec64736f6c634300080d0033608060405234801561001057600080fd5b50610f3c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80631de810a11461006757806397aba7f914610097578063a35f8a40146100c7578063a7bb5803146100f7578063abe5026a14610129578063fa54080114610159575b600080fd5b610081600480360381019061007c91906106e8565b610189565b60405161008e919061074a565b60405180910390f35b6100b160048036038101906100ac9190610832565b6101c9565b6040516100be91906108cf565b60405180910390f35b6100e160048036038101906100dc919061094c565b610238565b6040516100ee919061074a565b60405180910390f35b610111600480360381019061010c91906109cf565b610271565b60405161012093929190610a34565b60405180910390f35b610143600480360381019061013e9190610a6b565b6102d9565b6040516101509190610b4b565b60405180910390f35b610173600480360381019061016e9190610b66565b61033d565b604051610180919061074a565b60405180910390f35b600080829050610199815161036d565b816040516020016101ab929190610ca0565b60405160208183030381529060405280519060200120915050919050565b6000806000806101d885610271565b925092509250600186828585604051600081526020016040526040516102019493929190610ccf565b6020604051602081039080840390855afa158015610223573d6000803e3d6000fd5b50505060206040510351935050505092915050565b6000848484846040516020016102519493929190610d7d565b604051602081830303815290604052805190602001209050949350505050565b600080600060418451146102ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102b190610e24565b60405180910390fd5b6020840151925060408401519150606084015160001a90509193909250565b6000806102e887878787610238565b905060006102f58261033d565b90508873ffffffffffffffffffffffffffffffffffffffff1661031882866101c9565b73ffffffffffffffffffffffffffffffffffffffff1614925050509695505050505050565b6000816040516020016103509190610eb1565b604051602081830303815290604052805190602001209050919050565b60606000600161037c8461043b565b01905060008167ffffffffffffffff81111561039b5761039a6105bd565b5b6040519080825280601f01601f1916602001820160405280156103cd5781602001600182028036833780820191505090505b509050600082602001820190505b600115610430578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161042457610423610ed7565b5b049450600085036103db575b819350505050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310610499577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161048f5761048e610ed7565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106104d6576d04ee2d6d415b85acef810000000083816104cc576104cb610ed7565b5b0492506020810190505b662386f26fc10000831061050557662386f26fc1000083816104fb576104fa610ed7565b5b0492506010810190505b6305f5e100831061052e576305f5e100838161052457610523610ed7565b5b0492506008810190505b612710831061055357612710838161054957610548610ed7565b5b0492506004810190505b60648310610576576064838161056c5761056b610ed7565b5b0492506002810190505b600a8310610585576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6105f5826105ac565b810181811067ffffffffffffffff82111715610614576106136105bd565b5b80604052505050565b600061062761058e565b905061063382826105ec565b919050565b600067ffffffffffffffff821115610653576106526105bd565b5b61065c826105ac565b9050602081019050919050565b82818337600083830152505050565b600061068b61068684610638565b61061d565b9050828152602081018484840111156106a7576106a66105a7565b5b6106b2848285610669565b509392505050565b600082601f8301126106cf576106ce6105a2565b5b81356106df848260208601610678565b91505092915050565b6000602082840312156106fe576106fd610598565b5b600082013567ffffffffffffffff81111561071c5761071b61059d565b5b610728848285016106ba565b91505092915050565b6000819050919050565b61074481610731565b82525050565b600060208201905061075f600083018461073b565b92915050565b61076e81610731565b811461077957600080fd5b50565b60008135905061078b81610765565b92915050565b600067ffffffffffffffff8211156107ac576107ab6105bd565b5b6107b5826105ac565b9050602081019050919050565b60006107d56107d084610791565b61061d565b9050828152602081018484840111156107f1576107f06105a7565b5b6107fc848285610669565b509392505050565b600082601f830112610819576108186105a2565b5b81356108298482602086016107c2565b91505092915050565b6000806040838503121561084957610848610598565b5b60006108578582860161077c565b925050602083013567ffffffffffffffff8111156108785761087761059d565b5b61088485828601610804565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108b98261088e565b9050919050565b6108c9816108ae565b82525050565b60006020820190506108e460008301846108c0565b92915050565b6108f3816108ae565b81146108fe57600080fd5b50565b600081359050610910816108ea565b92915050565b6000819050919050565b61092981610916565b811461093457600080fd5b50565b60008135905061094681610920565b92915050565b6000806000806080858703121561096657610965610598565b5b600061097487828801610901565b945050602061098587828801610937565b935050604085013567ffffffffffffffff8111156109a6576109a561059d565b5b6109b2878288016106ba565b92505060606109c387828801610937565b91505092959194509250565b6000602082840312156109e5576109e4610598565b5b600082013567ffffffffffffffff811115610a0357610a0261059d565b5b610a0f84828501610804565b91505092915050565b600060ff82169050919050565b610a2e81610a18565b82525050565b6000606082019050610a49600083018661073b565b610a56602083018561073b565b610a636040830184610a25565b949350505050565b60008060008060008060c08789031215610a8857610a87610598565b5b6000610a9689828a01610901565b9650506020610aa789828a01610901565b9550506040610ab889828a01610937565b945050606087013567ffffffffffffffff811115610ad957610ad861059d565b5b610ae589828a016106ba565b9350506080610af689828a01610937565b92505060a087013567ffffffffffffffff811115610b1757610b1661059d565b5b610b2389828a01610804565b9150509295509295509295565b60008115159050919050565b610b4581610b30565b82525050565b6000602082019050610b606000830184610b3c565b92915050565b600060208284031215610b7c57610b7b610598565b5b6000610b8a8482850161077c565b91505092915050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a000000000000600082015250565b6000610bd4601a83610b93565b9150610bdf82610b9e565b601a82019050919050565b600081519050919050565b60005b83811015610c13578082015181840152602081019050610bf8565b83811115610c22576000848401525b50505050565b6000610c3382610bea565b610c3d8185610b93565b9350610c4d818560208601610bf5565b80840191505092915050565b600081519050919050565b600081905092915050565b6000610c7a82610c59565b610c848185610c64565b9350610c94818560208601610bf5565b80840191505092915050565b6000610cab82610bc7565b9150610cb78285610c28565b9150610cc38284610c6f565b91508190509392505050565b6000608082019050610ce4600083018761073b565b610cf16020830186610a25565b610cfe604083018561073b565b610d0b606083018461073b565b95945050505050565b60008160601b9050919050565b6000610d2c82610d14565b9050919050565b6000610d3e82610d21565b9050919050565b610d56610d51826108ae565b610d33565b82525050565b6000819050919050565b610d77610d7282610916565b610d5c565b82525050565b6000610d898287610d45565b601482019150610d998286610d66565b602082019150610da98285610c28565b9150610db58284610d66565b60208201915081905095945050505050565b600082825260208201905092915050565b7f696e76616c6964207369676e6174757265206c656e6774680000000000000000600082015250565b6000610e0e601883610dc7565b9150610e1982610dd8565b602082019050919050565b60006020820190508181036000830152610e3d81610e01565b9050919050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000610e7a601c83610b93565b9150610e8582610e44565b601c82019050919050565b6000819050919050565b610eab610ea682610731565b610e90565b82525050565b6000610ebc82610e6d565b9150610ec88284610e9a565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212203c3b21ab7a51e4526431a7279646fa9b3ac952ed26848eb153c8a904e03f74ab64736f6c634300080d0033000000000000000000000000b762f00e5ea9796b0c1e4c0a812a8253615b83c5

Deployed Bytecode

0x6080604052600436106101f25760003560e01c80636b87d24c1161010d57806395d89b41116100a0578063b88d4fde1161006f578063b88d4fde146106ef578063be985ac914610718578063c87b56dd14610755578063e985e9c514610792578063f2fde38b146107cf576101f9565b806395d89b4114610635578063a22cb46514610660578063a7ecd37e14610689578063b6640091146106b2576101f9565b80637284e416116100dc5780637284e4161461058b5780637931b3e4146105b65780638da5cb5b146105df5780638fc734841461060a576101f9565b80636b87d24c146104e15780636c02a9311461050c57806370a0823114610537578063715018a614610574576101f9565b80632653f517116101855780634f64b2be116101545780634f64b2be1461040f57806358cd25131461044e5780636352211e1461047957806365902b0a146104b6576101f9565b80632653f517146103795780632dab1e36146103a45780633ccfd60b146103cf57806342842e0e146103e6576101f9565b8063102581d2116101c1578063102581d2146102cc57806314e4354a146103095780631816ee7e1461032557806323b872dd14610350576101f9565b806301ffc9a7146101fe57806306fdde031461023b578063081812fc14610266578063095ea7b3146102a3576101f9565b366101f957005b600080fd5b34801561020a57600080fd5b5061022560048036038101906102209190612ee8565b6107f8565b6040516102329190612f30565b60405180910390f35b34801561024757600080fd5b506102506108da565b60405161025d9190612fe4565b60405180910390f35b34801561027257600080fd5b5061028d6004803603810190610288919061303c565b61096c565b60405161029a91906130aa565b60405180910390f35b3480156102af57600080fd5b506102ca60048036038101906102c591906130f1565b6109b2565b005b3480156102d857600080fd5b506102f360048036038101906102ee919061303c565b610ac9565b6040516103009190613186565b60405180910390f35b610323600480360381019061031e91906133b4565b610afa565b005b34801561033157600080fd5b5061033a610f89565b6040516103479190612fe4565b60405180910390f35b34801561035c57600080fd5b50610377600480360381019061037291906134b1565b610fa5565b005b34801561038557600080fd5b5061038e611005565b60405161039b9190612fe4565b60405180910390f35b3480156103b057600080fd5b506103b9611021565b6040516103c69190612fe4565b60405180910390f35b3480156103db57600080fd5b506103e4611040565b005b3480156103f257600080fd5b5061040d600480360381019061040891906134b1565b611091565b005b34801561041b57600080fd5b506104366004803603810190610431919061303c565b6110b1565b60405161044593929190613504565b60405180910390f35b34801561045a57600080fd5b50610463611273565b60405161047091906135af565b60405180910390f35b34801561048557600080fd5b506104a0600480360381019061049b919061303c565b611299565b6040516104ad91906130aa565b60405180910390f35b3480156104c257600080fd5b506104cb61131f565b6040516104d89190612fe4565b60405180910390f35b3480156104ed57600080fd5b506104f661133b565b6040516105039190612fe4565b60405180910390f35b34801561051857600080fd5b506105216113c9565b60405161052e9190612fe4565b60405180910390f35b34801561054357600080fd5b5061055e600480360381019061055991906135ca565b611402565b60405161056b9190613606565b60405180910390f35b34801561058057600080fd5b506105896114b9565b005b34801561059757600080fd5b506105a06114cd565b6040516105ad9190612fe4565b60405180910390f35b3480156105c257600080fd5b506105dd60048036038101906105d89190613621565b6114e9565b005b3480156105eb57600080fd5b506105f461150b565b60405161060191906130aa565b60405180910390f35b34801561061657600080fd5b5061061f611535565b60405161062c9190612fe4565b60405180910390f35b34801561064157600080fd5b5061064a6115c3565b6040516106579190612fe4565b60405180910390f35b34801561066c57600080fd5b5061068760048036038101906106829190613696565b611655565b005b34801561069557600080fd5b506106b060048036038101906106ab91906135ca565b61166b565b005b3480156106be57600080fd5b506106d960048036038101906106d49190613621565b6116b7565b6040516106e69190613606565b60405180910390f35b3480156106fb57600080fd5b50610716600480360381019061071191906136d6565b6116e5565b005b34801561072457600080fd5b5061073f600480360381019061073a919061303c565b611747565b60405161074c9190613186565b60405180910390f35b34801561076157600080fd5b5061077c6004803603810190610777919061303c565b611a0c565b6040516107899190612fe4565b60405180910390f35b34801561079e57600080fd5b506107b960048036038101906107b49190613759565b611b2f565b6040516107c69190612f30565b60405180910390f35b3480156107db57600080fd5b506107f660048036038101906107f191906135ca565b611bc3565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108c357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108d357506108d282611c46565b5b9050919050565b6060600080546108e9906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054610915906137c8565b80156109625780601f1061093757610100808354040283529160200191610962565b820191906000526020600020905b81548152906001019060200180831161094557829003601f168201915b5050505050905090565b600061097782611cb0565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109bd82611299565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a249061386b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a4c611cfb565b73ffffffffffffffffffffffffffffffffffffffff161480610a7b5750610a7a81610a75611cfb565b611b2f565b5b610aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab1906138fd565b60405180910390fd5b610ac48383611d03565b505050565b6060610ad482611747565b604051602001610ae49190613a3d565b6040516020818303038152906040529050919050565b6000858585604051602001610b1193929190613a6a565b60405160208183030381529060405290506000600c82604051610b349190613a9b565b90815260200160405180910390205414610b83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7a90613afe565b60405180910390fd5b610539600a541115610bca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc190613b6a565b60405180910390fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166397aba7f985856040518363ffffffff1660e01b8152600401610c60929190613b99565b602060405180830381865afa158015610c7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca19190613bde565b73ffffffffffffffffffffffffffffffffffffffff1614610cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cee90613c57565b60405180910390fd5b82600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631de810a1836040518263ffffffff1660e01b8152600401610d539190612fe4565b602060405180830381865afa158015610d70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d949190613c8c565b14610dd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dcb90613d05565b60405180910390fd5b610ddc61150b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e5957662386f26fc10000341015610e58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4f90613d71565b60405180910390fd5b5b60006040518060600160405280888152602001878152602001868152509050600a6000815480929190610e8b90613dc0565b9190505550600a54600c83604051610ea39190613a9b565b90815260200160405180910390208190555080600d6000600a5481526020019081526020016000206000820151816000019080519060200190610ee7929190612dd9565b506020820151816001019080519060200190610f04929190612dd9565b506040820151816002019080519060200190610f21929190612dd9565b50905050610f2d61150b565b73ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015610f72573d6000803e3d6000fd5b50610f7f88600a54611dbc565b5050505050505050565b604051806060016040528060268152602001614d916026913981565b610fb6610fb0611cfb565b82611dda565b610ff5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fec90613e7a565b60405180910390fd5b611000838383611e6f565b505050565b604051806060016040528060268152602001614dea6026913981565b604051806101a001604052806101658152602001614c2c610165913981565b611048612168565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561108e573d6000803e3d6000fd5b50565b6110ac838383604051806020016040528060008152506116e5565b505050565b600d6020528060005260406000206000915090508060000180546110d4906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611100906137c8565b801561114d5780601f106111225761010080835404028352916020019161114d565b820191906000526020600020905b81548152906001019060200180831161113057829003601f168201915b505050505090806001018054611162906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461118e906137c8565b80156111db5780601f106111b0576101008083540402835291602001916111db565b820191906000526020600020905b8154815290600101906020018083116111be57829003601f168201915b5050505050908060020180546111f0906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461121c906137c8565b80156112695780601f1061123e57610100808354040283529160200191611269565b820191906000526020600020905b81548152906001019060200180831161124c57829003601f168201915b5050505050905083565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806112a5836121e6565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130d90613ee6565b60405180910390fd5b80915050919050565b6040518060a00160405280606b8152602001614b81606b913981565b60078054611348906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611374906137c8565b80156113c15780601f10611396576101008083540402835291602001916113c1565b820191906000526020600020905b8154815290600101906020018083116113a457829003601f168201915b505050505081565b6040518060400160405280600c81526020017f4861636b6572204861696b75000000000000000000000000000000000000000081525081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146990613f78565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6114c1612168565b6114cb6000612223565b565b604051806060016040528060338152602001614db76033913981565b6114f1612168565b8060089080519060200190611507929190612dd9565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60088054611542906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461156e906137c8565b80156115bb5780601f10611590576101008083540402835291602001916115bb565b820191906000526020600020905b81548152906001019060200180831161159e57829003601f168201915b505050505081565b6060600180546115d2906137c8565b80601f01602080910402602001604051908101604052809291908181526020018280546115fe906137c8565b801561164b5780601f106116205761010080835404028352916020019161164b565b820191906000526020600020905b81548152906001019060200180831161162e57829003601f168201915b5050505050905090565b611667611660611cfb565b83836122e9565b5050565b611673612168565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600c818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6116f66116f0611cfb565b83611dda565b611735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172c90613e7a565b60405180910390fd5b61174184848484612455565b50505050565b6060611752826124b1565b611791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178890613fe4565b60405180910390fd5b6000600d60008481526020019081526020016000206040518060600160405290816000820180546117c1906137c8565b80601f01602080910402602001604051908101604052809291908181526020018280546117ed906137c8565b801561183a5780601f1061180f5761010080835404028352916020019161183a565b820191906000526020600020905b81548152906001019060200180831161181d57829003601f168201915b50505050508152602001600182018054611853906137c8565b80601f016020809104026020016040519081016040528092919081815260200182805461187f906137c8565b80156118cc5780601f106118a1576101008083540402835291602001916118cc565b820191906000526020600020905b8154815290600101906020018083116118af57829003601f168201915b505050505081526020016002820180546118e5906137c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611911906137c8565b801561195e5780601f106119335761010080835404028352916020019161195e565b820191906000526020600020905b81548152906001019060200180831161194157829003601f168201915b5050505050815250509050604051806101a001604052806101658152602001614c2c61016591398160000151604051806060016040528060268152602001614dea602691398360200151604051806060016040528060268152602001614d916026913985604001516040518060a00160405280606b8152602001614b81606b91396040516020016119f59796959493929190614004565b604051602081830303815290604052915050919050565b60606000611a21611a1c84611747565b6124f2565b604051602001611a319190614127565b60405160208183030381529060405290506000611a55611a5085610ac9565b6124f2565b604051602001611a6591906141c6565b60405160208183030381529060405290506000611b036040518060400160405280600c81526020017f4861636b6572204861696b750000000000000000000000000000000000000000815250611aba8761266a565b604051806060016040528060338152602001614db760339139868660076008604051602001611aef979695949392919061448b565b6040516020818303038152906040526124f2565b905080604051602001611b169190614594565b6040516020818303038152906040529350505050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611bcb612168565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3190614628565b60405180910390fd5b611c4381612223565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611cb9816124b1565b611cf8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cef90613ee6565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611d7683611299565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611dd6828260405180602001604052806000815250612738565b5050565b600080611de683611299565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e285750611e278185611b2f565b5b80611e6657508373ffffffffffffffffffffffffffffffffffffffff16611e4e8461096c565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e8f82611299565b73ffffffffffffffffffffffffffffffffffffffff1614611ee5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611edc906146ba565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611f54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f4b9061474c565b60405180910390fd5b611f618383836001612793565b8273ffffffffffffffffffffffffffffffffffffffff16611f8182611299565b73ffffffffffffffffffffffffffffffffffffffff1614611fd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fce906146ba565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461216383838360016128b9565b505050565b612170611cfb565b73ffffffffffffffffffffffffffffffffffffffff1661218e61150b565b73ffffffffffffffffffffffffffffffffffffffff16146121e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121db906147b8565b60405180910390fd5b565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234e90614824565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516124489190612f30565b60405180910390a3505050565b612460848484611e6f565b61246c848484846128bf565b6124ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124a2906148b6565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff166124d3836121e6565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6060600082510361251457604051806020016040528060008152509050612665565b6000604051806060016040528060408152602001614bec604091399050600060036002855161254391906148d6565b61254d919061495b565b6004612559919061498c565b9050600060208261256a91906148d6565b67ffffffffffffffff811115612583576125826131b2565b5b6040519080825280601f01601f1916602001820160405280156125b55781602001600182028036833780820191505090505b509050818152600183018586518101602084015b81831015612624576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f81168501518253600182019150506125c9565b60038951066001811461263e576002811461264e57612659565b613d3d60f01b6002830352612659565b603d60f81b60018303525b50505050508093505050505b919050565b60606000600161267984612a46565b01905060008167ffffffffffffffff811115612698576126976131b2565b5b6040519080825280601f01601f1916602001820160405280156126ca5781602001600182028036833780820191505090505b509050600082602001820190505b60011561272d578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816127215761272061492c565b5b049450600085036126d8575b819350505050919050565b6127428383612b99565b61274f60008484846128bf565b61278e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612785906148b6565b60405180910390fd5b505050565b60018111156128b357600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146128275780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461281f91906149e6565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146128b25780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546128aa91906148d6565b925050819055505b5b50505050565b50505050565b60006128e08473ffffffffffffffffffffffffffffffffffffffff16612db6565b15612a39578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612909611cfb565b8786866040518563ffffffff1660e01b815260040161292b9493929190614a1a565b6020604051808303816000875af192505050801561296757506040513d601f19601f820116820180604052508101906129649190614a7b565b60015b6129e9573d8060008114612997576040519150601f19603f3d011682016040523d82523d6000602084013e61299c565b606091505b5060008151036129e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d8906148b6565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612a3e565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612aa4577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a9a57612a9961492c565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612ae1576d04ee2d6d415b85acef81000000008381612ad757612ad661492c565b5b0492506020810190505b662386f26fc100008310612b1057662386f26fc100008381612b0657612b0561492c565b5b0492506010810190505b6305f5e1008310612b39576305f5e1008381612b2f57612b2e61492c565b5b0492506008810190505b6127108310612b5e576127108381612b5457612b5361492c565b5b0492506004810190505b60648310612b815760648381612b7757612b7661492c565b5b0492506002810190505b600a8310612b90576001810190505b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bff90614af4565b60405180910390fd5b612c11816124b1565b15612c51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c4890614b60565b60405180910390fd5b612c5f600083836001612793565b612c68816124b1565b15612ca8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9f90614b60565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612db26000838360016128b9565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054612de5906137c8565b90600052602060002090601f016020900481019282612e075760008555612e4e565b82601f10612e2057805160ff1916838001178555612e4e565b82800160010185558215612e4e579182015b82811115612e4d578251825591602001919060010190612e32565b5b509050612e5b9190612e5f565b5090565b5b80821115612e78576000816000905550600101612e60565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ec581612e90565b8114612ed057600080fd5b50565b600081359050612ee281612ebc565b92915050565b600060208284031215612efe57612efd612e86565b5b6000612f0c84828501612ed3565b91505092915050565b60008115159050919050565b612f2a81612f15565b82525050565b6000602082019050612f456000830184612f21565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f85578082015181840152602081019050612f6a565b83811115612f94576000848401525b50505050565b6000601f19601f8301169050919050565b6000612fb682612f4b565b612fc08185612f56565b9350612fd0818560208601612f67565b612fd981612f9a565b840191505092915050565b60006020820190508181036000830152612ffe8184612fab565b905092915050565b6000819050919050565b61301981613006565b811461302457600080fd5b50565b60008135905061303681613010565b92915050565b60006020828403121561305257613051612e86565b5b600061306084828501613027565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061309482613069565b9050919050565b6130a481613089565b82525050565b60006020820190506130bf600083018461309b565b92915050565b6130ce81613089565b81146130d957600080fd5b50565b6000813590506130eb816130c5565b92915050565b6000806040838503121561310857613107612e86565b5b6000613116858286016130dc565b925050602061312785828601613027565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b600061315882613131565b613162818561313c565b9350613172818560208601612f67565b61317b81612f9a565b840191505092915050565b600060208201905081810360008301526131a0818461314d565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6131ea82612f9a565b810181811067ffffffffffffffff82111715613209576132086131b2565b5b80604052505050565b600061321c612e7c565b905061322882826131e1565b919050565b600067ffffffffffffffff821115613248576132476131b2565b5b61325182612f9a565b9050602081019050919050565b82818337600083830152505050565b600061328061327b8461322d565b613212565b90508281526020810184848401111561329c5761329b6131ad565b5b6132a784828561325e565b509392505050565b600082601f8301126132c4576132c36131a8565b5b81356132d484826020860161326d565b91505092915050565b6000819050919050565b6132f0816132dd565b81146132fb57600080fd5b50565b60008135905061330d816132e7565b92915050565b600067ffffffffffffffff82111561332e5761332d6131b2565b5b61333782612f9a565b9050602081019050919050565b600061335761335284613313565b613212565b905082815260208101848484011115613373576133726131ad565b5b61337e84828561325e565b509392505050565b600082601f83011261339b5761339a6131a8565b5b81356133ab848260208601613344565b91505092915050565b60008060008060008060c087890312156133d1576133d0612e86565b5b60006133df89828a016130dc565b965050602087013567ffffffffffffffff811115613400576133ff612e8b565b5b61340c89828a016132af565b955050604087013567ffffffffffffffff81111561342d5761342c612e8b565b5b61343989828a016132af565b945050606087013567ffffffffffffffff81111561345a57613459612e8b565b5b61346689828a016132af565b935050608061347789828a016132fe565b92505060a087013567ffffffffffffffff81111561349857613497612e8b565b5b6134a489828a01613386565b9150509295509295509295565b6000806000606084860312156134ca576134c9612e86565b5b60006134d8868287016130dc565b93505060206134e9868287016130dc565b92505060406134fa86828701613027565b9150509250925092565b6000606082019050818103600083015261351e8186612fab565b905081810360208301526135328185612fab565b905081810360408301526135468184612fab565b9050949350505050565b6000819050919050565b600061357561357061356b84613069565b613550565b613069565b9050919050565b60006135878261355a565b9050919050565b60006135998261357c565b9050919050565b6135a98161358e565b82525050565b60006020820190506135c460008301846135a0565b92915050565b6000602082840312156135e0576135df612e86565b5b60006135ee848285016130dc565b91505092915050565b61360081613006565b82525050565b600060208201905061361b60008301846135f7565b92915050565b60006020828403121561363757613636612e86565b5b600082013567ffffffffffffffff81111561365557613654612e8b565b5b613661848285016132af565b91505092915050565b61367381612f15565b811461367e57600080fd5b50565b6000813590506136908161366a565b92915050565b600080604083850312156136ad576136ac612e86565b5b60006136bb858286016130dc565b92505060206136cc85828601613681565b9150509250929050565b600080600080608085870312156136f0576136ef612e86565b5b60006136fe878288016130dc565b945050602061370f878288016130dc565b935050604061372087828801613027565b925050606085013567ffffffffffffffff81111561374157613740612e8b565b5b61374d87828801613386565b91505092959194509250565b600080604083850312156137705761376f612e86565b5b600061377e858286016130dc565b925050602061378f858286016130dc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806137e057607f821691505b6020821081036137f3576137f2613799565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613855602183612f56565b9150613860826137f9565b604082019050919050565b6000602082019050818103600083015261388481613848565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b60006138e7603d83612f56565b91506138f28261388b565b604082019050919050565b60006020820190508181036000830152613916816138da565b9050919050565b600081905092915050565b7f3c21444f43545950452068746d6c3e3c68746d6c3e3c686561643e3c7374796c60008201527f653e2a7b6d617267696e3a303b70616464696e673a307d3c2f7374796c653e3c60208201527f2f686561643e3c626f64793e0000000000000000000000000000000000000000604082015250565b60006139aa604c8361391d565b91506139b582613928565b604c82019050919050565b60006139cb82612f4b565b6139d5818561391d565b93506139e5818560208601612f67565b80840191505092915050565b7f3c2f626f64793e3c2f68746d6c3e000000000000000000000000000000000000600082015250565b6000613a27600e8361391d565b9150613a32826139f1565b600e82019050919050565b6000613a488261399d565b9150613a5482846139c0565b9150613a5f82613a1a565b915081905092915050565b6000613a7682866139c0565b9150613a8282856139c0565b9150613a8e82846139c0565b9150819050949350505050565b6000613aa782846139c0565b915081905092915050565b7f4861696b7520616c726561647920636c61696d65642e00000000000000000000600082015250565b6000613ae8601683612f56565b9150613af382613ab2565b602082019050919050565b60006020820190508181036000830152613b1781613adb565b9050919050565b7f416c6c206f75742e000000000000000000000000000000000000000000000000600082015250565b6000613b54600883612f56565b9150613b5f82613b1e565b602082019050919050565b60006020820190508181036000830152613b8381613b47565b9050919050565b613b93816132dd565b82525050565b6000604082019050613bae6000830185613b8a565b8181036020830152613bc0818461314d565b90509392505050565b600081519050613bd8816130c5565b92915050565b600060208284031215613bf457613bf3612e86565b5b6000613c0284828501613bc9565b91505092915050565b7f496e76616c6964207369676e61747572652e0000000000000000000000000000600082015250565b6000613c41601283612f56565b9150613c4c82613c0b565b602082019050919050565b60006020820190508181036000830152613c7081613c34565b9050919050565b600081519050613c86816132e7565b92915050565b600060208284031215613ca257613ca1612e86565b5b6000613cb084828501613c77565b91505092915050565b7f4861736820616e64206861696b7520646f6e2774206d617463682e0000000000600082015250565b6000613cef601b83612f56565b9150613cfa82613cb9565b602082019050919050565b60006020820190508181036000830152613d1e81613ce2565b9050919050565b7f4e6f7420656e6f756768204554482e0000000000000000000000000000000000600082015250565b6000613d5b600f83612f56565b9150613d6682613d25565b602082019050919050565b60006020820190508181036000830152613d8a81613d4e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613dcb82613006565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dfd57613dfc613d91565b5b600182019050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e64602d83612f56565b9150613e6f82613e08565b604082019050919050565b60006020820190508181036000830152613e9381613e57565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613ed0601883612f56565b9150613edb82613e9a565b602082019050919050565b60006020820190508181036000830152613eff81613ec3565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f62602983612f56565b9150613f6d82613f06565b604082019050919050565b60006020820190508181036000830152613f9181613f55565b9050919050565b7f546f6b656e20646f65736e27742065786973742e000000000000000000000000600082015250565b6000613fce601483612f56565b9150613fd982613f98565b602082019050919050565b60006020820190508181036000830152613ffd81613fc1565b9050919050565b6000614010828a6139c0565b915061401c82896139c0565b915061402882886139c0565b915061403482876139c0565b915061404082866139c0565b915061404c82856139c0565b915061405882846139c0565b915081905098975050505050505050565b7f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b62617360008201527f6536342c00000000000000000000000000000000000000000000000000000000602082015250565b60006140c560248361391d565b91506140d082614069565b602482019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b600061411160028361391d565b915061411c826140db565b600282019050919050565b6000614132826140b8565b915061413e82846139c0565b915061414982614104565b915081905092915050565b7f22616e696d6174696f6e5f75726c223a2022646174613a746578742f68746d6c60008201527f3b6261736536342c000000000000000000000000000000000000000000000000602082015250565b60006141b060288361391d565b91506141bb82614154565b602882019050919050565b60006141d1826141a3565b91506141dd82846139c0565b91506141e882614104565b915081905092915050565b7f7b226e616d65223a202200000000000000000000000000000000000000000000600082015250565b6000614229600a8361391d565b9150614234826141f3565b600a82019050919050565b7f2023000000000000000000000000000000000000000000000000000000000000600082015250565b600061427560028361391d565b91506142808261423f565b600282019050919050565b7f226465736372697074696f6e223a202200000000000000000000000000000000600082015250565b60006142c160108361391d565b91506142cc8261428b565b601082019050919050565b600081905092915050565b60006142ed82613131565b6142f781856142d7565b9350614307818560208601612f67565b80840191505092915050565b7f226c6963656e7365223a20220000000000000000000000000000000000000000600082015250565b6000614349600c8361391d565b915061435482614313565b600c82019050919050565b60008190508160005260206000209050919050565b60008154614381816137c8565b61438b818661391d565b945060018216600081146143a657600181146143b7576143ea565b60ff198316865281860193506143ea565b6143c08561435f565b60005b838110156143e2578154818901526001820191506020810190506143c3565b838801955050505b50505092915050565b7f222c2265787465726e616c5f75726c223a202200000000000000000000000000600082015250565b600061442960138361391d565b9150614434826143f3565b601382019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b600061447560028361391d565b91506144808261443f565b600282019050919050565b60006144968261421c565b91506144a2828a6139c0565b91506144ad82614268565b91506144b982896139c0565b91506144c482614104565b91506144cf826142b4565b91506144db82886139c0565b91506144e682614104565b91506144f282876142e2565b91506144fe82866142e2565b91506145098261433c565b91506145158285614374565b91506145208261441c565b915061452c8284614374565b915061453782614468565b915081905098975050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061457e601d8361391d565b915061458982614548565b601d82019050919050565b600061459f82614571565b91506145ab82846139c0565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614612602683612f56565b915061461d826145b6565b604082019050919050565b6000602082019050818103600083015261464181614605565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006146a4602583612f56565b91506146af82614648565b604082019050919050565b600060208201905081810360008301526146d381614697565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614736602483612f56565b9150614741826146da565b604082019050919050565b6000602082019050818103600083015261476581614729565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006147a2602083612f56565b91506147ad8261476c565b602082019050919050565b600060208201905081810360008301526147d181614795565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061480e601983612f56565b9150614819826147d8565b602082019050919050565b6000602082019050818103600083015261483d81614801565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006148a0603283612f56565b91506148ab82614844565b604082019050919050565b600060208201905081810360008301526148cf81614893565b9050919050565b60006148e182613006565b91506148ec83613006565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561492157614920613d91565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061496682613006565b915061497183613006565b9250826149815761498061492c565b5b828204905092915050565b600061499782613006565b91506149a283613006565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156149db576149da613d91565b5b828202905092915050565b60006149f182613006565b91506149fc83613006565b925082821015614a0f57614a0e613d91565b5b828203905092915050565b6000608082019050614a2f600083018761309b565b614a3c602083018661309b565b614a4960408301856135f7565b8181036060830152614a5b818461314d565b905095945050505050565b600081519050614a7581612ebc565b92915050565b600060208284031215614a9157614a90612e86565b5b6000614a9f84828501614a66565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614ade602083612f56565b9150614ae982614aa8565b602082019050919050565b60006020820190508181036000830152614b0d81614ad1565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614b4a601c83612f56565b9150614b5582614b14565b602082019050919050565b60006020820190508181036000830152614b7981614b3d565b905091905056fe3c2f746578743e3c7265637420783d2233252220793d223325222077696474683d2239342522206865696768743d22393425222066696c6c3d226e6f6e6522207374726f6b653d222330356632323822207374726f6b652d77696474683d222e3525222f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222076696577426f783d223020302032303020323030223e3c7374796c653e2e687b666f6e742d66616d696c793a436f7572696572204e65773b666f6e742d73697a653a313070783b66696c6c3a233035663232383b616e696d6174696f6e3a20796720347320332e397320696e66696e6974653b7d2e66707b666f6e742d66616d696c793a436f7572696572204e65773b666f6e742d73697a653a3370783b66696c6c3a233035663232383b7d406b65796672616d65732079677b30257b66696c6c3a79656c6c6f773b7d3130257b66696c6c3a23333035663232383b7d7d3c2f7374796c653e3c7265637420783d22302220793d2230222077696474683d2232303022206865696768743d22323030222066696c6c3d22626c61636b222f3e3c7465787420783d2231302220793d2238352220636c6173733d2268223e3c2f746578743e3c7465787420783d2231302220793d223131352220636c6173733d2268223e47656e6572617469766520637962657270756e6b207468656d6564206861696b75206d696e7461626c652076696120534d532e3c2f746578743e3c7465787420783d2231302220793d223130302220636c6173733d2268223ea2646970667358221220c6d25413f6da329dea5448d072ab6d153c34a947a634f8b1ecb059a7157958ec64736f6c634300080d0033

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

000000000000000000000000b762f00e5ea9796b0c1e4c0a812a8253615b83c5

-----Decoded View---------------
Arg [0] : _signer (address): 0xb762f00e5EA9796B0C1E4c0a812A8253615B83c5

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000b762f00e5ea9796b0c1e4c0a812a8253615b83c5


Deployed Bytecode Sourcemap

63600:4580:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47692:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48620:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50132:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49650:416;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67736:286;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65096:1102;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64193:80;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50832:335;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64108:78;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63704:397;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68068:109;;;;;;;;;;;;;:::i;:::-;;51238:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64950:36;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;64695:62;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48330:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64280:148;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64588:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64532:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48061:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27123:103;;;;;;;;;;;;;:::i;:::-;;64435:90;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66313:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;26475:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64633:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48789:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50375:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66206:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64906:37;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51494:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67296:432;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66446:842;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50601:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27381:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47692:305;47794:4;47846:25;47831:40;;;:11;:40;;;;:105;;;;47903:33;47888:48;;;:11;:48;;;;47831:105;:158;;;;47953:36;47977:11;47953:23;:36::i;:::-;47831:158;47811:178;;47692:305;;;:::o;48620:100::-;48674:13;48707:5;48700:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48620:100;:::o;50132:171::-;50208:7;50228:23;50243:7;50228:14;:23::i;:::-;50271:15;:24;50287:7;50271:24;;;;;;;;;;;;;;;;;;;;;50264:31;;50132:171;;;:::o;49650:416::-;49731:13;49747:23;49762:7;49747:14;:23::i;:::-;49731:39;;49795:5;49789:11;;:2;:11;;;49781:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;49889:5;49873:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;49898:37;49915:5;49922:12;:10;:12::i;:::-;49898:16;:37::i;:::-;49873:62;49851:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;50037:21;50046:2;50050:7;50037:8;:21::i;:::-;49720:346;49650:416;;:::o;67736:286::-;67792:12;67955:16;67962:8;67955:6;:16::i;:::-;67824:190;;;;;;;;:::i;:::-;;;;;;;;;;;;;67817:197;;67736:286;;;:::o;65096:1102::-;65345:23;65395:6;65403;65411;65378:40;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;65345:74;;65463:1;65442:6;65449:9;65442:17;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;65434:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;65525:4;65514:7;;:15;;65506:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;65633:6;;;;;;;;;;;65565:74;;:15;;;;;;;;;;;:29;;;65595:21;65618:10;65565:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:74;;;65557:105;;;;;;;;;;;;:::i;:::-;;;;;;;;;65744:21;65685:15;;;;;;;;;;;:44;;;65730:9;65685:55;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;65677:120;;;;;;;;;;;;:::i;:::-;;;;;;;;;65832:7;:5;:7::i;:::-;65818:21;;:10;:21;;;65814:113;;65881:10;65868:9;:23;;65860:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;65814:113;65943:18;65964:29;;;;;;;;65970:6;65964:29;;;;65978:6;65964:29;;;;65986:6;65964:29;;;65943:50;;66010:7;;:9;;;;;;;;;:::i;:::-;;;;;;66054:7;;66034:6;66041:9;66034:17;;;;;;:::i;:::-;;;;;;;;;;;;;:27;;;;66094:5;66076:6;:15;66083:7;;66076:15;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;66122:7;:5;:7::i;:::-;66114:25;;:36;66140:9;66114:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66165:23;66175:3;66180:7;;66165:9;:23::i;:::-;65330:868;;65096:1102;;;;;;:::o;64193:80::-;;;;;;;;;;;;;;;;;;;:::o;50832:335::-;51027:41;51046:12;:10;:12::i;:::-;51060:7;51027:18;:41::i;:::-;51019:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;51131:28;51141:4;51147:2;51151:7;51131:9;:28::i;:::-;50832:335;;;:::o;64108:78::-;;;;;;;;;;;;;;;;;;;:::o;63704:397::-;;;;;;;;;;;;;;;;;;;:::o;68068:109::-;26361:13;:11;:13::i;:::-;68126:10:::1;68118:28;;:51;68147:21;68118:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;68068:109::o:0;51238:185::-;51376:39;51393:4;51399:2;51403:7;51376:39;;;;;;;;;;;;:16;:39::i;:::-;51238:185;;;:::o;64950:36::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64695:62::-;;;;;;;;;;;;;:::o;48330:223::-;48402:7;48422:13;48438:17;48447:7;48438:8;:17::i;:::-;48422:33;;48491:1;48474:19;;:5;:19;;;48466:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;48540:5;48533:12;;;48330:223;;;:::o;64280:148::-;;;;;;;;;;;;;;;;;;;:::o;64588:38::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64532:49::-;;;;;;;;;;;;;;;;;;;:::o;48061:207::-;48133:7;48178:1;48161:19;;:5;:19;;;48153:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;48244:9;:16;48254:5;48244:16;;;;;;;;;;;;;;;;48237:23;;48061:207;;;:::o;27123:103::-;26361:13;:11;:13::i;:::-;27188:30:::1;27215:1;27188:18;:30::i;:::-;27123:103::o:0;64435:90::-;;;;;;;;;;;;;;;;;;;:::o;66313:125::-;26361:13;:11;:13::i;:::-;66415:15:::1;66401:11;:29;;;;;;;;;;;;:::i;:::-;;66313:125:::0;:::o;26475:87::-;26521:7;26548:6;;;;;;;;;;;26541:13;;26475:87;:::o;64633:53::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;48789:104::-;48845:13;48878:7;48871:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48789:104;:::o;50375:155::-;50470:52;50489:12;:10;:12::i;:::-;50503:8;50513;50470:18;:52::i;:::-;50375:155;;:::o;66206:99::-;26361:13;:11;:13::i;:::-;66287:10:::1;66278:6;;:19;;;;;;;;;;;;;;;;;;66206:99:::0;:::o;64906:37::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;51494:322::-;51668:41;51687:12;:10;:12::i;:::-;51701:7;51668:18;:41::i;:::-;51660:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;51770:38;51784:4;51790:2;51794:7;51803:4;51770:13;:38::i;:::-;51494:322;;;;:::o;67296:432::-;67351:12;67384:17;67392:8;67384:7;:17::i;:::-;67376:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;67439:18;67460:6;:16;67467:8;67460:16;;;;;;;;;;;67439:37;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67525:12;;;;;;;;;;;;;;;;;67554:5;:11;;;67580:12;;;;;;;;;;;;;;;;;67608:5;:11;;;67635:14;;;;;;;;;;;;;;;;;67665:5;:11;;;67692:13;;;;;;;;;;;;;;;;;67494:226;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;67487:233;;;67296:432;;;:::o;66446:842::-;66520:13;66546:25;66631:31;66645:16;66652:8;66645:6;:16::i;:::-;66631:13;:31::i;:::-;66574:95;;;;;;;;:::i;:::-;;;;;;;;;;;;;66546:123;;66680:24;66768:32;66782:17;66790:8;66782:7;:17::i;:::-;66768:13;:32::i;:::-;66707:100;;;;;;;;:::i;:::-;;;;;;;;;;;;;66680:127;;66820:18;66841:358;66912:9;;;;;;;;;;;;;;;;;66929:26;66946:8;66929:16;:26::i;:::-;66996:11;;;;;;;;;;;;;;;;;67028:12;67055:11;67097:7;67145:11;66867:321;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66841:13;:358::i;:::-;66820:379;;67274:4;67224:55;;;;;;;;:::i;:::-;;;;;;;;;;;;;67210:70;;;;;66446:842;;;:::o;50601:164::-;50698:4;50722:18;:25;50741:5;50722:25;;;;;;;;;;;;;;;:35;50748:8;50722:35;;;;;;;;;;;;;;;;;;;;;;;;;50715:42;;50601:164;;;;:::o;27381:201::-;26361:13;:11;:13::i;:::-;27490:1:::1;27470:22;;:8;:22;;::::0;27462:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;27546:28;27565:8;27546:18;:28::i;:::-;27381:201:::0;:::o;40204:157::-;40289:4;40328:25;40313:40;;;:11;:40;;;;40306:47;;40204:157;;;:::o;59951:135::-;60033:16;60041:7;60033;:16::i;:::-;60025:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;59951:135;:::o;25026:98::-;25079:7;25106:10;25099:17;;25026:98;:::o;59230:174::-;59332:2;59305:15;:24;59321:7;59305:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;59388:7;59384:2;59350:46;;59359:23;59374:7;59359:14;:23::i;:::-;59350:46;;;;;;;;;;;;59230:174;;:::o;54455:110::-;54531:26;54541:2;54545:7;54531:26;;;;;;;;;;;;:9;:26::i;:::-;54455:110;;:::o;53849:264::-;53942:4;53959:13;53975:23;53990:7;53975:14;:23::i;:::-;53959:39;;54028:5;54017:16;;:7;:16;;;:52;;;;54037:32;54054:5;54061:7;54037:16;:32::i;:::-;54017:52;:87;;;;54097:7;54073:31;;:20;54085:7;54073:11;:20::i;:::-;:31;;;54017:87;54009:96;;;53849:264;;;;:::o;57848:1263::-;58007:4;57980:31;;:23;57995:7;57980:14;:23::i;:::-;:31;;;57972:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;58086:1;58072:16;;:2;:16;;;58064:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;58142:42;58163:4;58169:2;58173:7;58182:1;58142:20;:42::i;:::-;58314:4;58287:31;;:23;58302:7;58287:14;:23::i;:::-;:31;;;58279:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;58432:15;:24;58448:7;58432:24;;;;;;;;;;;;58425:31;;;;;;;;;;;58927:1;58908:9;:15;58918:4;58908:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;58960:1;58943:9;:13;58953:2;58943:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;59002:2;58983:7;:16;58991:7;58983:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;59041:7;59037:2;59022:27;;59031:4;59022:27;;;;;;;;;;;;59062:41;59082:4;59088:2;59092:7;59101:1;59062:19;:41::i;:::-;57848:1263;;;:::o;26640:132::-;26715:12;:10;:12::i;:::-;26704:23;;:7;:5;:7::i;:::-;:23;;;26696:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;26640:132::o;53124:117::-;53190:7;53217;:16;53225:7;53217:16;;;;;;;;;;;;;;;;;;;;;53210:23;;53124:117;;;:::o;27742:191::-;27816:16;27835:6;;;;;;;;;;;27816:25;;27861:8;27852:6;;:17;;;;;;;;;;;;;;;;;;27916:8;27885:40;;27906:8;27885:40;;;;;;;;;;;;27805:128;27742:191;:::o;59547:315::-;59702:8;59693:17;;:5;:17;;;59685:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;59789:8;59751:18;:25;59770:5;59751:25;;;;;;;;;;;;;;;:35;59777:8;59751:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;59835:8;59813:41;;59828:5;59813:41;;;59845:8;59813:41;;;;;;:::i;:::-;;;;;;;;59547:315;;;:::o;52697:313::-;52853:28;52863:4;52869:2;52873:7;52853:9;:28::i;:::-;52900:47;52923:4;52929:2;52933:7;52942:4;52900:22;:47::i;:::-;52892:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;52697:313;;;;:::o;53554:128::-;53619:4;53672:1;53643:31;;:17;53652:7;53643:8;:17::i;:::-;:31;;;;53636:38;;53554:128;;;:::o;783:1912::-;841:13;886:1;871:4;:11;:16;867:31;;889:9;;;;;;;;;;;;;;;;867:31;950:19;972:12;;;;;;;;;;;;;;;;;950:34;;1036:18;1082:1;1077;1063:4;:11;:15;;;;:::i;:::-;1062:21;;;;:::i;:::-;1057:1;:27;;;;:::i;:::-;1036:48;;1167:20;1214:2;1201:10;:15;;;;:::i;:::-;1190:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1167:50;;1314:10;1306:6;1299:26;1409:1;1402:5;1398:13;1468:4;1519;1513:11;1504:7;1500:25;1615:2;1607:6;1603:15;1688:754;1707:6;1698:7;1695:19;1688:754;;;1807:1;1798:7;1794:15;1783:26;;1846:7;1840:14;1972:4;1964:5;1960:2;1956:14;1952:25;1942:8;1938:40;1932:47;1921:9;1913:67;2026:1;2015:9;2011:17;1998:30;;2105:4;2097:5;2093:2;2089:14;2085:25;2075:8;2071:40;2065:47;2054:9;2046:67;2159:1;2148:9;2144:17;2131:30;;2238:4;2230:5;2227:1;2222:14;2218:25;2208:8;2204:40;2198:47;2187:9;2179:67;2292:1;2281:9;2277:17;2264:30;;2371:4;2363:5;2351:25;2341:8;2337:40;2331:47;2320:9;2312:67;2425:1;2414:9;2410:17;2397:30;;1731:711;1688:754;;;2515:1;2508:4;2502:11;2498:19;2536:1;2531:54;;;;2604:1;2599:52;;;;2491:160;;2531:54;2575:6;2570:3;2566:16;2562:1;2551:9;2547:17;2540:43;2531:54;;2599:52;2643:4;2638:3;2634:14;2630:1;2619:9;2615:17;2608:41;2491:160;;1239:1423;;;;2681:6;2674:13;;;;;783:1912;;;;:::o;18252:716::-;18308:13;18359:14;18396:1;18376:17;18387:5;18376:10;:17::i;:::-;:21;18359:38;;18412:20;18446:6;18435:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18412:41;;18468:11;18597:6;18593:2;18589:15;18581:6;18577:28;18570:35;;18634:288;18641:4;18634:288;;;18666:5;;;;;;;;18808:8;18803:2;18796:5;18792:14;18787:30;18782:3;18774:44;18864:2;18855:11;;;;;;:::i;:::-;;;;;18898:1;18889:5;:10;18634:288;18885:21;18634:288;18943:6;18936:13;;;;;18252:716;;;:::o;54792:319::-;54921:18;54927:2;54931:7;54921:5;:18::i;:::-;54972:53;55003:1;55007:2;55011:7;55020:4;54972:22;:53::i;:::-;54950:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;54792:319;;;:::o;62235:410::-;62425:1;62413:9;:13;62409:229;;;62463:1;62447:18;;:4;:18;;;62443:87;;62505:9;62486;:15;62496:4;62486:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;62443:87;62562:1;62548:16;;:2;:16;;;62544:83;;62602:9;62585;:13;62595:2;62585:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;62544:83;62409:229;62235:410;;;;:::o;63367:158::-;;;;;:::o;60650:853::-;60804:4;60825:15;:2;:13;;;:15::i;:::-;60821:675;;;60877:2;60861:36;;;60898:12;:10;:12::i;:::-;60912:4;60918:7;60927:4;60861:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;60857:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61119:1;61102:6;:13;:18;61098:328;;61145:60;;;;;;;;;;:::i;:::-;;;;;;;;61098:328;61376:6;61370:13;61361:6;61357:2;61353:15;61346:38;60857:584;60993:41;;;60983:51;;;:6;:51;;;;60976:58;;;;;60821:675;61480:4;61473:11;;60650:853;;;;;;;:::o;15118:922::-;15171:7;15191:14;15208:1;15191:18;;15258:6;15249:5;:15;15245:102;;15294:6;15285:15;;;;;;:::i;:::-;;;;;15329:2;15319:12;;;;15245:102;15374:6;15365:5;:15;15361:102;;15410:6;15401:15;;;;;;:::i;:::-;;;;;15445:2;15435:12;;;;15361:102;15490:6;15481:5;:15;15477:102;;15526:6;15517:15;;;;;;:::i;:::-;;;;;15561:2;15551:12;;;;15477:102;15606:5;15597;:14;15593:99;;15641:5;15632:14;;;;;;:::i;:::-;;;;;15675:1;15665:11;;;;15593:99;15719:5;15710;:14;15706:99;;15754:5;15745:14;;;;;;:::i;:::-;;;;;15788:1;15778:11;;;;15706:99;15832:5;15823;:14;15819:99;;15867:5;15858:14;;;;;;:::i;:::-;;;;;15901:1;15891:11;;;;15819:99;15945:5;15936;:14;15932:66;;15981:1;15971:11;;;;15932:66;16026:6;16019:13;;;15118:922;;;:::o;55447:942::-;55541:1;55527:16;;:2;:16;;;55519:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;55600:16;55608:7;55600;:16::i;:::-;55599:17;55591:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;55662:48;55691:1;55695:2;55699:7;55708:1;55662:20;:48::i;:::-;55809:16;55817:7;55809;:16::i;:::-;55808:17;55800:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;56224:1;56207:9;:13;56217:2;56207:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;56268:2;56249:7;:16;56257:7;56249:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;56313:7;56309:2;56288:33;;56305:1;56288:33;;;;;;;;;;;;56334:47;56362:1;56366:2;56370:7;56379:1;56334:19;:47::i;:::-;55447:942;;:::o;29173:326::-;29233:4;29490:1;29468:7;:19;;;:23;29461:30;;29173:326;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:98::-;4989:6;5023:5;5017:12;5007:22;;4938:98;;;:::o;5042:168::-;5125:11;5159:6;5154:3;5147:19;5199:4;5194:3;5190:14;5175:29;;5042:168;;;;:::o;5216:360::-;5302:3;5330:38;5362:5;5330:38;:::i;:::-;5384:70;5447:6;5442:3;5384:70;:::i;:::-;5377:77;;5463:52;5508:6;5503:3;5496:4;5489:5;5485:16;5463:52;:::i;:::-;5540:29;5562:6;5540:29;:::i;:::-;5535:3;5531:39;5524:46;;5306:270;5216:360;;;;:::o;5582:309::-;5693:4;5731:2;5720:9;5716:18;5708:26;;5780:9;5774:4;5770:20;5766:1;5755:9;5751:17;5744:47;5808:76;5879:4;5870:6;5808:76;:::i;:::-;5800:84;;5582:309;;;;:::o;5897:117::-;6006:1;6003;5996:12;6020:117;6129:1;6126;6119:12;6143:180;6191:77;6188:1;6181:88;6288:4;6285:1;6278:15;6312:4;6309:1;6302:15;6329:281;6412:27;6434:4;6412:27;:::i;:::-;6404:6;6400:40;6542:6;6530:10;6527:22;6506:18;6494:10;6491:34;6488:62;6485:88;;;6553:18;;:::i;:::-;6485:88;6593:10;6589:2;6582:22;6372:238;6329:281;;:::o;6616:129::-;6650:6;6677:20;;:::i;:::-;6667:30;;6706:33;6734:4;6726:6;6706:33;:::i;:::-;6616:129;;;:::o;6751:308::-;6813:4;6903:18;6895:6;6892:30;6889:56;;;6925:18;;:::i;:::-;6889:56;6963:29;6985:6;6963:29;:::i;:::-;6955:37;;7047:4;7041;7037:15;7029:23;;6751:308;;;:::o;7065:154::-;7149:6;7144:3;7139;7126:30;7211:1;7202:6;7197:3;7193:16;7186:27;7065:154;;;:::o;7225:412::-;7303:5;7328:66;7344:49;7386:6;7344:49;:::i;:::-;7328:66;:::i;:::-;7319:75;;7417:6;7410:5;7403:21;7455:4;7448:5;7444:16;7493:3;7484:6;7479:3;7475:16;7472:25;7469:112;;;7500:79;;:::i;:::-;7469:112;7590:41;7624:6;7619:3;7614;7590:41;:::i;:::-;7309:328;7225:412;;;;;:::o;7657:340::-;7713:5;7762:3;7755:4;7747:6;7743:17;7739:27;7729:122;;7770:79;;:::i;:::-;7729:122;7887:6;7874:20;7912:79;7987:3;7979:6;7972:4;7964:6;7960:17;7912:79;:::i;:::-;7903:88;;7719:278;7657:340;;;;:::o;8003:77::-;8040:7;8069:5;8058:16;;8003:77;;;:::o;8086:122::-;8159:24;8177:5;8159:24;:::i;:::-;8152:5;8149:35;8139:63;;8198:1;8195;8188:12;8139:63;8086:122;:::o;8214:139::-;8260:5;8298:6;8285:20;8276:29;;8314:33;8341:5;8314:33;:::i;:::-;8214:139;;;;:::o;8359:307::-;8420:4;8510:18;8502:6;8499:30;8496:56;;;8532:18;;:::i;:::-;8496:56;8570:29;8592:6;8570:29;:::i;:::-;8562:37;;8654:4;8648;8644:15;8636:23;;8359:307;;;:::o;8672:410::-;8749:5;8774:65;8790:48;8831:6;8790:48;:::i;:::-;8774:65;:::i;:::-;8765:74;;8862:6;8855:5;8848:21;8900:4;8893:5;8889:16;8938:3;8929:6;8924:3;8920:16;8917:25;8914:112;;;8945:79;;:::i;:::-;8914:112;9035:41;9069:6;9064:3;9059;9035:41;:::i;:::-;8755:327;8672:410;;;;;:::o;9101:338::-;9156:5;9205:3;9198:4;9190:6;9186:17;9182:27;9172:122;;9213:79;;:::i;:::-;9172:122;9330:6;9317:20;9355:78;9429:3;9421:6;9414:4;9406:6;9402:17;9355:78;:::i;:::-;9346:87;;9162:277;9101:338;;;;:::o;9445:1775::-;9588:6;9596;9604;9612;9620;9628;9677:3;9665:9;9656:7;9652:23;9648:33;9645:120;;;9684:79;;:::i;:::-;9645:120;9804:1;9829:53;9874:7;9865:6;9854:9;9850:22;9829:53;:::i;:::-;9819:63;;9775:117;9959:2;9948:9;9944:18;9931:32;9990:18;9982:6;9979:30;9976:117;;;10012:79;;:::i;:::-;9976:117;10117:63;10172:7;10163:6;10152:9;10148:22;10117:63;:::i;:::-;10107:73;;9902:288;10257:2;10246:9;10242:18;10229:32;10288:18;10280:6;10277:30;10274:117;;;10310:79;;:::i;:::-;10274:117;10415:63;10470:7;10461:6;10450:9;10446:22;10415:63;:::i;:::-;10405:73;;10200:288;10555:2;10544:9;10540:18;10527:32;10586:18;10578:6;10575:30;10572:117;;;10608:79;;:::i;:::-;10572:117;10713:63;10768:7;10759:6;10748:9;10744:22;10713:63;:::i;:::-;10703:73;;10498:288;10825:3;10852:53;10897:7;10888:6;10877:9;10873:22;10852:53;:::i;:::-;10842:63;;10796:119;10982:3;10971:9;10967:19;10954:33;11014:18;11006:6;11003:30;11000:117;;;11036:79;;:::i;:::-;11000:117;11141:62;11195:7;11186:6;11175:9;11171:22;11141:62;:::i;:::-;11131:72;;10925:288;9445:1775;;;;;;;;:::o;11226:619::-;11303:6;11311;11319;11368:2;11356:9;11347:7;11343:23;11339:32;11336:119;;;11374:79;;:::i;:::-;11336:119;11494:1;11519:53;11564:7;11555:6;11544:9;11540:22;11519:53;:::i;:::-;11509:63;;11465:117;11621:2;11647:53;11692:7;11683:6;11672:9;11668:22;11647:53;:::i;:::-;11637:63;;11592:118;11749:2;11775:53;11820:7;11811:6;11800:9;11796:22;11775:53;:::i;:::-;11765:63;;11720:118;11226:619;;;;;:::o;11851:715::-;12060:4;12098:2;12087:9;12083:18;12075:26;;12147:9;12141:4;12137:20;12133:1;12122:9;12118:17;12111:47;12175:78;12248:4;12239:6;12175:78;:::i;:::-;12167:86;;12300:9;12294:4;12290:20;12285:2;12274:9;12270:18;12263:48;12328:78;12401:4;12392:6;12328:78;:::i;:::-;12320:86;;12453:9;12447:4;12443:20;12438:2;12427:9;12423:18;12416:48;12481:78;12554:4;12545:6;12481:78;:::i;:::-;12473:86;;11851:715;;;;;;:::o;12572:60::-;12600:3;12621:5;12614:12;;12572:60;;;:::o;12638:142::-;12688:9;12721:53;12739:34;12748:24;12766:5;12748:24;:::i;:::-;12739:34;:::i;:::-;12721:53;:::i;:::-;12708:66;;12638:142;;;:::o;12786:126::-;12836:9;12869:37;12900:5;12869:37;:::i;:::-;12856:50;;12786:126;;;:::o;12918:150::-;12992:9;13025:37;13056:5;13025:37;:::i;:::-;13012:50;;12918:150;;;:::o;13074:179::-;13185:61;13240:5;13185:61;:::i;:::-;13180:3;13173:74;13074:179;;:::o;13259:270::-;13376:4;13414:2;13403:9;13399:18;13391:26;;13427:95;13519:1;13508:9;13504:17;13495:6;13427:95;:::i;:::-;13259:270;;;;:::o;13535:329::-;13594:6;13643:2;13631:9;13622:7;13618:23;13614:32;13611:119;;;13649:79;;:::i;:::-;13611:119;13769:1;13794:53;13839:7;13830:6;13819:9;13815:22;13794:53;:::i;:::-;13784:63;;13740:117;13535:329;;;;:::o;13870:118::-;13957:24;13975:5;13957:24;:::i;:::-;13952:3;13945:37;13870:118;;:::o;13994:222::-;14087:4;14125:2;14114:9;14110:18;14102:26;;14138:71;14206:1;14195:9;14191:17;14182:6;14138:71;:::i;:::-;13994:222;;;;:::o;14222:509::-;14291:6;14340:2;14328:9;14319:7;14315:23;14311:32;14308:119;;;14346:79;;:::i;:::-;14308:119;14494:1;14483:9;14479:17;14466:31;14524:18;14516:6;14513:30;14510:117;;;14546:79;;:::i;:::-;14510:117;14651:63;14706:7;14697:6;14686:9;14682:22;14651:63;:::i;:::-;14641:73;;14437:287;14222:509;;;;:::o;14737:116::-;14807:21;14822:5;14807:21;:::i;:::-;14800:5;14797:32;14787:60;;14843:1;14840;14833:12;14787:60;14737:116;:::o;14859:133::-;14902:5;14940:6;14927:20;14918:29;;14956:30;14980:5;14956:30;:::i;:::-;14859:133;;;;:::o;14998:468::-;15063:6;15071;15120:2;15108:9;15099:7;15095:23;15091:32;15088:119;;;15126:79;;:::i;:::-;15088:119;15246:1;15271:53;15316:7;15307:6;15296:9;15292:22;15271:53;:::i;:::-;15261:63;;15217:117;15373:2;15399:50;15441:7;15432:6;15421:9;15417:22;15399:50;:::i;:::-;15389:60;;15344:115;14998:468;;;;;:::o;15472:943::-;15567:6;15575;15583;15591;15640:3;15628:9;15619:7;15615:23;15611:33;15608:120;;;15647:79;;:::i;:::-;15608:120;15767:1;15792:53;15837:7;15828:6;15817:9;15813:22;15792:53;:::i;:::-;15782:63;;15738:117;15894:2;15920:53;15965:7;15956:6;15945:9;15941:22;15920:53;:::i;:::-;15910:63;;15865:118;16022:2;16048:53;16093:7;16084:6;16073:9;16069:22;16048:53;:::i;:::-;16038:63;;15993:118;16178:2;16167:9;16163:18;16150:32;16209:18;16201:6;16198:30;16195:117;;;16231:79;;:::i;:::-;16195:117;16336:62;16390:7;16381:6;16370:9;16366:22;16336:62;:::i;:::-;16326:72;;16121:287;15472:943;;;;;;;:::o;16421:474::-;16489:6;16497;16546:2;16534:9;16525:7;16521:23;16517:32;16514:119;;;16552:79;;:::i;:::-;16514:119;16672:1;16697:53;16742:7;16733:6;16722:9;16718:22;16697:53;:::i;:::-;16687:63;;16643:117;16799:2;16825:53;16870:7;16861:6;16850:9;16846:22;16825:53;:::i;:::-;16815:63;;16770:118;16421:474;;;;;:::o;16901:180::-;16949:77;16946:1;16939:88;17046:4;17043:1;17036:15;17070:4;17067:1;17060:15;17087:320;17131:6;17168:1;17162:4;17158:12;17148:22;;17215:1;17209:4;17205:12;17236:18;17226:81;;17292:4;17284:6;17280:17;17270:27;;17226:81;17354:2;17346:6;17343:14;17323:18;17320:38;17317:84;;17373:18;;:::i;:::-;17317:84;17138:269;17087:320;;;:::o;17413:220::-;17553:34;17549:1;17541:6;17537:14;17530:58;17622:3;17617:2;17609:6;17605:15;17598:28;17413:220;:::o;17639:366::-;17781:3;17802:67;17866:2;17861:3;17802:67;:::i;:::-;17795:74;;17878:93;17967:3;17878:93;:::i;:::-;17996:2;17991:3;17987:12;17980:19;;17639:366;;;:::o;18011:419::-;18177:4;18215:2;18204:9;18200:18;18192:26;;18264:9;18258:4;18254:20;18250:1;18239:9;18235:17;18228:47;18292:131;18418:4;18292:131;:::i;:::-;18284:139;;18011:419;;;:::o;18436:248::-;18576:34;18572:1;18564:6;18560:14;18553:58;18645:31;18640:2;18632:6;18628:15;18621:56;18436:248;:::o;18690:366::-;18832:3;18853:67;18917:2;18912:3;18853:67;:::i;:::-;18846:74;;18929:93;19018:3;18929:93;:::i;:::-;19047:2;19042:3;19038:12;19031:19;;18690:366;;;:::o;19062:419::-;19228:4;19266:2;19255:9;19251:18;19243:26;;19315:9;19309:4;19305:20;19301:1;19290:9;19286:17;19279:47;19343:131;19469:4;19343:131;:::i;:::-;19335:139;;19062:419;;;:::o;19487:148::-;19589:11;19626:3;19611:18;;19487:148;;;;:::o;19641:300::-;19781:34;19777:1;19769:6;19765:14;19758:58;19850:34;19845:2;19837:6;19833:15;19826:59;19919:14;19914:2;19906:6;19902:15;19895:39;19641:300;:::o;19947:402::-;20107:3;20128:85;20210:2;20205:3;20128:85;:::i;:::-;20121:92;;20222:93;20311:3;20222:93;:::i;:::-;20340:2;20335:3;20331:12;20324:19;;19947:402;;;:::o;20355:377::-;20461:3;20489:39;20522:5;20489:39;:::i;:::-;20544:89;20626:6;20621:3;20544:89;:::i;:::-;20537:96;;20642:52;20687:6;20682:3;20675:4;20668:5;20664:16;20642:52;:::i;:::-;20719:6;20714:3;20710:16;20703:23;;20465:267;20355:377;;;;:::o;20738:164::-;20878:16;20874:1;20866:6;20862:14;20855:40;20738:164;:::o;20908:402::-;21068:3;21089:85;21171:2;21166:3;21089:85;:::i;:::-;21082:92;;21183:93;21272:3;21183:93;:::i;:::-;21301:2;21296:3;21292:12;21285:19;;20908:402;;;:::o;21316:807::-;21650:3;21672:148;21816:3;21672:148;:::i;:::-;21665:155;;21837:95;21928:3;21919:6;21837:95;:::i;:::-;21830:102;;21949:148;22093:3;21949:148;:::i;:::-;21942:155;;22114:3;22107:10;;21316:807;;;;:::o;22129:595::-;22357:3;22379:95;22470:3;22461:6;22379:95;:::i;:::-;22372:102;;22491:95;22582:3;22573:6;22491:95;:::i;:::-;22484:102;;22603:95;22694:3;22685:6;22603:95;:::i;:::-;22596:102;;22715:3;22708:10;;22129:595;;;;;;:::o;22730:275::-;22862:3;22884:95;22975:3;22966:6;22884:95;:::i;:::-;22877:102;;22996:3;22989:10;;22730:275;;;;:::o;23011:172::-;23151:24;23147:1;23139:6;23135:14;23128:48;23011:172;:::o;23189:366::-;23331:3;23352:67;23416:2;23411:3;23352:67;:::i;:::-;23345:74;;23428:93;23517:3;23428:93;:::i;:::-;23546:2;23541:3;23537:12;23530:19;;23189:366;;;:::o;23561:419::-;23727:4;23765:2;23754:9;23750:18;23742:26;;23814:9;23808:4;23804:20;23800:1;23789:9;23785:17;23778:47;23842:131;23968:4;23842:131;:::i;:::-;23834:139;;23561:419;;;:::o;23986:158::-;24126:10;24122:1;24114:6;24110:14;24103:34;23986:158;:::o;24150:365::-;24292:3;24313:66;24377:1;24372:3;24313:66;:::i;:::-;24306:73;;24388:93;24477:3;24388:93;:::i;:::-;24506:2;24501:3;24497:12;24490:19;;24150:365;;;:::o;24521:419::-;24687:4;24725:2;24714:9;24710:18;24702:26;;24774:9;24768:4;24764:20;24760:1;24749:9;24745:17;24738:47;24802:131;24928:4;24802:131;:::i;:::-;24794:139;;24521:419;;;:::o;24946:118::-;25033:24;25051:5;25033:24;:::i;:::-;25028:3;25021:37;24946:118;;:::o;25070:419::-;25209:4;25247:2;25236:9;25232:18;25224:26;;25260:71;25328:1;25317:9;25313:17;25304:6;25260:71;:::i;:::-;25378:9;25372:4;25368:20;25363:2;25352:9;25348:18;25341:48;25406:76;25477:4;25468:6;25406:76;:::i;:::-;25398:84;;25070:419;;;;;:::o;25495:143::-;25552:5;25583:6;25577:13;25568:22;;25599:33;25626:5;25599:33;:::i;:::-;25495:143;;;;:::o;25644:351::-;25714:6;25763:2;25751:9;25742:7;25738:23;25734:32;25731:119;;;25769:79;;:::i;:::-;25731:119;25889:1;25914:64;25970:7;25961:6;25950:9;25946:22;25914:64;:::i;:::-;25904:74;;25860:128;25644:351;;;;:::o;26001:168::-;26141:20;26137:1;26129:6;26125:14;26118:44;26001:168;:::o;26175:366::-;26317:3;26338:67;26402:2;26397:3;26338:67;:::i;:::-;26331:74;;26414:93;26503:3;26414:93;:::i;:::-;26532:2;26527:3;26523:12;26516:19;;26175:366;;;:::o;26547:419::-;26713:4;26751:2;26740:9;26736:18;26728:26;;26800:9;26794:4;26790:20;26786:1;26775:9;26771:17;26764:47;26828:131;26954:4;26828:131;:::i;:::-;26820:139;;26547:419;;;:::o;26972:143::-;27029:5;27060:6;27054:13;27045:22;;27076:33;27103:5;27076:33;:::i;:::-;26972:143;;;;:::o;27121:351::-;27191:6;27240:2;27228:9;27219:7;27215:23;27211:32;27208:119;;;27246:79;;:::i;:::-;27208:119;27366:1;27391:64;27447:7;27438:6;27427:9;27423:22;27391:64;:::i;:::-;27381:74;;27337:128;27121:351;;;;:::o;27478:177::-;27618:29;27614:1;27606:6;27602:14;27595:53;27478:177;:::o;27661:366::-;27803:3;27824:67;27888:2;27883:3;27824:67;:::i;:::-;27817:74;;27900:93;27989:3;27900:93;:::i;:::-;28018:2;28013:3;28009:12;28002:19;;27661:366;;;:::o;28033:419::-;28199:4;28237:2;28226:9;28222:18;28214:26;;28286:9;28280:4;28276:20;28272:1;28261:9;28257:17;28250:47;28314:131;28440:4;28314:131;:::i;:::-;28306:139;;28033:419;;;:::o;28458:165::-;28598:17;28594:1;28586:6;28582:14;28575:41;28458:165;:::o;28629:366::-;28771:3;28792:67;28856:2;28851:3;28792:67;:::i;:::-;28785:74;;28868:93;28957:3;28868:93;:::i;:::-;28986:2;28981:3;28977:12;28970:19;;28629:366;;;:::o;29001:419::-;29167:4;29205:2;29194:9;29190:18;29182:26;;29254:9;29248:4;29244:20;29240:1;29229:9;29225:17;29218:47;29282:131;29408:4;29282:131;:::i;:::-;29274:139;;29001:419;;;:::o;29426:180::-;29474:77;29471:1;29464:88;29571:4;29568:1;29561:15;29595:4;29592:1;29585:15;29612:233;29651:3;29674:24;29692:5;29674:24;:::i;:::-;29665:33;;29720:66;29713:5;29710:77;29707:103;;29790:18;;:::i;:::-;29707:103;29837:1;29830:5;29826:13;29819:20;;29612:233;;;:::o;29851:232::-;29991:34;29987:1;29979:6;29975:14;29968:58;30060:15;30055:2;30047:6;30043:15;30036:40;29851:232;:::o;30089:366::-;30231:3;30252:67;30316:2;30311:3;30252:67;:::i;:::-;30245:74;;30328:93;30417:3;30328:93;:::i;:::-;30446:2;30441:3;30437:12;30430:19;;30089:366;;;:::o;30461:419::-;30627:4;30665:2;30654:9;30650:18;30642:26;;30714:9;30708:4;30704:20;30700:1;30689:9;30685:17;30678:47;30742:131;30868:4;30742:131;:::i;:::-;30734:139;;30461:419;;;:::o;30886:174::-;31026:26;31022:1;31014:6;31010:14;31003:50;30886:174;:::o;31066:366::-;31208:3;31229:67;31293:2;31288:3;31229:67;:::i;:::-;31222:74;;31305:93;31394:3;31305:93;:::i;:::-;31423:2;31418:3;31414:12;31407:19;;31066:366;;;:::o;31438:419::-;31604:4;31642:2;31631:9;31627:18;31619:26;;31691:9;31685:4;31681:20;31677:1;31666:9;31662:17;31655:47;31719:131;31845:4;31719:131;:::i;:::-;31711:139;;31438:419;;;:::o;31863:228::-;32003:34;31999:1;31991:6;31987:14;31980:58;32072:11;32067:2;32059:6;32055:15;32048:36;31863:228;:::o;32097:366::-;32239:3;32260:67;32324:2;32319:3;32260:67;:::i;:::-;32253:74;;32336:93;32425:3;32336:93;:::i;:::-;32454:2;32449:3;32445:12;32438:19;;32097:366;;;:::o;32469:419::-;32635:4;32673:2;32662:9;32658:18;32650:26;;32722:9;32716:4;32712:20;32708:1;32697:9;32693:17;32686:47;32750:131;32876:4;32750:131;:::i;:::-;32742:139;;32469:419;;;:::o;32894:170::-;33034:22;33030:1;33022:6;33018:14;33011:46;32894:170;:::o;33070:366::-;33212:3;33233:67;33297:2;33292:3;33233:67;:::i;:::-;33226:74;;33309:93;33398:3;33309:93;:::i;:::-;33427:2;33422:3;33418:12;33411:19;;33070:366;;;:::o;33442:419::-;33608:4;33646:2;33635:9;33631:18;33623:26;;33695:9;33689:4;33685:20;33681:1;33670:9;33666:17;33659:47;33723:131;33849:4;33723:131;:::i;:::-;33715:139;;33442:419;;;:::o;33867:1235::-;34287:3;34309:95;34400:3;34391:6;34309:95;:::i;:::-;34302:102;;34421:95;34512:3;34503:6;34421:95;:::i;:::-;34414:102;;34533:95;34624:3;34615:6;34533:95;:::i;:::-;34526:102;;34645:95;34736:3;34727:6;34645:95;:::i;:::-;34638:102;;34757:95;34848:3;34839:6;34757:95;:::i;:::-;34750:102;;34869:95;34960:3;34951:6;34869:95;:::i;:::-;34862:102;;34981:95;35072:3;35063:6;34981:95;:::i;:::-;34974:102;;35093:3;35086:10;;33867:1235;;;;;;;;;;:::o;35108:255::-;35248:66;35244:1;35236:6;35232:14;35225:90;35349:6;35344:2;35336:6;35332:15;35325:31;35108:255;:::o;35369:402::-;35529:3;35550:85;35632:2;35627:3;35550:85;:::i;:::-;35543:92;;35644:93;35733:3;35644:93;:::i;:::-;35762:2;35757:3;35753:12;35746:19;;35369:402;;;:::o;35777:214::-;35917:66;35913:1;35905:6;35901:14;35894:90;35777:214;:::o;35997:400::-;36157:3;36178:84;36260:1;36255:3;36178:84;:::i;:::-;36171:91;;36271:93;36360:3;36271:93;:::i;:::-;36389:1;36384:3;36380:11;36373:18;;35997:400;;;:::o;36403:807::-;36737:3;36759:148;36903:3;36759:148;:::i;:::-;36752:155;;36924:95;37015:3;37006:6;36924:95;:::i;:::-;36917:102;;37036:148;37180:3;37036:148;:::i;:::-;37029:155;;37201:3;37194:10;;36403:807;;;;:::o;37216:259::-;37356:66;37352:1;37344:6;37340:14;37333:90;37457:10;37452:2;37444:6;37440:15;37433:35;37216:259;:::o;37481:402::-;37641:3;37662:85;37744:2;37739:3;37662:85;:::i;:::-;37655:92;;37756:93;37845:3;37756:93;:::i;:::-;37874:2;37869:3;37865:12;37858:19;;37481:402;;;:::o;37889:807::-;38223:3;38245:148;38389:3;38245:148;:::i;:::-;38238:155;;38410:95;38501:3;38492:6;38410:95;:::i;:::-;38403:102;;38522:148;38666:3;38522:148;:::i;:::-;38515:155;;38687:3;38680:10;;37889:807;;;;:::o;38702:214::-;38842:66;38838:1;38830:6;38826:14;38819:90;38702:214;:::o;38922:402::-;39082:3;39103:85;39185:2;39180:3;39103:85;:::i;:::-;39096:92;;39197:93;39286:3;39197:93;:::i;:::-;39315:2;39310:3;39306:12;39299:19;;38922:402;;;:::o;39330:152::-;39470:4;39466:1;39458:6;39454:14;39447:28;39330:152;:::o;39488:400::-;39648:3;39669:84;39751:1;39746:3;39669:84;:::i;:::-;39662:91;;39762:93;39851:3;39762:93;:::i;:::-;39880:1;39875:3;39871:11;39864:18;;39488:400;;;:::o;39894:214::-;40034:66;40030:1;40022:6;40018:14;40011:90;39894:214;:::o;40114:402::-;40274:3;40295:85;40377:2;40372:3;40295:85;:::i;:::-;40288:92;;40389:93;40478:3;40389:93;:::i;:::-;40507:2;40502:3;40498:12;40491:19;;40114:402;;;:::o;40522:147::-;40623:11;40660:3;40645:18;;40522:147;;;;:::o;40675:373::-;40779:3;40807:38;40839:5;40807:38;:::i;:::-;40861:88;40942:6;40937:3;40861:88;:::i;:::-;40854:95;;40958:52;41003:6;40998:3;40991:4;40984:5;40980:16;40958:52;:::i;:::-;41035:6;41030:3;41026:16;41019:23;;40783:265;40675:373;;;;:::o;41054:214::-;41194:66;41190:1;41182:6;41178:14;41171:90;41054:214;:::o;41274:402::-;41434:3;41455:85;41537:2;41532:3;41455:85;:::i;:::-;41448:92;;41549:93;41638:3;41549:93;:::i;:::-;41667:2;41662:3;41658:12;41651:19;;41274:402;;;:::o;41682:141::-;41731:4;41754:3;41746:11;;41777:3;41774:1;41767:14;41811:4;41808:1;41798:18;41790:26;;41682:141;;;:::o;41853:845::-;41956:3;41993:5;41987:12;42022:36;42048:9;42022:36;:::i;:::-;42074:89;42156:6;42151:3;42074:89;:::i;:::-;42067:96;;42194:1;42183:9;42179:17;42210:1;42205:137;;;;42356:1;42351:341;;;;42172:520;;42205:137;42289:4;42285:9;42274;42270:25;42265:3;42258:38;42325:6;42320:3;42316:16;42309:23;;42205:137;;42351:341;42418:38;42450:5;42418:38;:::i;:::-;42478:1;42492:154;42506:6;42503:1;42500:13;42492:154;;;42580:7;42574:14;42570:1;42565:3;42561:11;42554:35;42630:1;42621:7;42617:15;42606:26;;42528:4;42525:1;42521:12;42516:17;;42492:154;;;42675:6;42670:3;42666:16;42659:23;;42358:334;;42172:520;;41960:738;;41853:845;;;;:::o;42704:214::-;42844:66;42840:1;42832:6;42828:14;42821:90;42704:214;:::o;42924:402::-;43084:3;43105:85;43187:2;43182:3;43105:85;:::i;:::-;43098:92;;43199:93;43288:3;43199:93;:::i;:::-;43317:2;43312:3;43308:12;43301:19;;42924:402;;;:::o;43332:214::-;43472:66;43468:1;43460:6;43456:14;43449:90;43332:214;:::o;43552:400::-;43712:3;43733:84;43815:1;43810:3;43733:84;:::i;:::-;43726:91;;43826:93;43915:3;43826:93;:::i;:::-;43944:1;43939:3;43935:11;43928:18;;43552:400;;;:::o;43958:3343::-;45176:3;45198:148;45342:3;45198:148;:::i;:::-;45191:155;;45363:95;45454:3;45445:6;45363:95;:::i;:::-;45356:102;;45475:148;45619:3;45475:148;:::i;:::-;45468:155;;45640:95;45731:3;45722:6;45640:95;:::i;:::-;45633:102;;45752:148;45896:3;45752:148;:::i;:::-;45745:155;;45917:148;46061:3;45917:148;:::i;:::-;45910:155;;46082:95;46173:3;46164:6;46082:95;:::i;:::-;46075:102;;46194:148;46338:3;46194:148;:::i;:::-;46187:155;;46359:93;46448:3;46439:6;46359:93;:::i;:::-;46352:100;;46469:93;46558:3;46549:6;46469:93;:::i;:::-;46462:100;;46579:148;46723:3;46579:148;:::i;:::-;46572:155;;46744:92;46832:3;46823:6;46744:92;:::i;:::-;46737:99;;46853:148;46997:3;46853:148;:::i;:::-;46846:155;;47018:92;47106:3;47097:6;47018:92;:::i;:::-;47011:99;;47127:148;47271:3;47127:148;:::i;:::-;47120:155;;47292:3;47285:10;;43958:3343;;;;;;;;;;:::o;47307:179::-;47447:31;47443:1;47435:6;47431:14;47424:55;47307:179;:::o;47492:402::-;47652:3;47673:85;47755:2;47750:3;47673:85;:::i;:::-;47666:92;;47767:93;47856:3;47767:93;:::i;:::-;47885:2;47880:3;47876:12;47869:19;;47492:402;;;:::o;47900:541::-;48133:3;48155:148;48299:3;48155:148;:::i;:::-;48148:155;;48320:95;48411:3;48402:6;48320:95;:::i;:::-;48313:102;;48432:3;48425:10;;47900:541;;;;:::o;48447:225::-;48587:34;48583:1;48575:6;48571:14;48564:58;48656:8;48651:2;48643:6;48639:15;48632:33;48447:225;:::o;48678:366::-;48820:3;48841:67;48905:2;48900:3;48841:67;:::i;:::-;48834:74;;48917:93;49006:3;48917:93;:::i;:::-;49035:2;49030:3;49026:12;49019:19;;48678:366;;;:::o;49050:419::-;49216:4;49254:2;49243:9;49239:18;49231:26;;49303:9;49297:4;49293:20;49289:1;49278:9;49274:17;49267:47;49331:131;49457:4;49331:131;:::i;:::-;49323:139;;49050:419;;;:::o;49475:224::-;49615:34;49611:1;49603:6;49599:14;49592:58;49684:7;49679:2;49671:6;49667:15;49660:32;49475:224;:::o;49705:366::-;49847:3;49868:67;49932:2;49927:3;49868:67;:::i;:::-;49861:74;;49944:93;50033:3;49944:93;:::i;:::-;50062:2;50057:3;50053:12;50046:19;;49705:366;;;:::o;50077:419::-;50243:4;50281:2;50270:9;50266:18;50258:26;;50330:9;50324:4;50320:20;50316:1;50305:9;50301:17;50294:47;50358:131;50484:4;50358:131;:::i;:::-;50350:139;;50077:419;;;:::o;50502:223::-;50642:34;50638:1;50630:6;50626:14;50619:58;50711:6;50706:2;50698:6;50694:15;50687:31;50502:223;:::o;50731:366::-;50873:3;50894:67;50958:2;50953:3;50894:67;:::i;:::-;50887:74;;50970:93;51059:3;50970:93;:::i;:::-;51088:2;51083:3;51079:12;51072:19;;50731:366;;;:::o;51103:419::-;51269:4;51307:2;51296:9;51292:18;51284:26;;51356:9;51350:4;51346:20;51342:1;51331:9;51327:17;51320:47;51384:131;51510:4;51384:131;:::i;:::-;51376:139;;51103:419;;;:::o;51528:182::-;51668:34;51664:1;51656:6;51652:14;51645:58;51528:182;:::o;51716:366::-;51858:3;51879:67;51943:2;51938:3;51879:67;:::i;:::-;51872:74;;51955:93;52044:3;51955:93;:::i;:::-;52073:2;52068:3;52064:12;52057:19;;51716:366;;;:::o;52088:419::-;52254:4;52292:2;52281:9;52277:18;52269:26;;52341:9;52335:4;52331:20;52327:1;52316:9;52312:17;52305:47;52369:131;52495:4;52369:131;:::i;:::-;52361:139;;52088:419;;;:::o;52513:175::-;52653:27;52649:1;52641:6;52637:14;52630:51;52513:175;:::o;52694:366::-;52836:3;52857:67;52921:2;52916:3;52857:67;:::i;:::-;52850:74;;52933:93;53022:3;52933:93;:::i;:::-;53051:2;53046:3;53042:12;53035:19;;52694:366;;;:::o;53066:419::-;53232:4;53270:2;53259:9;53255:18;53247:26;;53319:9;53313:4;53309:20;53305:1;53294:9;53290:17;53283:47;53347:131;53473:4;53347:131;:::i;:::-;53339:139;;53066:419;;;:::o;53491:237::-;53631:34;53627:1;53619:6;53615:14;53608:58;53700:20;53695:2;53687:6;53683:15;53676:45;53491:237;:::o;53734:366::-;53876:3;53897:67;53961:2;53956:3;53897:67;:::i;:::-;53890:74;;53973:93;54062:3;53973:93;:::i;:::-;54091:2;54086:3;54082:12;54075:19;;53734:366;;;:::o;54106:419::-;54272:4;54310:2;54299:9;54295:18;54287:26;;54359:9;54353:4;54349:20;54345:1;54334:9;54330:17;54323:47;54387:131;54513:4;54387:131;:::i;:::-;54379:139;;54106:419;;;:::o;54531:305::-;54571:3;54590:20;54608:1;54590:20;:::i;:::-;54585:25;;54624:20;54642:1;54624:20;:::i;:::-;54619:25;;54778:1;54710:66;54706:74;54703:1;54700:81;54697:107;;;54784:18;;:::i;:::-;54697:107;54828:1;54825;54821:9;54814:16;;54531:305;;;;:::o;54842:180::-;54890:77;54887:1;54880:88;54987:4;54984:1;54977:15;55011:4;55008:1;55001:15;55028:185;55068:1;55085:20;55103:1;55085:20;:::i;:::-;55080:25;;55119:20;55137:1;55119:20;:::i;:::-;55114:25;;55158:1;55148:35;;55163:18;;:::i;:::-;55148:35;55205:1;55202;55198:9;55193:14;;55028:185;;;;:::o;55219:348::-;55259:7;55282:20;55300:1;55282:20;:::i;:::-;55277:25;;55316:20;55334:1;55316:20;:::i;:::-;55311:25;;55504:1;55436:66;55432:74;55429:1;55426:81;55421:1;55414:9;55407:17;55403:105;55400:131;;;55511:18;;:::i;:::-;55400:131;55559:1;55556;55552:9;55541:20;;55219:348;;;;:::o;55573:191::-;55613:4;55633:20;55651:1;55633:20;:::i;:::-;55628:25;;55667:20;55685:1;55667:20;:::i;:::-;55662:25;;55706:1;55703;55700:8;55697:34;;;55711:18;;:::i;:::-;55697:34;55756:1;55753;55749:9;55741:17;;55573:191;;;;:::o;55770:640::-;55965:4;56003:3;55992:9;55988:19;55980:27;;56017:71;56085:1;56074:9;56070:17;56061:6;56017:71;:::i;:::-;56098:72;56166:2;56155:9;56151:18;56142:6;56098:72;:::i;:::-;56180;56248:2;56237:9;56233:18;56224:6;56180:72;:::i;:::-;56299:9;56293:4;56289:20;56284:2;56273:9;56269:18;56262:48;56327:76;56398:4;56389:6;56327:76;:::i;:::-;56319:84;;55770:640;;;;;;;:::o;56416:141::-;56472:5;56503:6;56497:13;56488:22;;56519:32;56545:5;56519:32;:::i;:::-;56416:141;;;;:::o;56563:349::-;56632:6;56681:2;56669:9;56660:7;56656:23;56652:32;56649:119;;;56687:79;;:::i;:::-;56649:119;56807:1;56832:63;56887:7;56878:6;56867:9;56863:22;56832:63;:::i;:::-;56822:73;;56778:127;56563:349;;;;:::o;56918:182::-;57058:34;57054:1;57046:6;57042:14;57035:58;56918:182;:::o;57106:366::-;57248:3;57269:67;57333:2;57328:3;57269:67;:::i;:::-;57262:74;;57345:93;57434:3;57345:93;:::i;:::-;57463:2;57458:3;57454:12;57447:19;;57106:366;;;:::o;57478:419::-;57644:4;57682:2;57671:9;57667:18;57659:26;;57731:9;57725:4;57721:20;57717:1;57706:9;57702:17;57695:47;57759:131;57885:4;57759:131;:::i;:::-;57751:139;;57478:419;;;:::o;57903:178::-;58043:30;58039:1;58031:6;58027:14;58020:54;57903:178;:::o;58087:366::-;58229:3;58250:67;58314:2;58309:3;58250:67;:::i;:::-;58243:74;;58326:93;58415:3;58326:93;:::i;:::-;58444:2;58439:3;58435:12;58428:19;;58087:366;;;:::o;58459:419::-;58625:4;58663:2;58652:9;58648:18;58640:26;;58712:9;58706:4;58702:20;58698:1;58687:9;58683:17;58676:47;58740:131;58866:4;58740:131;:::i;:::-;58732:139;;58459:419;;;:::o

Swarm Source

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