Overview

TokenID

8

Total Transfers

-

Market

Onchain Market Cap

-

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
SkyRocketNFTFactory

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at SonicScan.org on 2024-12-11
*/

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

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

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

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

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

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

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

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 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 functionCall(target, data, "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");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason 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 {
            // 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    function hasRole(bytes32 role, address account) external view returns (bool);

    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    function grantRole(bytes32 role, address account) external;

    function revokeRole(bytes32 role, address account) external;

    function renounceRole(bytes32 role, address account) external;
}

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    modifier isAdmin() {
        require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Account is not in the admin list");
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                abi.encodePacked(
                    "AccessControl: account ",
                    Strings.toHexString(uint160(account), 20),
                    " is missing role ",
                    Strings.toHexString(uint256(role), 32)
                )
            )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
    external
    view
    returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

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

    function getPrivateUri() public view virtual returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for the zero address");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
    public
    view
    virtual
    override
    returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(_msgSender() != operator, "ERC1155: setting approval status for self");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(account != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);

        _balances[id][account] += amount;
        emit TransferSingle(operator, address(0), account, id, amount);

        _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `account`
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address account,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");

        uint256 accountBalance = _balances[id][account];
        require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][account] = accountBalance - amount;
        }

        emit TransferSingle(operator, account, address(0), id, amount);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 accountBalance = _balances[id][account];
            require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][account] = accountBalance - amount;
            }
        }

        emit TransferBatch(operator, account, address(0), ids, amounts);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

/**
 * @dev Extension of ERC1155 that adds tracking of total supply per id.
 *
 * Useful for scenarios where Fungible and Non-fungible tokens have to be
 * clearly identified. Note: While a totalSupply of 1 might mean the
 * corresponding is an NFT, there is no guarantees that no other token with the
 * same id are not going to be minted.
 */
abstract contract ERC1155Supply is ERC1155 {
    mapping(uint256 => uint256) private _totalSupply;

    /**
     * @dev Total amount of tokens in with a given id.
     */
    function totalSupply(uint256 id) public view virtual returns (uint256) {
        return _totalSupply[id];
    }

    /**
     * @dev Indicates whether any token exist with a given id, or not.
     */
    function exists(uint256 id) public view virtual returns (bool) {
        return ERC1155Supply.totalSupply(id) > 0;
    }

    /**
     * @dev See {ERC1155-_mint}.
     */
    function _mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual override {
        super._mint(account, id, amount, data);
        _totalSupply[id] += amount;
    }

    /**
     * @dev See {ERC1155-_mintBatch}.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        super._mintBatch(to, ids, amounts, data);
        for (uint256 i = 0; i < ids.length; ++i) {
            _totalSupply[ids[i]] += amounts[i];
        }
    }

    /**
     * @dev See {ERC1155-_burn}.
     */
    function _burn(
        address account,
        uint256 id,
        uint256 amount
    ) internal virtual override {
        super._burn(account, id, amount);
        _totalSupply[id] -= amount;
    }

    /**
     * @dev See {ERC1155-_burnBatch}.
     */
    function _burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual override {
        super._burnBatch(account, ids, amounts);
        for (uint256 i = 0; i < ids.length; ++i) {
            _totalSupply[ids[i]] -= amounts[i];
        }
    }
}

/**
 * @dev Extension of {ERC1155} that allows token holders to destroy both their
 * own tokens and those that they have been approved to use.
 *
 * _Available since v3.1._
 */
abstract contract ERC1155Burnable is ERC1155Supply {


    function burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory values
    ) public virtual {
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        _burnBatch(account, ids, values);
    }
}

contract SkyRocketNFTFactory is ERC1155Burnable, AccessControl {

    bool private UseNewERC1155Uri = false;

    uint256 public nftId = 1;
    uint256 public totalSupplyNFT = 200_000;

    uint256 private dnaDigits = 16;
    uint256 private dnaModulus = 10 ** dnaDigits;

    struct SkyRocketNFTStruct {
        bool initialized;
        uint256 tier;
        string tierName;
        uint256 DNA;
    }

    // Maps the NFT Id to the SkyRocketNFT
    mapping(uint256 => SkyRocketNFTStruct) public SkyRocketNFT;  // Maps NFTId by SkyRocketNFTStruct

    // Maps the Address to the NFT Ids owned by the address
    mapping(address => uint256[]) public ownedNFTs;  // Maps Address by NFTId

    constructor() ERC1155("https://skyrocket.fi/nft/") {
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
    }

    // Needed for compiling
    function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC1155, AccessControl) returns (bool) {
        return super.supportsInterface(_interfaceId);
    }

    // Getters and Setters
    /**
    * @dev
    * use new ERC1155 standard ?
    **/
    function updateUseNewERC1155Uri(bool _val) public isAdmin {
        UseNewERC1155Uri = _val;
    }

    /**
    * @dev Update the URI
    **/
    function updateUri(string memory _newUri) public isAdmin {
        _setURI(_newUri);
    }

    /**
    * @dev Update the total supply
    **/
    function updateTotalSupplyNFT(uint256 _newTotalSupplyNFT) public isAdmin {
        totalSupplyNFT = _newTotalSupplyNFT;
    }

    /**
    * @dev Increment the nftId, private
    **/
    function _incrementNftId() private {
        nftId++;
    }

    /**
    * @dev Get the total owned NFTs by the address
    **/
    function getTotalOwnedNFTs(address _address) public view returns (uint256 _totalOwnedNFTs) {
        return ownedNFTs[_address].length;
    }

    /**
    * @dev Get array of all owned NFTs by the address
    **/
    function getOwnedNFTs(address _address) public view returns (uint256[] memory _ownedNFTs) {
        return ownedNFTs[_address];
    }

    /**
    * @dev Get DNA by NFT Id
    **/
    function getDNAByNFTId(uint256 _nftId) public view returns (uint256 _dna) {
        return SkyRocketNFT[_nftId].DNA;
    }

    /**
    * @dev See {IERC1155MetadataURI-uri}.
    *
    * This implementation returns the same URI for *all* token types. It relies
    * on the token type ID substitution mechanism
    * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
    *
    * Clients calling this function must replace the `\{id\}` substring with the
    * actual token type ID.
    *
    * REMEMBER: We have updated the ERC1155 and added getPrivateUri() ?-_-?
    **/
    function uri(uint256 _id) public view virtual override returns (string memory) {
        require(SkyRocketNFT[_id].initialized == true, "NFT does not exist");

        if (UseNewERC1155Uri) {
            return getPrivateUri();  // Just remember to add {id}.json
        }

        return string(abi.encodePacked(getPrivateUri(), Strings.toString(_id)));
    }

    /**
    * @dev
    * Get the Tier based on the NFT Id
    **/
    function getTierByNFTId(uint256 _nftId) public view returns (uint256 _tier) {
        return SkyRocketNFT[_nftId].tier;
    }

    /**
    * @dev
    * Get the Tier Name based on the NFT Id
    **/
    function getTierNameByNFTId(uint256 _nftId) public view returns (string memory _tierName) {
        return SkyRocketNFT[_nftId].tierName;
    }

    // BusinessLogic
    /**
    * @dev Create a random DNA
    **/
    function createRandomDNA() public view returns (uint256)
    {
        return
            uint256(
                keccak256(
                    abi.encodePacked(
                        block.timestamp,
                        block.difficulty,
                        msg.sender
                    )
                )
            ) % dnaModulus;
    }

    /**
    * @dev Add NFT to collection (mint) owner
    **/
    function addNFTToCollection(address _receiver, uint256 _nftId) internal isAdmin {
        ownedNFTs[_receiver].push(_nftId);
    }

    /**
    * @dev Remove NFT from collection (burn) owner
    **/
    function removeNFTFromCollection(address _receiver, uint256 _nftId) internal isAdmin {
        // Loop through the ownedNFTs and remove the NFT Id,
        // Create a new array without the NFT Id and replace the old array
        uint256[] memory _ownedNFTs = new uint256[](ownedNFTs[_receiver].length - 1);

        uint256 j = 0;
        for (uint256 i = 0; i < ownedNFTs[_receiver].length; i++) {
            if (ownedNFTs[_receiver][i] != _nftId) {
                _ownedNFTs[j] = ownedNFTs[_receiver][i];
                j++;
            }
        }

        // Replace the old array with the new array
        ownedNFTs[_receiver] = _ownedNFTs;
    }

    /**
    * @dev Mint the token to the _receiver address, although you can specify a quantity it is suggested to mint only 1
    * Only Admins are allowed to mint tokens
    **/
    function mint(address _receiver, bytes calldata _data) public isAdmin {
        require(nftId <= totalSupplyNFT, "NFT no longer mintable");
        require(SkyRocketNFT[nftId].initialized == false, "NFT already exists");

        createSkyRocketNFT(_receiver, _data);
    }

    function burn(address account, uint256 id, uint256 value) public virtual {
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        removeNFTFromCollection(account, id);

        _burn(account, id, value);
    }

    /**
    * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        // Remove the NFT from the collection of the sender
        removeNFTFromCollection(from, id);

        // Add the NFT to the collection of the receiver
        addNFTToCollection(to, id);

        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: transfer caller is not owner nor approved"
        );

        // For each NFT Id in the array, remove the NFT from the collection of the sender
        for (uint256 i = 0; i < ids.length; i++) {
            // Remove the NFT from the collection of the sender
            removeNFTFromCollection(from, ids[i]);

            // Add the NFT to the collection of the receiver
            addNFTToCollection(to, ids[i]);
        }

        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
    * @dev Create a new NFT
    **/
    function createSkyRocketNFT(address _receiver, bytes calldata _data) private {
        uint256 _dna = createRandomDNA();

        string memory _tierName = "NORMAL";

        if (nftId <= 50) {
            _tierName = "LEGENDARY";
        } else if (nftId > 50 && nftId <= 100) {
            _tierName = "EPIC";
        } else if (nftId > 100 && nftId <= 150) {
            _tierName = "RARE";
        } else if (nftId > 150 && nftId <= 200) {
            _tierName = "UNCOMMON";
        } else if (nftId > 200 && nftId <= 250) {
            _tierName = "COMMON";
        }

        SkyRocketNFT[nftId] = SkyRocketNFTStruct(true, 1, _tierName, _dna);

        // Add the NFT Id to the ownedNFTs array
        addNFTToCollection(_receiver, nftId);

        _mint(_receiver, nftId, 1, _data);

        _incrementNftId();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"SkyRocketNFT","outputs":[{"internalType":"bool","name":"initialized","type":"bool"},{"internalType":"uint256","name":"tier","type":"uint256"},{"internalType":"string","name":"tierName","type":"string"},{"internalType":"uint256","name":"DNA","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createRandomDNA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"getDNAByNFTId","outputs":[{"internalType":"uint256","name":"_dna","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getOwnedNFTs","outputs":[{"internalType":"uint256[]","name":"_ownedNFTs","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrivateUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"getTierByNFTId","outputs":[{"internalType":"uint256","name":"_tier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"getTierNameByNFTId","outputs":[{"internalType":"string","name":"_tierName","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getTotalOwnedNFTs","outputs":[{"internalType":"uint256","name":"_totalOwnedNFTs","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nftId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedNFTs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","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":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTotalSupplyNFT","type":"uint256"}],"name":"updateTotalSupplyNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newUri","type":"string"}],"name":"updateUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_val","type":"bool"}],"name":"updateUseNewERC1155Uri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

60806040526000600560006101000a81548160ff021916908315150217905550600160065562030d406007556010600855600854600a62000041919062000489565b6009553480156200005157600080fd5b506040518060400160405280601981526020017f68747470733a2f2f736b79726f636b65742e66692f6e66742f000000000000008152506200009981620000b560201b60201c565b50620000af6000801b33620000d160201b60201c565b6200053f565b8060029080519060200190620000cd9291906200024c565b5050565b620000e38282620000e760201b60201c565b5050565b620000f98282620001d960201b60201c565b620001d55760016004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200017a6200024460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b8280546200025a9062000509565b90600052602060002090601f0160209004810192826200027e5760008555620002ca565b82601f106200029957805160ff1916838001178555620002ca565b82800160010185558215620002ca579182015b82811115620002c9578251825591602001919060010190620002ac565b5b509050620002d99190620002dd565b5090565b5b80821115620002f8576000816000905550600101620002de565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160011c9050919050565b6000808291508390505b60018511156200038a57808604811115620003625762000361620002fc565b5b6001851615620003725780820291505b808102905062000382856200032b565b945062000342565b94509492505050565b600082620003a5576001905062000478565b81620003b5576000905062000478565b8160018114620003ce5760028114620003d9576200040f565b600191505062000478565b60ff841115620003ee57620003ed620002fc565b5b8360020a915084821115620004085762000407620002fc565b5b5062000478565b5060208310610133831016604e8410600b8410161715620004495782820a905083811115620004435762000442620002fc565b5b62000478565b62000458848484600162000338565b92509050818404811115620004725762000471620002fc565b5b81810290505b9392505050565b6000819050919050565b600062000496826200047f565b9150620004a3836200047f565b9250620004d27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000393565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200052257607f821691505b60208210811415620005395762000538620004da565b5b50919050565b6154ec806200054f6000396000f3fe608060405234801561001057600080fd5b50600436106101fa5760003560e01c806354f5db3f1161011a578063b0ea6a84116100ad578063c6bc51821161007c578063c6bc518214610646578063d547741f14610664578063e985e9c514610680578063f242432a146106b0578063f5298aca146106cc576101fa565b8063b0ea6a84146105be578063b510391f146105dc578063bc7882d1146105f8578063bd85b03914610616576101fa565b806391d14854116100e957806391d14854146105365780639e23e98314610566578063a217fddf14610584578063a22cb465146105a2576101fa565b806354f5db3f1461049b578063570b3c6a146104cb5780636b20c454146104e7578063870e6bbf14610503576101fa565b8063248a9ca31161019257806336568abe1161016157806336568abe146103ef5780634551169d1461040b5780634e1273f41461043b5780634f558e791461046b576101fa565b8063248a9ca31461036b578063286e901d1461039b5780632eb2c2d6146103b75780632f2ff15d146103d3576101fa565b806314115c85116101ce57806314115c85146102bf57806318148f1b146102ef5780631a72b87d1461031f5780631da5e15f1461034f576101fa565b8062fdd58e146101ff57806301ffc9a71461022f5780630c29a4df1461025f5780630e89341c1461028f575b600080fd5b61021960048036038101906102149190613765565b6106e8565b60405161022691906137b4565b60405180910390f35b61024960048036038101906102449190613827565b6107b1565b604051610256919061386f565b60405180910390f35b6102796004803603810190610274919061388a565b6107c3565b60405161028691906137b4565b60405180910390f35b6102a960048036038101906102a4919061388a565b6107e3565b6040516102b69190613950565b60405180910390f35b6102d960048036038101906102d49190613972565b6108ac565b6040516102e691906137b4565b60405180910390f35b61030960048036038101906103049190613972565b6108f8565b6040516103169190613a5d565b60405180910390f35b61033960048036038101906103349190613765565b61098f565b60405161034691906137b4565b60405180910390f35b61036960048036038101906103649190613aab565b6109c0565b005b61038560048036038101906103809190613b0e565b610a30565b6040516103929190613b4a565b60405180910390f35b6103b560048036038101906103b0919061388a565b610a50565b005b6103d160048036038101906103cc9190613d62565b610aad565b005b6103ed60048036038101906103e89190613e31565b610bb6565b005b61040960048036038101906104049190613e31565b610bdf565b005b6104256004803603810190610420919061388a565b610c62565b60405161043291906137b4565b60405180910390f35b61045560048036038101906104509190613f34565b610c82565b6040516104629190613a5d565b60405180910390f35b6104856004803603810190610480919061388a565b610d9b565b604051610492919061386f565b60405180910390f35b6104b560048036038101906104b0919061388a565b610daf565b6040516104c29190613950565b60405180910390f35b6104e560048036038101906104e0919061404d565b610e57565b005b61050160048036038101906104fc9190614096565b610eb6565b005b61051d6004803603810190610518919061388a565b610f53565b60405161052d9493929190614121565b60405180910390f35b610550600480360381019061054b9190613e31565b611018565b60405161055d919061386f565b60405180910390f35b61056e611083565b60405161057b9190613950565b60405180910390f35b61058c611115565b6040516105999190613b4a565b60405180910390f35b6105bc60048036038101906105b7919061416d565b61111c565b005b6105c661129d565b6040516105d391906137b4565b60405180910390f35b6105f660048036038101906105f19190614208565b6112a3565b005b6106006113b9565b60405161060d91906137b4565b60405180910390f35b610630600480360381019061062b919061388a565b6113fb565b60405161063d91906137b4565b60405180910390f35b61064e611418565b60405161065b91906137b4565b60405180910390f35b61067e60048036038101906106799190613e31565b61141e565b005b61069a60048036038101906106959190614268565b611447565b6040516106a7919061386f565b60405180910390f35b6106ca60048036038101906106c591906142a8565b6114db565b005b6106e660048036038101906106e1919061433f565b611590565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075090614404565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006107bc82611637565b9050919050565b6000600a6000838152602001908152602001600020600301549050919050565b606060011515600a600084815260200190815260200160002060000160009054906101000a900460ff1615151461084f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084690614470565b60405180910390fd5b600560009054906101000a900460ff16156108735761086c611083565b90506108a7565b61087b611083565b610884836116b1565b6040516020016108959291906144cc565b60405160208183030381529060405290505b919050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6060600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561098357602002820191906000526020600020905b81548152602001906001019080831161096f575b50505050509050919050565b600b60205281600052604060002081815481106109ab57600080fd5b90600052602060002001600091509150505481565b6109d46000801b6109cf611812565b611018565b610a13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0a9061453c565b60405180910390fd5b80600560006101000a81548160ff02191690831515021790555050565b600060046000838152602001908152602001600020600101549050919050565b610a646000801b610a5f611812565b611018565b610aa3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9a9061453c565b60405180910390fd5b8060078190555050565b610ab5611812565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480610afb5750610afa85610af5611812565b611447565b5b610b3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b31906145ce565b60405180910390fd5b60005b8351811015610ba157610b6a86858381518110610b5d57610b5c6145ee565b5b602002602001015161181a565b610b8e85858381518110610b8157610b806145ee565b5b6020026020010151611ab0565b8080610b999061464c565b915050610b3d565b50610baf8585858585611b6d565b5050505050565b610bbf82610a30565b610bd081610bcb611812565b611e81565b610bda8383611f1e565b505050565b610be7611812565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4b90614707565b60405180910390fd5b610c5e8282611fff565b5050565b6000600a6000838152602001908152602001600020600101549050919050565b60608151835114610cc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cbf90614799565b60405180910390fd5b6000835167ffffffffffffffff811115610ce557610ce4613b6a565b5b604051908082528060200260200182016040528015610d135781602001602082028036833780820191505090505b50905060005b8451811015610d9057610d60858281518110610d3857610d376145ee565b5b6020026020010151858381518110610d5357610d526145ee565b5b60200260200101516106e8565b828281518110610d7357610d726145ee565b5b60200260200101818152505080610d899061464c565b9050610d19565b508091505092915050565b600080610da7836113fb565b119050919050565b6060600a60008381526020019081526020016000206002018054610dd2906147e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfe906147e8565b8015610e4b5780601f10610e2057610100808354040283529160200191610e4b565b820191906000526020600020905b815481529060010190602001808311610e2e57829003601f168201915b50505050509050919050565b610e6b6000801b610e66611812565b611018565b610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea19061453c565b60405180910390fd5b610eb3816120e1565b50565b610ebe611812565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480610f045750610f0383610efe611812565b611447565b5b610f43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3a9061488c565b60405180910390fd5b610f4e8383836120fb565b505050565b600a6020528060005260406000206000915090508060000160009054906101000a900460ff1690806001015490806002018054610f8f906147e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbb906147e8565b80156110085780601f10610fdd57610100808354040283529160200191611008565b820191906000526020600020905b815481529060010190602001808311610feb57829003601f168201915b5050505050908060030154905084565b60006004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060028054611092906147e8565b80601f01602080910402602001604051908101604052809291908181526020018280546110be906147e8565b801561110b5780601f106110e05761010080835404028352916020019161110b565b820191906000526020600020905b8154815290600101906020018083116110ee57829003601f168201915b5050505050905090565b6000801b81565b8173ffffffffffffffffffffffffffffffffffffffff1661113b611812565b73ffffffffffffffffffffffffffffffffffffffff161415611192576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111899061491e565b60405180910390fd5b806001600061119f611812565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661124c611812565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611291919061386f565b60405180910390a35050565b60075481565b6112b76000801b6112b2611812565b611018565b6112f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ed9061453c565b60405180910390fd5b600754600654111561133d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113349061498a565b60405180910390fd5b60001515600a6000600654815260200190815260200160002060000160009054906101000a900460ff161515146113a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a0906149f6565b60405180910390fd5b6113b4838383612187565b505050565b60006009544244336040516020016113d393929190614a7f565b6040516020818303038152906040528051906020012060001c6113f69190614aeb565b905090565b600060036000838152602001908152602001600020549050919050565b60065481565b61142782610a30565b61143881611433611812565b611e81565b6114428383611fff565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6114e3611812565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611529575061152885611523611812565b611447565b5b611568576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155f9061488c565b60405180910390fd5b611572858461181a565b61157c8484611ab0565b611589858585858561246c565b5050505050565b611598611812565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806115de57506115dd836115d8611812565b611447565b5b61161d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116149061488c565b60405180910390fd5b611627838361181a565b6116328383836126ee565b505050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806116aa57506116a982612728565b5b9050919050565b606060008214156116f9576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061180d565b600082905060005b6000821461172b5780806117149061464c565b915050600a826117249190614b1c565b9150611701565b60008167ffffffffffffffff81111561174757611746613b6a565b5b6040519080825280601f01601f1916602001820160405280156117795781602001600182028036833780820191505090505b5090505b60008514611806576001826117929190614b4d565b9150600a856117a19190614aeb565b60306117ad9190614b81565b60f81b8183815181106117c3576117c26145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856117ff9190614b1c565b945061177d565b8093505050505b919050565b600033905090565b61182e6000801b611829611812565b611018565b61186d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118649061453c565b60405180910390fd5b60006001600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490506118be9190614b4d565b67ffffffffffffffff8111156118d7576118d6613b6a565b5b6040519080825280602002602001820160405280156119055781602001602082028036833780820191505090505b5090506000805b600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050811015611a555783600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106119a8576119a76145ee565b5b906000526020600020015414611a4257600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208181548110611a0957611a086145ee565b5b9060005260206000200154838381518110611a2757611a266145ee565b5b6020026020010181815250508180611a3e9061464c565b9250505b8080611a4d9061464c565b91505061190c565b5081600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190611aa99291906135cd565b5050505050565b611ac46000801b611abf611812565b611018565b611b03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611afa9061453c565b60405180910390fd5b600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002001600090919091909150555050565b8151835114611bb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba890614c49565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1890614cdb565b60405180910390fd5b6000611c2b611812565b9050611c3b81878787878761280a565b60005b8451811015611dec576000858281518110611c5c57611c5b6145ee565b5b602002602001015190506000858381518110611c7b57611c7a6145ee565b5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614d6d565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dd19190614b81565b9250508190555050505080611de59061464c565b9050611c3e565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611e63929190614d8d565b60405180910390a4611e79818787878787612812565b505050505050565b611e8b8282611018565b611f1a57611eb08173ffffffffffffffffffffffffffffffffffffffff1660146129f9565b611ebe8360001c60206129f9565b604051602001611ecf929190614e5c565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f119190613950565b60405180910390fd5b5050565b611f288282611018565b611ffb5760016004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611fa0611812565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6120098282611018565b156120dd5760006004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612082611812565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b80600290805190602001906120f792919061361a565b5050565b612106838383612c35565b60005b825181101561218157818181518110612125576121246145ee565b5b602002602001015160036000858481518110612144576121436145ee565b5b6020026020010151815260200190815260200160002060008282546121699190614b4d565b925050819055508061217a9061464c565b9050612109565b50505050565b60006121916113b9565b905060006040518060400160405280600681526020017f4e4f524d414c00000000000000000000000000000000000000000000000000008152509050603260065411612214576040518060400160405280600981526020017f4c4547454e4441525900000000000000000000000000000000000000000000008152509050612370565b60326006541180156122295750606460065411155b1561226b576040518060400160405280600481526020017f4550494300000000000000000000000000000000000000000000000000000000815250905061236f565b60646006541180156122805750609660065411155b156122c2576040518060400160405280600481526020017f5241524500000000000000000000000000000000000000000000000000000000815250905061236e565b60966006541180156122d7575060c860065411155b15612319576040518060400160405280600881526020017f554e434f4d4d4f4e000000000000000000000000000000000000000000000000815250905061236d565b60c860065411801561232e575060fa60065411155b1561236c576040518060400160405280600681526020017f434f4d4d4f4e000000000000000000000000000000000000000000000000000081525090505b5b5b5b5b60405180608001604052806001151581526020016001815260200182815260200183815250600a6000600654815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020190805190602001906123f092919061361a565b506060820151816003015590505061240a85600654611ab0565b61245d85600654600187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612ee6565b612465612f22565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156124dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124d390614cdb565b60405180910390fd5b60006124e6611812565b90506125068187876124f788612f3c565b61250088612f3c565b8761280a565b600080600086815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508381101561259d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259490614d6d565b60405180910390fd5b83810360008087815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508360008087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546126529190614b81565b925050819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6288886040516126cf929190614e96565b60405180910390a46126e5828888888888612fb6565b50505050505050565b6126f983838361319d565b8060036000848152602001908152602001600020600082825461271c9190614b4d565b92505081905550505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806127f357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806128035750612802826133ba565b5b9050919050565b505050505050565b6128318473ffffffffffffffffffffffffffffffffffffffff16613424565b156129f1578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b8152600401612877959493929190614f23565b602060405180830381600087803b15801561289157600080fd5b505af19250505080156128c257506040513d601f19601f820116820180604052508101906128bf9190614fa0565b60015b612968576128ce614fda565b806308c379a0141561292b57506128e3614ffc565b806128ee575061292d565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129229190613950565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295f90615104565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146129ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129e690615196565b60405180910390fd5b505b505050505050565b606060006002836002612a0c91906151b6565b612a169190614b81565b67ffffffffffffffff811115612a2f57612a2e613b6a565b5b6040519080825280601f01601f191660200182016040528015612a615781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a9957612a986145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612afd57612afc6145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612b3d91906151b6565b612b479190614b81565b90505b6001811115612be7577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612b8957612b886145ee565b5b1a60f81b828281518110612ba057612b9f6145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612be090615210565b9050612b4a565b5060008414612c2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2290615286565b60405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612ca5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9c90615318565b60405180910390fd5b8051825114612ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce090614c49565b60405180910390fd5b6000612cf3611812565b9050612d138185600086866040518060200160405280600081525061280a565b60005b8351811015612e60576000848281518110612d3457612d336145ee565b5b602002602001015190506000848381518110612d5357612d526145ee565b5b60200260200101519050600080600084815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612df4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612deb906153aa565b60405180910390fd5b81810360008085815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050508080612e589061464c565b915050612d16565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612ed8929190614d8d565b60405180910390a450505050565b612ef284848484613437565b81600360008581526020019081526020016000206000828254612f159190614b81565b9250508190555050505050565b60066000815480929190612f359061464c565b9190505550565b60606000600167ffffffffffffffff811115612f5b57612f5a613b6a565b5b604051908082528060200260200182016040528015612f895781602001602082028036833780820191505090505b5090508281600081518110612fa157612fa06145ee565b5b60200260200101818152505080915050919050565b612fd58473ffffffffffffffffffffffffffffffffffffffff16613424565b15613195578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b815260040161301b9594939291906153ca565b602060405180830381600087803b15801561303557600080fd5b505af192505050801561306657506040513d601f19601f820116820180604052508101906130639190614fa0565b60015b61310c57613072614fda565b806308c379a014156130cf5750613087614ffc565b8061309257506130d1565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130c69190613950565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161310390615104565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318a90615196565b60405180910390fd5b505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561320d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320490615318565b60405180910390fd5b6000613217611812565b90506132478185600061322987612f3c565b61323287612f3c565b6040518060200160405280600081525061280a565b600080600085815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156132de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d5906153aa565b60405180910390fd5b82810360008086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6287876040516133ab929190614e96565b60405180910390a45050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600080823b905060008111915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156134a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349e90615496565b60405180910390fd5b60006134b1611812565b90506134d2816000876134c388612f3c565b6134cc88612f3c565b8761280a565b8260008086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546135319190614b81565b925050819055508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6287876040516135af929190614e96565b60405180910390a46135c681600087878787612fb6565b5050505050565b828054828255906000526020600020908101928215613609579160200282015b828111156136085782518255916020019190600101906135ed565b5b50905061361691906136a0565b5090565b828054613626906147e8565b90600052602060002090601f016020900481019282613648576000855561368f565b82601f1061366157805160ff191683800117855561368f565b8280016001018555821561368f579182015b8281111561368e578251825591602001919060010190613673565b5b50905061369c91906136a0565b5090565b5b808211156136b95760008160009055506001016136a1565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006136fc826136d1565b9050919050565b61370c816136f1565b811461371757600080fd5b50565b60008135905061372981613703565b92915050565b6000819050919050565b6137428161372f565b811461374d57600080fd5b50565b60008135905061375f81613739565b92915050565b6000806040838503121561377c5761377b6136c7565b5b600061378a8582860161371a565b925050602061379b85828601613750565b9150509250929050565b6137ae8161372f565b82525050565b60006020820190506137c960008301846137a5565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613804816137cf565b811461380f57600080fd5b50565b600081359050613821816137fb565b92915050565b60006020828403121561383d5761383c6136c7565b5b600061384b84828501613812565b91505092915050565b60008115159050919050565b61386981613854565b82525050565b60006020820190506138846000830184613860565b92915050565b6000602082840312156138a05761389f6136c7565b5b60006138ae84828501613750565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156138f15780820151818401526020810190506138d6565b83811115613900576000848401525b50505050565b6000601f19601f8301169050919050565b6000613922826138b7565b61392c81856138c2565b935061393c8185602086016138d3565b61394581613906565b840191505092915050565b6000602082019050818103600083015261396a8184613917565b905092915050565b600060208284031215613988576139876136c7565b5b60006139968482850161371a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6139d48161372f565b82525050565b60006139e683836139cb565b60208301905092915050565b6000602082019050919050565b6000613a0a8261399f565b613a1481856139aa565b9350613a1f836139bb565b8060005b83811015613a50578151613a3788826139da565b9750613a42836139f2565b925050600181019050613a23565b5085935050505092915050565b60006020820190508181036000830152613a7781846139ff565b905092915050565b613a8881613854565b8114613a9357600080fd5b50565b600081359050613aa581613a7f565b92915050565b600060208284031215613ac157613ac06136c7565b5b6000613acf84828501613a96565b91505092915050565b6000819050919050565b613aeb81613ad8565b8114613af657600080fd5b50565b600081359050613b0881613ae2565b92915050565b600060208284031215613b2457613b236136c7565b5b6000613b3284828501613af9565b91505092915050565b613b4481613ad8565b82525050565b6000602082019050613b5f6000830184613b3b565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613ba282613906565b810181811067ffffffffffffffff82111715613bc157613bc0613b6a565b5b80604052505050565b6000613bd46136bd565b9050613be08282613b99565b919050565b600067ffffffffffffffff821115613c0057613bff613b6a565b5b602082029050602081019050919050565b600080fd5b6000613c29613c2484613be5565b613bca565b90508083825260208201905060208402830185811115613c4c57613c4b613c11565b5b835b81811015613c755780613c618882613750565b845260208401935050602081019050613c4e565b5050509392505050565b600082601f830112613c9457613c93613b65565b5b8135613ca4848260208601613c16565b91505092915050565b600080fd5b600067ffffffffffffffff821115613ccd57613ccc613b6a565b5b613cd682613906565b9050602081019050919050565b82818337600083830152505050565b6000613d05613d0084613cb2565b613bca565b905082815260208101848484011115613d2157613d20613cad565b5b613d2c848285613ce3565b509392505050565b600082601f830112613d4957613d48613b65565b5b8135613d59848260208601613cf2565b91505092915050565b600080600080600060a08688031215613d7e57613d7d6136c7565b5b6000613d8c8882890161371a565b9550506020613d9d8882890161371a565b945050604086013567ffffffffffffffff811115613dbe57613dbd6136cc565b5b613dca88828901613c7f565b935050606086013567ffffffffffffffff811115613deb57613dea6136cc565b5b613df788828901613c7f565b925050608086013567ffffffffffffffff811115613e1857613e176136cc565b5b613e2488828901613d34565b9150509295509295909350565b60008060408385031215613e4857613e476136c7565b5b6000613e5685828601613af9565b9250506020613e678582860161371a565b9150509250929050565b600067ffffffffffffffff821115613e8c57613e8b613b6a565b5b602082029050602081019050919050565b6000613eb0613eab84613e71565b613bca565b90508083825260208201905060208402830185811115613ed357613ed2613c11565b5b835b81811015613efc5780613ee8888261371a565b845260208401935050602081019050613ed5565b5050509392505050565b600082601f830112613f1b57613f1a613b65565b5b8135613f2b848260208601613e9d565b91505092915050565b60008060408385031215613f4b57613f4a6136c7565b5b600083013567ffffffffffffffff811115613f6957613f686136cc565b5b613f7585828601613f06565b925050602083013567ffffffffffffffff811115613f9657613f956136cc565b5b613fa285828601613c7f565b9150509250929050565b600067ffffffffffffffff821115613fc757613fc6613b6a565b5b613fd082613906565b9050602081019050919050565b6000613ff0613feb84613fac565b613bca565b90508281526020810184848401111561400c5761400b613cad565b5b614017848285613ce3565b509392505050565b600082601f83011261403457614033613b65565b5b8135614044848260208601613fdd565b91505092915050565b600060208284031215614063576140626136c7565b5b600082013567ffffffffffffffff811115614081576140806136cc565b5b61408d8482850161401f565b91505092915050565b6000806000606084860312156140af576140ae6136c7565b5b60006140bd8682870161371a565b935050602084013567ffffffffffffffff8111156140de576140dd6136cc565b5b6140ea86828701613c7f565b925050604084013567ffffffffffffffff81111561410b5761410a6136cc565b5b61411786828701613c7f565b9150509250925092565b60006080820190506141366000830187613860565b61414360208301866137a5565b81810360408301526141558185613917565b905061416460608301846137a5565b95945050505050565b60008060408385031215614184576141836136c7565b5b60006141928582860161371a565b92505060206141a385828601613a96565b9150509250929050565b600080fd5b60008083601f8401126141c8576141c7613b65565b5b8235905067ffffffffffffffff8111156141e5576141e46141ad565b5b60208301915083600182028301111561420157614200613c11565b5b9250929050565b600080600060408486031215614221576142206136c7565b5b600061422f8682870161371a565b935050602084013567ffffffffffffffff8111156142505761424f6136cc565b5b61425c868287016141b2565b92509250509250925092565b6000806040838503121561427f5761427e6136c7565b5b600061428d8582860161371a565b925050602061429e8582860161371a565b9150509250929050565b600080600080600060a086880312156142c4576142c36136c7565b5b60006142d28882890161371a565b95505060206142e38882890161371a565b94505060406142f488828901613750565b935050606061430588828901613750565b925050608086013567ffffffffffffffff811115614326576143256136cc565b5b61433288828901613d34565b9150509295509295909350565b600080600060608486031215614358576143576136c7565b5b60006143668682870161371a565b935050602061437786828701613750565b925050604061438886828701613750565b9150509250925092565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b60006143ee602b836138c2565b91506143f982614392565b604082019050919050565b6000602082019050818103600083015261441d816143e1565b9050919050565b7f4e465420646f6573206e6f742065786973740000000000000000000000000000600082015250565b600061445a6012836138c2565b915061446582614424565b602082019050919050565b600060208201905081810360008301526144898161444d565b9050919050565b600081905092915050565b60006144a6826138b7565b6144b08185614490565b93506144c08185602086016138d3565b80840191505092915050565b60006144d8828561449b565b91506144e4828461449b565b91508190509392505050565b7f4163636f756e74206973206e6f7420696e207468652061646d696e206c697374600082015250565b60006145266020836138c2565b9150614531826144f0565b602082019050919050565b6000602082019050818103600083015261455581614519565b9050919050565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b60006145b86032836138c2565b91506145c38261455c565b604082019050919050565b600060208201905081810360008301526145e7816145ab565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006146578261372f565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561468a5761468961461d565b5b600182019050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b60006146f1602f836138c2565b91506146fc82614695565b604082019050919050565b60006020820190508181036000830152614720816146e4565b9050919050565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b60006147836029836138c2565b915061478e82614727565b604082019050919050565b600060208201905081810360008301526147b281614776565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061480057607f821691505b60208210811415614814576148136147b9565b5b50919050565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b60006148766029836138c2565b91506148818261481a565b604082019050919050565b600060208201905081810360008301526148a581614869565b9050919050565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b60006149086029836138c2565b9150614913826148ac565b604082019050919050565b60006020820190508181036000830152614937816148fb565b9050919050565b7f4e4654206e6f206c6f6e676572206d696e7461626c6500000000000000000000600082015250565b60006149746016836138c2565b915061497f8261493e565b602082019050919050565b600060208201905081810360008301526149a381614967565b9050919050565b7f4e465420616c7265616479206578697374730000000000000000000000000000600082015250565b60006149e06012836138c2565b91506149eb826149aa565b602082019050919050565b60006020820190508181036000830152614a0f816149d3565b9050919050565b6000819050919050565b614a31614a2c8261372f565b614a16565b82525050565b60008160601b9050919050565b6000614a4f82614a37565b9050919050565b6000614a6182614a44565b9050919050565b614a79614a74826136f1565b614a56565b82525050565b6000614a8b8286614a20565b602082019150614a9b8285614a20565b602082019150614aab8284614a68565b601482019150819050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614af68261372f565b9150614b018361372f565b925082614b1157614b10614abc565b5b828206905092915050565b6000614b278261372f565b9150614b328361372f565b925082614b4257614b41614abc565b5b828204905092915050565b6000614b588261372f565b9150614b638361372f565b925082821015614b7657614b7561461d565b5b828203905092915050565b6000614b8c8261372f565b9150614b978361372f565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614bcc57614bcb61461d565b5b828201905092915050565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b6000614c336028836138c2565b9150614c3e82614bd7565b604082019050919050565b60006020820190508181036000830152614c6281614c26565b9050919050565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614cc56025836138c2565b9150614cd082614c69565b604082019050919050565b60006020820190508181036000830152614cf481614cb8565b9050919050565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b6000614d57602a836138c2565b9150614d6282614cfb565b604082019050919050565b60006020820190508181036000830152614d8681614d4a565b9050919050565b60006040820190508181036000830152614da781856139ff565b90508181036020830152614dbb81846139ff565b90509392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000614dfa601783614490565b9150614e0582614dc4565b601782019050919050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614e46601183614490565b9150614e5182614e10565b601182019050919050565b6000614e6782614ded565b9150614e73828561449b565b9150614e7e82614e39565b9150614e8a828461449b565b91508190509392505050565b6000604082019050614eab60008301856137a5565b614eb860208301846137a5565b9392505050565b614ec8816136f1565b82525050565b600081519050919050565b600082825260208201905092915050565b6000614ef582614ece565b614eff8185614ed9565b9350614f0f8185602086016138d3565b614f1881613906565b840191505092915050565b600060a082019050614f386000830188614ebf565b614f456020830187614ebf565b8181036040830152614f5781866139ff565b90508181036060830152614f6b81856139ff565b90508181036080830152614f7f8184614eea565b90509695505050505050565b600081519050614f9a816137fb565b92915050565b600060208284031215614fb657614fb56136c7565b5b6000614fc484828501614f8b565b91505092915050565b60008160e01c9050919050565b600060033d1115614ff95760046000803e614ff6600051614fcd565b90505b90565b600060443d101561500c5761508f565b6150146136bd565b60043d036004823e80513d602482011167ffffffffffffffff8211171561503c57505061508f565b808201805167ffffffffffffffff81111561505a575050505061508f565b80602083010160043d03850181111561507757505050505061508f565b61508682602001850186613b99565b82955050505050505b90565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b60006150ee6034836138c2565b91506150f982615092565b604082019050919050565b6000602082019050818103600083015261511d816150e1565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b60006151806028836138c2565b915061518b82615124565b604082019050919050565b600060208201905081810360008301526151af81615173565b9050919050565b60006151c18261372f565b91506151cc8361372f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156152055761520461461d565b5b828202905092915050565b600061521b8261372f565b9150600082141561522f5761522e61461d565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006152706020836138c2565b915061527b8261523a565b602082019050919050565b6000602082019050818103600083015261529f81615263565b9050919050565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006153026023836138c2565b915061530d826152a6565b604082019050919050565b60006020820190508181036000830152615331816152f5565b9050919050565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b60006153946024836138c2565b915061539f82615338565b604082019050919050565b600060208201905081810360008301526153c381615387565b9050919050565b600060a0820190506153df6000830188614ebf565b6153ec6020830187614ebf565b6153f960408301866137a5565b61540660608301856137a5565b81810360808301526154188184614eea565b90509695505050505050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006154806021836138c2565b915061548b82615424565b604082019050919050565b600060208201905081810360008301526154af81615473565b905091905056fea2646970667358221220759d0383336bf0d360a82ae1ae8682022386fbf57cd5638446f4a267dab2fa9964736f6c63430008090033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101fa5760003560e01c806354f5db3f1161011a578063b0ea6a84116100ad578063c6bc51821161007c578063c6bc518214610646578063d547741f14610664578063e985e9c514610680578063f242432a146106b0578063f5298aca146106cc576101fa565b8063b0ea6a84146105be578063b510391f146105dc578063bc7882d1146105f8578063bd85b03914610616576101fa565b806391d14854116100e957806391d14854146105365780639e23e98314610566578063a217fddf14610584578063a22cb465146105a2576101fa565b806354f5db3f1461049b578063570b3c6a146104cb5780636b20c454146104e7578063870e6bbf14610503576101fa565b8063248a9ca31161019257806336568abe1161016157806336568abe146103ef5780634551169d1461040b5780634e1273f41461043b5780634f558e791461046b576101fa565b8063248a9ca31461036b578063286e901d1461039b5780632eb2c2d6146103b75780632f2ff15d146103d3576101fa565b806314115c85116101ce57806314115c85146102bf57806318148f1b146102ef5780631a72b87d1461031f5780631da5e15f1461034f576101fa565b8062fdd58e146101ff57806301ffc9a71461022f5780630c29a4df1461025f5780630e89341c1461028f575b600080fd5b61021960048036038101906102149190613765565b6106e8565b60405161022691906137b4565b60405180910390f35b61024960048036038101906102449190613827565b6107b1565b604051610256919061386f565b60405180910390f35b6102796004803603810190610274919061388a565b6107c3565b60405161028691906137b4565b60405180910390f35b6102a960048036038101906102a4919061388a565b6107e3565b6040516102b69190613950565b60405180910390f35b6102d960048036038101906102d49190613972565b6108ac565b6040516102e691906137b4565b60405180910390f35b61030960048036038101906103049190613972565b6108f8565b6040516103169190613a5d565b60405180910390f35b61033960048036038101906103349190613765565b61098f565b60405161034691906137b4565b60405180910390f35b61036960048036038101906103649190613aab565b6109c0565b005b61038560048036038101906103809190613b0e565b610a30565b6040516103929190613b4a565b60405180910390f35b6103b560048036038101906103b0919061388a565b610a50565b005b6103d160048036038101906103cc9190613d62565b610aad565b005b6103ed60048036038101906103e89190613e31565b610bb6565b005b61040960048036038101906104049190613e31565b610bdf565b005b6104256004803603810190610420919061388a565b610c62565b60405161043291906137b4565b60405180910390f35b61045560048036038101906104509190613f34565b610c82565b6040516104629190613a5d565b60405180910390f35b6104856004803603810190610480919061388a565b610d9b565b604051610492919061386f565b60405180910390f35b6104b560048036038101906104b0919061388a565b610daf565b6040516104c29190613950565b60405180910390f35b6104e560048036038101906104e0919061404d565b610e57565b005b61050160048036038101906104fc9190614096565b610eb6565b005b61051d6004803603810190610518919061388a565b610f53565b60405161052d9493929190614121565b60405180910390f35b610550600480360381019061054b9190613e31565b611018565b60405161055d919061386f565b60405180910390f35b61056e611083565b60405161057b9190613950565b60405180910390f35b61058c611115565b6040516105999190613b4a565b60405180910390f35b6105bc60048036038101906105b7919061416d565b61111c565b005b6105c661129d565b6040516105d391906137b4565b60405180910390f35b6105f660048036038101906105f19190614208565b6112a3565b005b6106006113b9565b60405161060d91906137b4565b60405180910390f35b610630600480360381019061062b919061388a565b6113fb565b60405161063d91906137b4565b60405180910390f35b61064e611418565b60405161065b91906137b4565b60405180910390f35b61067e60048036038101906106799190613e31565b61141e565b005b61069a60048036038101906106959190614268565b611447565b6040516106a7919061386f565b60405180910390f35b6106ca60048036038101906106c591906142a8565b6114db565b005b6106e660048036038101906106e1919061433f565b611590565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075090614404565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006107bc82611637565b9050919050565b6000600a6000838152602001908152602001600020600301549050919050565b606060011515600a600084815260200190815260200160002060000160009054906101000a900460ff1615151461084f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084690614470565b60405180910390fd5b600560009054906101000a900460ff16156108735761086c611083565b90506108a7565b61087b611083565b610884836116b1565b6040516020016108959291906144cc565b60405160208183030381529060405290505b919050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6060600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561098357602002820191906000526020600020905b81548152602001906001019080831161096f575b50505050509050919050565b600b60205281600052604060002081815481106109ab57600080fd5b90600052602060002001600091509150505481565b6109d46000801b6109cf611812565b611018565b610a13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0a9061453c565b60405180910390fd5b80600560006101000a81548160ff02191690831515021790555050565b600060046000838152602001908152602001600020600101549050919050565b610a646000801b610a5f611812565b611018565b610aa3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9a9061453c565b60405180910390fd5b8060078190555050565b610ab5611812565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480610afb5750610afa85610af5611812565b611447565b5b610b3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b31906145ce565b60405180910390fd5b60005b8351811015610ba157610b6a86858381518110610b5d57610b5c6145ee565b5b602002602001015161181a565b610b8e85858381518110610b8157610b806145ee565b5b6020026020010151611ab0565b8080610b999061464c565b915050610b3d565b50610baf8585858585611b6d565b5050505050565b610bbf82610a30565b610bd081610bcb611812565b611e81565b610bda8383611f1e565b505050565b610be7611812565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4b90614707565b60405180910390fd5b610c5e8282611fff565b5050565b6000600a6000838152602001908152602001600020600101549050919050565b60608151835114610cc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cbf90614799565b60405180910390fd5b6000835167ffffffffffffffff811115610ce557610ce4613b6a565b5b604051908082528060200260200182016040528015610d135781602001602082028036833780820191505090505b50905060005b8451811015610d9057610d60858281518110610d3857610d376145ee565b5b6020026020010151858381518110610d5357610d526145ee565b5b60200260200101516106e8565b828281518110610d7357610d726145ee565b5b60200260200101818152505080610d899061464c565b9050610d19565b508091505092915050565b600080610da7836113fb565b119050919050565b6060600a60008381526020019081526020016000206002018054610dd2906147e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfe906147e8565b8015610e4b5780601f10610e2057610100808354040283529160200191610e4b565b820191906000526020600020905b815481529060010190602001808311610e2e57829003601f168201915b50505050509050919050565b610e6b6000801b610e66611812565b611018565b610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea19061453c565b60405180910390fd5b610eb3816120e1565b50565b610ebe611812565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480610f045750610f0383610efe611812565b611447565b5b610f43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3a9061488c565b60405180910390fd5b610f4e8383836120fb565b505050565b600a6020528060005260406000206000915090508060000160009054906101000a900460ff1690806001015490806002018054610f8f906147e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbb906147e8565b80156110085780601f10610fdd57610100808354040283529160200191611008565b820191906000526020600020905b815481529060010190602001808311610feb57829003601f168201915b5050505050908060030154905084565b60006004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060028054611092906147e8565b80601f01602080910402602001604051908101604052809291908181526020018280546110be906147e8565b801561110b5780601f106110e05761010080835404028352916020019161110b565b820191906000526020600020905b8154815290600101906020018083116110ee57829003601f168201915b5050505050905090565b6000801b81565b8173ffffffffffffffffffffffffffffffffffffffff1661113b611812565b73ffffffffffffffffffffffffffffffffffffffff161415611192576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111899061491e565b60405180910390fd5b806001600061119f611812565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661124c611812565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611291919061386f565b60405180910390a35050565b60075481565b6112b76000801b6112b2611812565b611018565b6112f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ed9061453c565b60405180910390fd5b600754600654111561133d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113349061498a565b60405180910390fd5b60001515600a6000600654815260200190815260200160002060000160009054906101000a900460ff161515146113a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a0906149f6565b60405180910390fd5b6113b4838383612187565b505050565b60006009544244336040516020016113d393929190614a7f565b6040516020818303038152906040528051906020012060001c6113f69190614aeb565b905090565b600060036000838152602001908152602001600020549050919050565b60065481565b61142782610a30565b61143881611433611812565b611e81565b6114428383611fff565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6114e3611812565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611529575061152885611523611812565b611447565b5b611568576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155f9061488c565b60405180910390fd5b611572858461181a565b61157c8484611ab0565b611589858585858561246c565b5050505050565b611598611812565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806115de57506115dd836115d8611812565b611447565b5b61161d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116149061488c565b60405180910390fd5b611627838361181a565b6116328383836126ee565b505050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806116aa57506116a982612728565b5b9050919050565b606060008214156116f9576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061180d565b600082905060005b6000821461172b5780806117149061464c565b915050600a826117249190614b1c565b9150611701565b60008167ffffffffffffffff81111561174757611746613b6a565b5b6040519080825280601f01601f1916602001820160405280156117795781602001600182028036833780820191505090505b5090505b60008514611806576001826117929190614b4d565b9150600a856117a19190614aeb565b60306117ad9190614b81565b60f81b8183815181106117c3576117c26145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856117ff9190614b1c565b945061177d565b8093505050505b919050565b600033905090565b61182e6000801b611829611812565b611018565b61186d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118649061453c565b60405180910390fd5b60006001600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490506118be9190614b4d565b67ffffffffffffffff8111156118d7576118d6613b6a565b5b6040519080825280602002602001820160405280156119055781602001602082028036833780820191505090505b5090506000805b600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050811015611a555783600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106119a8576119a76145ee565b5b906000526020600020015414611a4257600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208181548110611a0957611a086145ee565b5b9060005260206000200154838381518110611a2757611a266145ee565b5b6020026020010181815250508180611a3e9061464c565b9250505b8080611a4d9061464c565b91505061190c565b5081600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190611aa99291906135cd565b5050505050565b611ac46000801b611abf611812565b611018565b611b03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611afa9061453c565b60405180910390fd5b600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002001600090919091909150555050565b8151835114611bb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba890614c49565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1890614cdb565b60405180910390fd5b6000611c2b611812565b9050611c3b81878787878761280a565b60005b8451811015611dec576000858281518110611c5c57611c5b6145ee565b5b602002602001015190506000858381518110611c7b57611c7a6145ee565b5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614d6d565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dd19190614b81565b9250508190555050505080611de59061464c565b9050611c3e565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611e63929190614d8d565b60405180910390a4611e79818787878787612812565b505050505050565b611e8b8282611018565b611f1a57611eb08173ffffffffffffffffffffffffffffffffffffffff1660146129f9565b611ebe8360001c60206129f9565b604051602001611ecf929190614e5c565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f119190613950565b60405180910390fd5b5050565b611f288282611018565b611ffb5760016004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611fa0611812565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6120098282611018565b156120dd5760006004600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612082611812565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b80600290805190602001906120f792919061361a565b5050565b612106838383612c35565b60005b825181101561218157818181518110612125576121246145ee565b5b602002602001015160036000858481518110612144576121436145ee565b5b6020026020010151815260200190815260200160002060008282546121699190614b4d565b925050819055508061217a9061464c565b9050612109565b50505050565b60006121916113b9565b905060006040518060400160405280600681526020017f4e4f524d414c00000000000000000000000000000000000000000000000000008152509050603260065411612214576040518060400160405280600981526020017f4c4547454e4441525900000000000000000000000000000000000000000000008152509050612370565b60326006541180156122295750606460065411155b1561226b576040518060400160405280600481526020017f4550494300000000000000000000000000000000000000000000000000000000815250905061236f565b60646006541180156122805750609660065411155b156122c2576040518060400160405280600481526020017f5241524500000000000000000000000000000000000000000000000000000000815250905061236e565b60966006541180156122d7575060c860065411155b15612319576040518060400160405280600881526020017f554e434f4d4d4f4e000000000000000000000000000000000000000000000000815250905061236d565b60c860065411801561232e575060fa60065411155b1561236c576040518060400160405280600681526020017f434f4d4d4f4e000000000000000000000000000000000000000000000000000081525090505b5b5b5b5b60405180608001604052806001151581526020016001815260200182815260200183815250600a6000600654815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020190805190602001906123f092919061361a565b506060820151816003015590505061240a85600654611ab0565b61245d85600654600187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612ee6565b612465612f22565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156124dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124d390614cdb565b60405180910390fd5b60006124e6611812565b90506125068187876124f788612f3c565b61250088612f3c565b8761280a565b600080600086815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508381101561259d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259490614d6d565b60405180910390fd5b83810360008087815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508360008087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546126529190614b81565b925050819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6288886040516126cf929190614e96565b60405180910390a46126e5828888888888612fb6565b50505050505050565b6126f983838361319d565b8060036000848152602001908152602001600020600082825461271c9190614b4d565b92505081905550505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806127f357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806128035750612802826133ba565b5b9050919050565b505050505050565b6128318473ffffffffffffffffffffffffffffffffffffffff16613424565b156129f1578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b8152600401612877959493929190614f23565b602060405180830381600087803b15801561289157600080fd5b505af19250505080156128c257506040513d601f19601f820116820180604052508101906128bf9190614fa0565b60015b612968576128ce614fda565b806308c379a0141561292b57506128e3614ffc565b806128ee575061292d565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129229190613950565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295f90615104565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146129ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129e690615196565b60405180910390fd5b505b505050505050565b606060006002836002612a0c91906151b6565b612a169190614b81565b67ffffffffffffffff811115612a2f57612a2e613b6a565b5b6040519080825280601f01601f191660200182016040528015612a615781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a9957612a986145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612afd57612afc6145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612b3d91906151b6565b612b479190614b81565b90505b6001811115612be7577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612b8957612b886145ee565b5b1a60f81b828281518110612ba057612b9f6145ee565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612be090615210565b9050612b4a565b5060008414612c2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2290615286565b60405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612ca5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9c90615318565b60405180910390fd5b8051825114612ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce090614c49565b60405180910390fd5b6000612cf3611812565b9050612d138185600086866040518060200160405280600081525061280a565b60005b8351811015612e60576000848281518110612d3457612d336145ee565b5b602002602001015190506000848381518110612d5357612d526145ee565b5b60200260200101519050600080600084815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612df4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612deb906153aa565b60405180910390fd5b81810360008085815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050508080612e589061464c565b915050612d16565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612ed8929190614d8d565b60405180910390a450505050565b612ef284848484613437565b81600360008581526020019081526020016000206000828254612f159190614b81565b9250508190555050505050565b60066000815480929190612f359061464c565b9190505550565b60606000600167ffffffffffffffff811115612f5b57612f5a613b6a565b5b604051908082528060200260200182016040528015612f895781602001602082028036833780820191505090505b5090508281600081518110612fa157612fa06145ee565b5b60200260200101818152505080915050919050565b612fd58473ffffffffffffffffffffffffffffffffffffffff16613424565b15613195578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b815260040161301b9594939291906153ca565b602060405180830381600087803b15801561303557600080fd5b505af192505050801561306657506040513d601f19601f820116820180604052508101906130639190614fa0565b60015b61310c57613072614fda565b806308c379a014156130cf5750613087614ffc565b8061309257506130d1565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130c69190613950565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161310390615104565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318a90615196565b60405180910390fd5b505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561320d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320490615318565b60405180910390fd5b6000613217611812565b90506132478185600061322987612f3c565b61323287612f3c565b6040518060200160405280600081525061280a565b600080600085815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156132de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d5906153aa565b60405180910390fd5b82810360008086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6287876040516133ab929190614e96565b60405180910390a45050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600080823b905060008111915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156134a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349e90615496565b60405180910390fd5b60006134b1611812565b90506134d2816000876134c388612f3c565b6134cc88612f3c565b8761280a565b8260008086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546135319190614b81565b925050819055508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6287876040516135af929190614e96565b60405180910390a46135c681600087878787612fb6565b5050505050565b828054828255906000526020600020908101928215613609579160200282015b828111156136085782518255916020019190600101906135ed565b5b50905061361691906136a0565b5090565b828054613626906147e8565b90600052602060002090601f016020900481019282613648576000855561368f565b82601f1061366157805160ff191683800117855561368f565b8280016001018555821561368f579182015b8281111561368e578251825591602001919060010190613673565b5b50905061369c91906136a0565b5090565b5b808211156136b95760008160009055506001016136a1565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006136fc826136d1565b9050919050565b61370c816136f1565b811461371757600080fd5b50565b60008135905061372981613703565b92915050565b6000819050919050565b6137428161372f565b811461374d57600080fd5b50565b60008135905061375f81613739565b92915050565b6000806040838503121561377c5761377b6136c7565b5b600061378a8582860161371a565b925050602061379b85828601613750565b9150509250929050565b6137ae8161372f565b82525050565b60006020820190506137c960008301846137a5565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613804816137cf565b811461380f57600080fd5b50565b600081359050613821816137fb565b92915050565b60006020828403121561383d5761383c6136c7565b5b600061384b84828501613812565b91505092915050565b60008115159050919050565b61386981613854565b82525050565b60006020820190506138846000830184613860565b92915050565b6000602082840312156138a05761389f6136c7565b5b60006138ae84828501613750565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156138f15780820151818401526020810190506138d6565b83811115613900576000848401525b50505050565b6000601f19601f8301169050919050565b6000613922826138b7565b61392c81856138c2565b935061393c8185602086016138d3565b61394581613906565b840191505092915050565b6000602082019050818103600083015261396a8184613917565b905092915050565b600060208284031215613988576139876136c7565b5b60006139968482850161371a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6139d48161372f565b82525050565b60006139e683836139cb565b60208301905092915050565b6000602082019050919050565b6000613a0a8261399f565b613a1481856139aa565b9350613a1f836139bb565b8060005b83811015613a50578151613a3788826139da565b9750613a42836139f2565b925050600181019050613a23565b5085935050505092915050565b60006020820190508181036000830152613a7781846139ff565b905092915050565b613a8881613854565b8114613a9357600080fd5b50565b600081359050613aa581613a7f565b92915050565b600060208284031215613ac157613ac06136c7565b5b6000613acf84828501613a96565b91505092915050565b6000819050919050565b613aeb81613ad8565b8114613af657600080fd5b50565b600081359050613b0881613ae2565b92915050565b600060208284031215613b2457613b236136c7565b5b6000613b3284828501613af9565b91505092915050565b613b4481613ad8565b82525050565b6000602082019050613b5f6000830184613b3b565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613ba282613906565b810181811067ffffffffffffffff82111715613bc157613bc0613b6a565b5b80604052505050565b6000613bd46136bd565b9050613be08282613b99565b919050565b600067ffffffffffffffff821115613c0057613bff613b6a565b5b602082029050602081019050919050565b600080fd5b6000613c29613c2484613be5565b613bca565b90508083825260208201905060208402830185811115613c4c57613c4b613c11565b5b835b81811015613c755780613c618882613750565b845260208401935050602081019050613c4e565b5050509392505050565b600082601f830112613c9457613c93613b65565b5b8135613ca4848260208601613c16565b91505092915050565b600080fd5b600067ffffffffffffffff821115613ccd57613ccc613b6a565b5b613cd682613906565b9050602081019050919050565b82818337600083830152505050565b6000613d05613d0084613cb2565b613bca565b905082815260208101848484011115613d2157613d20613cad565b5b613d2c848285613ce3565b509392505050565b600082601f830112613d4957613d48613b65565b5b8135613d59848260208601613cf2565b91505092915050565b600080600080600060a08688031215613d7e57613d7d6136c7565b5b6000613d8c8882890161371a565b9550506020613d9d8882890161371a565b945050604086013567ffffffffffffffff811115613dbe57613dbd6136cc565b5b613dca88828901613c7f565b935050606086013567ffffffffffffffff811115613deb57613dea6136cc565b5b613df788828901613c7f565b925050608086013567ffffffffffffffff811115613e1857613e176136cc565b5b613e2488828901613d34565b9150509295509295909350565b60008060408385031215613e4857613e476136c7565b5b6000613e5685828601613af9565b9250506020613e678582860161371a565b9150509250929050565b600067ffffffffffffffff821115613e8c57613e8b613b6a565b5b602082029050602081019050919050565b6000613eb0613eab84613e71565b613bca565b90508083825260208201905060208402830185811115613ed357613ed2613c11565b5b835b81811015613efc5780613ee8888261371a565b845260208401935050602081019050613ed5565b5050509392505050565b600082601f830112613f1b57613f1a613b65565b5b8135613f2b848260208601613e9d565b91505092915050565b60008060408385031215613f4b57613f4a6136c7565b5b600083013567ffffffffffffffff811115613f6957613f686136cc565b5b613f7585828601613f06565b925050602083013567ffffffffffffffff811115613f9657613f956136cc565b5b613fa285828601613c7f565b9150509250929050565b600067ffffffffffffffff821115613fc757613fc6613b6a565b5b613fd082613906565b9050602081019050919050565b6000613ff0613feb84613fac565b613bca565b90508281526020810184848401111561400c5761400b613cad565b5b614017848285613ce3565b509392505050565b600082601f83011261403457614033613b65565b5b8135614044848260208601613fdd565b91505092915050565b600060208284031215614063576140626136c7565b5b600082013567ffffffffffffffff811115614081576140806136cc565b5b61408d8482850161401f565b91505092915050565b6000806000606084860312156140af576140ae6136c7565b5b60006140bd8682870161371a565b935050602084013567ffffffffffffffff8111156140de576140dd6136cc565b5b6140ea86828701613c7f565b925050604084013567ffffffffffffffff81111561410b5761410a6136cc565b5b61411786828701613c7f565b9150509250925092565b60006080820190506141366000830187613860565b61414360208301866137a5565b81810360408301526141558185613917565b905061416460608301846137a5565b95945050505050565b60008060408385031215614184576141836136c7565b5b60006141928582860161371a565b92505060206141a385828601613a96565b9150509250929050565b600080fd5b60008083601f8401126141c8576141c7613b65565b5b8235905067ffffffffffffffff8111156141e5576141e46141ad565b5b60208301915083600182028301111561420157614200613c11565b5b9250929050565b600080600060408486031215614221576142206136c7565b5b600061422f8682870161371a565b935050602084013567ffffffffffffffff8111156142505761424f6136cc565b5b61425c868287016141b2565b92509250509250925092565b6000806040838503121561427f5761427e6136c7565b5b600061428d8582860161371a565b925050602061429e8582860161371a565b9150509250929050565b600080600080600060a086880312156142c4576142c36136c7565b5b60006142d28882890161371a565b95505060206142e38882890161371a565b94505060406142f488828901613750565b935050606061430588828901613750565b925050608086013567ffffffffffffffff811115614326576143256136cc565b5b61433288828901613d34565b9150509295509295909350565b600080600060608486031215614358576143576136c7565b5b60006143668682870161371a565b935050602061437786828701613750565b925050604061438886828701613750565b9150509250925092565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b60006143ee602b836138c2565b91506143f982614392565b604082019050919050565b6000602082019050818103600083015261441d816143e1565b9050919050565b7f4e465420646f6573206e6f742065786973740000000000000000000000000000600082015250565b600061445a6012836138c2565b915061446582614424565b602082019050919050565b600060208201905081810360008301526144898161444d565b9050919050565b600081905092915050565b60006144a6826138b7565b6144b08185614490565b93506144c08185602086016138d3565b80840191505092915050565b60006144d8828561449b565b91506144e4828461449b565b91508190509392505050565b7f4163636f756e74206973206e6f7420696e207468652061646d696e206c697374600082015250565b60006145266020836138c2565b9150614531826144f0565b602082019050919050565b6000602082019050818103600083015261455581614519565b9050919050565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b60006145b86032836138c2565b91506145c38261455c565b604082019050919050565b600060208201905081810360008301526145e7816145ab565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006146578261372f565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561468a5761468961461d565b5b600182019050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b60006146f1602f836138c2565b91506146fc82614695565b604082019050919050565b60006020820190508181036000830152614720816146e4565b9050919050565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b60006147836029836138c2565b915061478e82614727565b604082019050919050565b600060208201905081810360008301526147b281614776565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061480057607f821691505b60208210811415614814576148136147b9565b5b50919050565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b60006148766029836138c2565b91506148818261481a565b604082019050919050565b600060208201905081810360008301526148a581614869565b9050919050565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b60006149086029836138c2565b9150614913826148ac565b604082019050919050565b60006020820190508181036000830152614937816148fb565b9050919050565b7f4e4654206e6f206c6f6e676572206d696e7461626c6500000000000000000000600082015250565b60006149746016836138c2565b915061497f8261493e565b602082019050919050565b600060208201905081810360008301526149a381614967565b9050919050565b7f4e465420616c7265616479206578697374730000000000000000000000000000600082015250565b60006149e06012836138c2565b91506149eb826149aa565b602082019050919050565b60006020820190508181036000830152614a0f816149d3565b9050919050565b6000819050919050565b614a31614a2c8261372f565b614a16565b82525050565b60008160601b9050919050565b6000614a4f82614a37565b9050919050565b6000614a6182614a44565b9050919050565b614a79614a74826136f1565b614a56565b82525050565b6000614a8b8286614a20565b602082019150614a9b8285614a20565b602082019150614aab8284614a68565b601482019150819050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614af68261372f565b9150614b018361372f565b925082614b1157614b10614abc565b5b828206905092915050565b6000614b278261372f565b9150614b328361372f565b925082614b4257614b41614abc565b5b828204905092915050565b6000614b588261372f565b9150614b638361372f565b925082821015614b7657614b7561461d565b5b828203905092915050565b6000614b8c8261372f565b9150614b978361372f565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614bcc57614bcb61461d565b5b828201905092915050565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b6000614c336028836138c2565b9150614c3e82614bd7565b604082019050919050565b60006020820190508181036000830152614c6281614c26565b9050919050565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614cc56025836138c2565b9150614cd082614c69565b604082019050919050565b60006020820190508181036000830152614cf481614cb8565b9050919050565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b6000614d57602a836138c2565b9150614d6282614cfb565b604082019050919050565b60006020820190508181036000830152614d8681614d4a565b9050919050565b60006040820190508181036000830152614da781856139ff565b90508181036020830152614dbb81846139ff565b90509392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000614dfa601783614490565b9150614e0582614dc4565b601782019050919050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614e46601183614490565b9150614e5182614e10565b601182019050919050565b6000614e6782614ded565b9150614e73828561449b565b9150614e7e82614e39565b9150614e8a828461449b565b91508190509392505050565b6000604082019050614eab60008301856137a5565b614eb860208301846137a5565b9392505050565b614ec8816136f1565b82525050565b600081519050919050565b600082825260208201905092915050565b6000614ef582614ece565b614eff8185614ed9565b9350614f0f8185602086016138d3565b614f1881613906565b840191505092915050565b600060a082019050614f386000830188614ebf565b614f456020830187614ebf565b8181036040830152614f5781866139ff565b90508181036060830152614f6b81856139ff565b90508181036080830152614f7f8184614eea565b90509695505050505050565b600081519050614f9a816137fb565b92915050565b600060208284031215614fb657614fb56136c7565b5b6000614fc484828501614f8b565b91505092915050565b60008160e01c9050919050565b600060033d1115614ff95760046000803e614ff6600051614fcd565b90505b90565b600060443d101561500c5761508f565b6150146136bd565b60043d036004823e80513d602482011167ffffffffffffffff8211171561503c57505061508f565b808201805167ffffffffffffffff81111561505a575050505061508f565b80602083010160043d03850181111561507757505050505061508f565b61508682602001850186613b99565b82955050505050505b90565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b60006150ee6034836138c2565b91506150f982615092565b604082019050919050565b6000602082019050818103600083015261511d816150e1565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b60006151806028836138c2565b915061518b82615124565b604082019050919050565b600060208201905081810360008301526151af81615173565b9050919050565b60006151c18261372f565b91506151cc8361372f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156152055761520461461d565b5b828202905092915050565b600061521b8261372f565b9150600082141561522f5761522e61461d565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006152706020836138c2565b915061527b8261523a565b602082019050919050565b6000602082019050818103600083015261529f81615263565b9050919050565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006153026023836138c2565b915061530d826152a6565b604082019050919050565b60006020820190508181036000830152615331816152f5565b9050919050565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b60006153946024836138c2565b915061539f82615338565b604082019050919050565b600060208201905081810360008301526153c381615387565b9050919050565b600060a0820190506153df6000830188614ebf565b6153ec6020830187614ebf565b6153f960408301866137a5565b61540660608301856137a5565b81810360808301526154188184614eea565b90509695505050505050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006154806021836138c2565b915061548b82615424565b604082019050919050565b600060208201905081810360008301526154af81615473565b905091905056fea2646970667358221220759d0383336bf0d360a82ae1ae8682022386fbf57cd5638446f4a267dab2fa9964736f6c63430008090033

Deployed Bytecode Sourcemap

52008:8316:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36892:231;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52874:179;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54208:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54819:368;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53793:143;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54017:135;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52644:46;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53153:100;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24823:123;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53460:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58591:826;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25208:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;26256:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55265:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37289:504;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49919:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55475:145;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53306:92;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51648:353;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52479:58;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;23736:139;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36126:99;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21570:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37866:311;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52157:39;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57214:278;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55700:367;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49708:113;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52126:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25600:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38249:168;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57907:607;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57500:336;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36892:231;36978:7;37025:1;37006:21;;:7;:21;;;;36998:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;37093:9;:13;37103:2;37093:13;;;;;;;;;;;:22;37107:7;37093:22;;;;;;;;;;;;;;;;37086:29;;36892:231;;;;:::o;52874:179::-;52984:4;53008:37;53032:12;53008:23;:37::i;:::-;53001:44;;52874:179;;;:::o;54208:124::-;54268:12;54300;:20;54313:6;54300:20;;;;;;;;;;;:24;;;54293:31;;54208:124;;;:::o;54819:368::-;54883:13;54950:4;54917:37;;:12;:17;54930:3;54917:17;;;;;;;;;;;:29;;;;;;;;;;;;:37;;;54909:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;54994:16;;;;;;;;;;;54990:106;;;55034:15;:13;:15::i;:::-;55027:22;;;;54990:106;55139:15;:13;:15::i;:::-;55156:21;55173:3;55156:16;:21::i;:::-;55122:56;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55108:71;;54819:368;;;;:::o;53793:143::-;53859:23;53902:9;:19;53912:8;53902:19;;;;;;;;;;;;;;;:26;;;;53895:33;;53793:143;;;:::o;54017:135::-;54078:27;54125:9;:19;54135:8;54125:19;;;;;;;;;;;;;;;54118:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54017:135;;;:::o;52644:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;53153:100::-;23270:41;21615:4;23278:18;;23298:12;:10;:12::i;:::-;23270:7;:41::i;:::-;23262:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;53241:4:::1;53222:16;;:23;;;;;;;;;;;;;;;;;;53153:100:::0;:::o;24823:123::-;24889:7;24916:6;:12;24923:4;24916:12;;;;;;;;;;;:22;;;24909:29;;24823:123;;;:::o;53460:127::-;23270:41;21615:4;23278:18;;23298:12;:10;:12::i;:::-;23270:7;:41::i;:::-;23262:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;53561:18:::1;53544:14;:35;;;;53460:127:::0;:::o;58591:826::-;58832:12;:10;:12::i;:::-;58824:20;;:4;:20;;;:60;;;;58848:36;58865:4;58871:12;:10;:12::i;:::-;58848:16;:36::i;:::-;58824:60;58802:160;;;;;;;;;;;;:::i;:::-;;;;;;;;;59071:9;59066:279;59090:3;:10;59086:1;:14;59066:279;;;59187:37;59211:4;59217:3;59221:1;59217:6;;;;;;;;:::i;:::-;;;;;;;;59187:23;:37::i;:::-;59303:30;59322:2;59326:3;59330:1;59326:6;;;;;;;;:::i;:::-;;;;;;;;59303:18;:30::i;:::-;59102:3;;;;;:::i;:::-;;;;59066:279;;;;59357:52;59380:4;59386:2;59390:3;59395:7;59404:4;59357:22;:52::i;:::-;58591:826;;;;;:::o;25208:147::-;25291:18;25304:4;25291:12;:18::i;:::-;23174:30;23185:4;23191:12;:10;:12::i;:::-;23174:10;:30::i;:::-;25322:25:::1;25333:4;25339:7;25322:10;:25::i;:::-;25208:147:::0;;;:::o;26256:218::-;26363:12;:10;:12::i;:::-;26352:23;;:7;:23;;;26344:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;26440:26;26452:4;26458:7;26440:11;:26::i;:::-;26256:218;;:::o;55265:127::-;55326:13;55359:12;:20;55372:6;55359:20;;;;;;;;;;;:25;;;55352:32;;55265:127;;;:::o;37289:504::-;37425:16;37486:3;:10;37467:8;:15;:29;37459:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;37555:30;37602:8;:15;37588:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37555:63;;37636:9;37631:122;37655:8;:15;37651:1;:19;37631:122;;;37711:30;37721:8;37730:1;37721:11;;;;;;;;:::i;:::-;;;;;;;;37734:3;37738:1;37734:6;;;;;;;;:::i;:::-;;;;;;;;37711:9;:30::i;:::-;37692:13;37706:1;37692:16;;;;;;;;:::i;:::-;;;;;;;:49;;;;;37672:3;;;;:::i;:::-;;;37631:122;;;;37772:13;37765:20;;;37289:504;;;;:::o;49919:122::-;49976:4;50032:1;50000:29;50026:2;50000:25;:29::i;:::-;:33;49993:40;;49919:122;;;:::o;55475:145::-;55540:23;55583:12;:20;55596:6;55583:20;;;;;;;;;;;:29;;55576:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55475:145;;;:::o;53306:92::-;23270:41;21615:4;23278:18;;23298:12;:10;:12::i;:::-;23270:7;:41::i;:::-;23262:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;53374:16:::1;53382:7;53374;:16::i;:::-;53306:92:::0;:::o;51648:353::-;51824:12;:10;:12::i;:::-;51813:23;;:7;:23;;;:66;;;;51840:39;51857:7;51866:12;:10;:12::i;:::-;51840:16;:39::i;:::-;51813:66;51791:157;;;;;;;;;;;;:::i;:::-;;;;;;;;;51961:32;51972:7;51981:3;51986:6;51961:10;:32::i;:::-;51648:353;;;:::o;52479:58::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;23736:139::-;23814:4;23838:6;:12;23845:4;23838:12;;;;;;;;;;;:20;;:29;23859:7;23838:29;;;;;;;;;;;;;;;;;;;;;;;;;23831:36;;23736:139;;;;:::o;36126:99::-;36180:13;36213:4;36206:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36126:99;:::o;21570:49::-;21615:4;21570:49;;;:::o;37866:311::-;37985:8;37969:24;;:12;:10;:12::i;:::-;:24;;;;37961:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;38097:8;38052:18;:32;38071:12;:10;:12::i;:::-;38052:32;;;;;;;;;;;;;;;:42;38085:8;38052:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;38150:8;38121:48;;38136:12;:10;:12::i;:::-;38121:48;;;38160:8;38121:48;;;;;;:::i;:::-;;;;;;;;37866:311;;:::o;52157:39::-;;;;:::o;57214:278::-;23270:41;21615:4;23278:18;;23298:12;:10;:12::i;:::-;23270:7;:41::i;:::-;23262:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;57312:14:::1;;57303:5;;:23;;57295:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;57407:5;57372:40;;:12;:19;57385:5;;57372:19;;;;;;;;;;;:31;;;;;;;;;;;;:40;;;57364:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;57448:36;57467:9;57478:5;;57448:18;:36::i;:::-;57214:278:::0;;;:::o;55700:367::-;55748:7;56049:10;;55894:15;55936:16;55979:10;55851:161;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55819:212;;;;;;55793:253;;:266;;;;:::i;:::-;55773:286;;55700:367;:::o;49708:113::-;49770:7;49797:12;:16;49810:2;49797:16;;;;;;;;;;;;49790:23;;49708:113;;;:::o;52126:24::-;;;;:::o;25600:149::-;25684:18;25697:4;25684:12;:18::i;:::-;23174:30;23185:4;23191:12;:10;:12::i;:::-;23174:10;:30::i;:::-;25715:26:::1;25727:4;25733:7;25715:11;:26::i;:::-;25600:149:::0;;;:::o;38249:168::-;38348:4;38372:18;:27;38391:7;38372:27;;;;;;;;;;;;;;;:37;38400:8;38372:37;;;;;;;;;;;;;;;;;;;;;;;;;38365:44;;38249:168;;;;:::o;57907:607::-;58123:12;:10;:12::i;:::-;58115:20;;:4;:20;;;:60;;;;58139:36;58156:4;58162:12;:10;:12::i;:::-;58139:16;:36::i;:::-;58115:60;58093:151;;;;;;;;;;;;:::i;:::-;;;;;;;;;58318:33;58342:4;58348:2;58318:23;:33::i;:::-;58422:26;58441:2;58445;58422:18;:26::i;:::-;58461:45;58479:4;58485:2;58489;58493:6;58501:4;58461:17;:45::i;:::-;57907:607;;;;;:::o;57500:336::-;57617:12;:10;:12::i;:::-;57606:23;;:7;:23;;;:66;;;;57633:39;57650:7;57659:12;:10;:12::i;:::-;57633:16;:39::i;:::-;57606:66;57584:157;;;;;;;;;;;;:::i;:::-;;;;;;;;;57754:36;57778:7;57787:2;57754:23;:36::i;:::-;57803:25;57809:7;57818:2;57822:5;57803;:25::i;:::-;57500:336;;;:::o;23440:204::-;23525:4;23564:32;23549:47;;;:11;:47;;;;:87;;;;23600:36;23624:11;23600:23;:36::i;:::-;23549:87;23542:94;;23440:204;;;:::o;9508:723::-;9564:13;9794:1;9785:5;:10;9781:53;;;9812:10;;;;;;;;;;;;;;;;;;;;;9781:53;9844:12;9859:5;9844:20;;9875:14;9900:78;9915:1;9907:4;:9;9900:78;;9933:8;;;;;:::i;:::-;;;;9964:2;9956:10;;;;;:::i;:::-;;;9900:78;;;9988:19;10020:6;10010:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9988:39;;10038:154;10054:1;10045:5;:10;10038:154;;10082:1;10072:11;;;;;:::i;:::-;;;10149:2;10141:5;:10;;;;:::i;:::-;10128:2;:24;;;;:::i;:::-;10115:39;;10098:6;10105;10098:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;10178:2;10169:11;;;;;:::i;:::-;;;10038:154;;;10216:6;10202:21;;;;;9508:723;;;;:::o;602:98::-;655:7;682:10;675:17;;602:98;:::o;56350:672::-;23270:41;21615:4;23278:18;;23298:12;:10;:12::i;:::-;23270:7;:41::i;:::-;23262:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;56584:27:::1;56658:1;56628:9;:20;56638:9;56628:20;;;;;;;;;;;;;;;:27;;;;:31;;;;:::i;:::-;56614:46;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56584:76;;56673:9;56702::::0;56697:219:::1;56721:9;:20;56731:9;56721:20;;;;;;;;;;;;;;;:27;;;;56717:1;:31;56697:219;;;56801:6;56774:9;:20;56784:9;56774:20;;;;;;;;;;;;;;;56795:1;56774:23;;;;;;;;:::i;:::-;;;;;;;;;;:33;56770:135;;56844:9;:20;56854:9;56844:20;;;;;;;;;;;;;;;56865:1;56844:23;;;;;;;;:::i;:::-;;;;;;;;;;56828:10;56839:1;56828:13;;;;;;;;:::i;:::-;;;;;;;:39;;;::::0;::::1;56886:3;;;;;:::i;:::-;;;;56770:135;56750:3;;;;;:::i;:::-;;;;56697:219;;;;57004:10;56981:9;:20;56991:9;56981:20;;;;;;;;;;;;;;;:33;;;;;;;;;;;;:::i;:::-;;56435:587;;56350:672:::0;;:::o;56140:132::-;23270:41;21615:4;23278:18;;23298:12;:10;:12::i;:::-;23270:7;:41::i;:::-;23262:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;56231:9:::1;:20;56241:9;56231:20;;;;;;;;;;;;;;;56257:6;56231:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56140:132:::0;;:::o;40059:1074::-;40286:7;:14;40272:3;:10;:28;40264:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;40378:1;40364:16;;:2;:16;;;;40356:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;40435:16;40454:12;:10;:12::i;:::-;40435:31;;40479:60;40500:8;40510:4;40516:2;40520:3;40525:7;40534:4;40479:20;:60::i;:::-;40557:9;40552:421;40576:3;:10;40572:1;:14;40552:421;;;40608:10;40621:3;40625:1;40621:6;;;;;;;;:::i;:::-;;;;;;;;40608:19;;40642:14;40659:7;40667:1;40659:10;;;;;;;;:::i;:::-;;;;;;;;40642:27;;40686:19;40708:9;:13;40718:2;40708:13;;;;;;;;;;;:19;40722:4;40708:19;;;;;;;;;;;;;;;;40686:41;;40765:6;40750:11;:21;;40742:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;40898:6;40884:11;:20;40862:9;:13;40872:2;40862:13;;;;;;;;;;;:19;40876:4;40862:19;;;;;;;;;;;;;;;:42;;;;40955:6;40934:9;:13;40944:2;40934:13;;;;;;;;;;;:17;40948:2;40934:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;40593:380;;;40588:3;;;;:::i;:::-;;;40552:421;;;;41020:2;40990:47;;41014:4;40990:47;;41004:8;40990:47;;;41024:3;41029:7;40990:47;;;;;;;:::i;:::-;;;;;;;;41050:75;41086:8;41096:4;41102:2;41106:3;41111:7;41120:4;41050:35;:75::i;:::-;40253:880;40059:1074;;;;;:::o;24165:469::-;24246:22;24254:4;24260:7;24246;:22::i;:::-;24241:386;;24422:41;24450:7;24422:41;;24460:2;24422:19;:41::i;:::-;24528:38;24556:4;24548:13;;24563:2;24528:19;:38::i;:::-;24335:250;;;;;;;;;:::i;:::-;;;;;;;;;;;;;24285:330;;;;;;;;;;;:::i;:::-;;;;;;;;24241:386;24165:469;;:::o;27560:229::-;27635:22;27643:4;27649:7;27635;:22::i;:::-;27630:152;;27706:4;27674:6;:12;27681:4;27674:12;;;;;;;;;;;:20;;:29;27695:7;27674:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;27757:12;:10;:12::i;:::-;27730:40;;27748:7;27730:40;;27742:4;27730:40;;;;;;;;;;27630:152;27560:229;;:::o;27797:230::-;27872:22;27880:4;27886:7;27872;:22::i;:::-;27868:152;;;27943:5;27911:6;:12;27918:4;27911:12;;;;;;;;;;;:20;;:29;27932:7;27911:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;27995:12;:10;:12::i;:::-;27968:40;;27986:7;27968:40;;27980:4;27968:40;;;;;;;;;;27868:152;27797:230;;:::o;41977:88::-;42051:6;42044:4;:13;;;;;;;;;;;;:::i;:::-;;41977:88;:::o;51080:315::-;51236:39;51253:7;51262:3;51267:7;51236:16;:39::i;:::-;51291:9;51286:102;51310:3;:10;51306:1;:14;51286:102;;;51366:7;51374:1;51366:10;;;;;;;;:::i;:::-;;;;;;;;51342:12;:20;51355:3;51359:1;51355:6;;;;;;;;:::i;:::-;;;;;;;;51342:20;;;;;;;;;;;;:34;;;;;;;:::i;:::-;;;;;;;;51322:3;;;;:::i;:::-;;;51286:102;;;;51080:315;;;:::o;59472:849::-;59560:12;59575:17;:15;:17::i;:::-;59560:32;;59605:23;:34;;;;;;;;;;;;;;;;;;;59665:2;59656:5;;:11;59652:408;;59684:23;;;;;;;;;;;;;;;;;;;59652:408;;;59737:2;59729:5;;:10;:26;;;;;59752:3;59743:5;;:12;;59729:26;59725:335;;;59772:18;;;;;;;;;;;;;;;;;;;59725:335;;;59820:3;59812:5;;:11;:27;;;;;59836:3;59827:5;;:12;;59812:27;59808:252;;;59856:18;;;;;;;;;;;;;;;;;;;59808:252;;;59904:3;59896:5;;:11;:27;;;;;59920:3;59911:5;;:12;;59896:27;59892:168;;;59940:22;;;;;;;;;;;;;;;;;;;59892:168;;;59992:3;59984:5;;:11;:27;;;;;60008:3;59999:5;;:12;;59984:27;59980:80;;;60028:20;;;;;;;;;;;;;;;;;;;59980:80;59892:168;59808:252;59725:335;59652:408;60094:44;;;;;;;;60113:4;60094:44;;;;;;60119:1;60094:44;;;;60122:9;60094:44;;;;60133:4;60094:44;;;60072:12;:19;60085:5;;60072:19;;;;;;;;;;;:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60201:36;60220:9;60231:5;;60201:18;:36::i;:::-;60250:33;60256:9;60267:5;;60274:1;60277:5;;60250:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:5;:33::i;:::-;60296:17;:15;:17::i;:::-;59549:772;;59472:849;;;:::o;38881:820::-;39083:1;39069:16;;:2;:16;;;;39061:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;39140:16;39159:12;:10;:12::i;:::-;39140:31;;39184:96;39205:8;39215:4;39221:2;39225:21;39243:2;39225:17;:21::i;:::-;39248:25;39266:6;39248:17;:25::i;:::-;39275:4;39184:20;:96::i;:::-;39293:19;39315:9;:13;39325:2;39315:13;;;;;;;;;;;:19;39329:4;39315:19;;;;;;;;;;;;;;;;39293:41;;39368:6;39353:11;:21;;39345:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;39493:6;39479:11;:20;39457:9;:13;39467:2;39457:13;;;;;;;;;;;:19;39471:4;39457:19;;;;;;;;;;;;;;;:42;;;;39542:6;39521:9;:13;39531:2;39521:13;;;;;;;;;;;:17;39535:2;39521:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;39597:2;39566:46;;39591:4;39566:46;;39581:8;39566:46;;;39601:2;39605:6;39566:46;;;;;;;:::i;:::-;;;;;;;;39625:68;39656:8;39666:4;39672:2;39676;39680:6;39688:4;39625:30;:68::i;:::-;39050:651;;38881:820;;;;;:::o;50807:208::-;50938:32;50950:7;50959:2;50963:6;50938:11;:32::i;:::-;51001:6;50981:12;:16;50994:2;50981:16;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;50807:208;;;:::o;35808:310::-;35910:4;35962:26;35947:41;;;:11;:41;;;;:110;;;;36020:37;36005:52;;;:11;:52;;;;35947:110;:163;;;;36074:36;36098:11;36074:23;:36::i;:::-;35947:163;35927:183;;35808:310;;;:::o;47167:221::-;;;;;;;:::o;48148:813::-;48388:15;:2;:13;;;:15::i;:::-;48384:570;;;48441:2;48424:43;;;48468:8;48478:4;48484:3;48489:7;48498:4;48424:79;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;48420:523;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;48816:6;48809:14;;;;;;;;;;;:::i;:::-;;;;;;;;48420:523;;;48865:62;;;;;;;;;;:::i;:::-;;;;;;;;48420:523;48597:48;;;48585:60;;;:8;:60;;;;48581:159;;48670:50;;;;;;;;;;:::i;:::-;;;;;;;;48581:159;48504:251;48384:570;48148:813;;;;;;:::o;10809:451::-;10884:13;10910:19;10955:1;10946:6;10942:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;10932:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10910:47;;10968:15;:6;10975:1;10968:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;10994;:6;11001:1;10994:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;11025:9;11050:1;11041:6;11037:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;11025:26;;11020:135;11057:1;11053;:5;11020:135;;;11092:12;11113:3;11105:5;:11;11092:25;;;;;;;:::i;:::-;;;;;11080:6;11087:1;11080:9;;;;;;;;:::i;:::-;;;;;:37;;;;;;;;;;;11142:1;11132:11;;;;;11060:3;;;;:::i;:::-;;;11020:135;;;;11182:1;11173:5;:10;11165:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;11245:6;11231:21;;;10809:451;;;;:::o;45293:918::-;45467:1;45448:21;;:7;:21;;;;45440:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;45542:7;:14;45528:3;:10;:28;45520:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;45614:16;45633:12;:10;:12::i;:::-;45614:31;;45658:69;45679:8;45689:7;45706:1;45710:3;45715:7;45658:69;;;;;;;;;;;;:20;:69::i;:::-;45745:9;45740:388;45764:3;:10;45760:1;:14;45740:388;;;45796:10;45809:3;45813:1;45809:6;;;;;;;;:::i;:::-;;;;;;;;45796:19;;45830:14;45847:7;45855:1;45847:10;;;;;;;;:::i;:::-;;;;;;;;45830:27;;45874:22;45899:9;:13;45909:2;45899:13;;;;;;;;;;;:22;45913:7;45899:22;;;;;;;;;;;;;;;;45874:47;;45962:6;45944:14;:24;;45936:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;46095:6;46078:14;:23;46053:9;:13;46063:2;46053:13;;;;;;;;;;;:22;46067:7;46053:22;;;;;;;;;;;;;;;:48;;;;45781:347;;;45776:3;;;;;:::i;:::-;;;;45740:388;;;;46186:1;46145:58;;46169:7;46145:58;;46159:8;46145:58;;;46190:3;46195:7;46145:58;;;;;;;:::i;:::-;;;;;;;;45429:782;45293:918;;;:::o;50101:242::-;50260:38;50272:7;50281:2;50285:6;50293:4;50260:11;:38::i;:::-;50329:6;50309:12;:16;50322:2;50309:16;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;50101:242;;;;:::o;53654:61::-;53700:5;;:7;;;;;;;;;:::i;:::-;;;;;;53654:61::o;48969:198::-;49035:16;49064:22;49103:1;49089:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49064:41;;49127:7;49116:5;49122:1;49116:8;;;;;;;;:::i;:::-;;;;;;;:18;;;;;49154:5;49147:12;;;48969:198;;;:::o;47396:744::-;47611:15;:2;:13;;;:15::i;:::-;47607:526;;;47664:2;47647:38;;;47686:8;47696:4;47702:2;47706:6;47714:4;47647:72;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;47643:479;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;47995:6;47988:14;;;;;;;;;;;:::i;:::-;;;;;;;;47643:479;;;48044:62;;;;;;;;;;:::i;:::-;;;;;;;;47643:479;47781:43;;;47769:55;;;:8;:55;;;;47765:154;;47849:50;;;;;;;;;;:::i;:::-;;;;;;;;47765:154;47720:214;47607:526;47396:744;;;;;;:::o;44415:675::-;44564:1;44545:21;;:7;:21;;;;44537:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;44619:16;44638:12;:10;:12::i;:::-;44619:31;;44663:105;44684:8;44694:7;44711:1;44715:21;44733:2;44715:17;:21::i;:::-;44738:25;44756:6;44738:17;:25::i;:::-;44663:105;;;;;;;;;;;;:20;:105::i;:::-;44781:22;44806:9;:13;44816:2;44806:13;;;;;;;;;;;:22;44820:7;44806:22;;;;;;;;;;;;;;;;44781:47;;44865:6;44847:14;:24;;44839:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;44990:6;44973:14;:23;44948:9;:13;44958:2;44948:13;;;;;;;;;;;:22;44962:7;44948:22;;;;;;;;;;;;;;;:48;;;;45067:1;45025:57;;45050:7;45025:57;;45040:8;45025:57;;;45071:2;45075:6;45025:57;;;;;;;:::i;:::-;;;;;;;;44526:564;;44415:675;;;:::o;9118:157::-;9203:4;9242:25;9227:40;;;:11;:40;;;;9220:47;;9118:157;;;:::o;11948:387::-;12008:4;12216:12;12283:7;12271:20;12263:28;;12326:1;12319:4;:8;12312:15;;;11948:387;;;:::o;42466:599::-;42643:1;42624:21;;:7;:21;;;;42616:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;42696:16;42715:12;:10;:12::i;:::-;42696:31;;42740:107;42761:8;42779:1;42783:7;42792:21;42810:2;42792:17;:21::i;:::-;42815:25;42833:6;42815:17;:25::i;:::-;42842:4;42740:20;:107::i;:::-;42886:6;42860:9;:13;42870:2;42860:13;;;;;;;;;;;:22;42874:7;42860:22;;;;;;;;;;;;;;;;:32;;;;;;;:::i;:::-;;;;;;;;42945:7;42908:57;;42941:1;42908:57;;42923:8;42908:57;;;42954:2;42958:6;42908:57;;;;;;;:::i;:::-;;;;;;;;42978:79;43009:8;43027:1;43031:7;43040:2;43044:6;43052:4;42978:30;:79::i;:::-;42605:460;42466:599;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::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:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:77::-;878:7;907:5;896:16;;841:77;;;:::o;924:122::-;997:24;1015:5;997:24;:::i;:::-;990:5;987:35;977:63;;1036:1;1033;1026:12;977:63;924:122;:::o;1052:139::-;1098:5;1136:6;1123:20;1114:29;;1152:33;1179:5;1152:33;:::i;:::-;1052:139;;;;:::o;1197:474::-;1265:6;1273;1322:2;1310:9;1301:7;1297:23;1293:32;1290:119;;;1328:79;;:::i;:::-;1290:119;1448:1;1473:53;1518:7;1509:6;1498:9;1494:22;1473:53;:::i;:::-;1463:63;;1419:117;1575:2;1601:53;1646:7;1637:6;1626:9;1622:22;1601:53;:::i;:::-;1591:63;;1546:118;1197:474;;;;;:::o;1677:118::-;1764:24;1782:5;1764:24;:::i;:::-;1759:3;1752:37;1677:118;;:::o;1801:222::-;1894:4;1932:2;1921:9;1917:18;1909:26;;1945:71;2013:1;2002:9;1998:17;1989:6;1945:71;:::i;:::-;1801:222;;;;:::o;2029:149::-;2065:7;2105:66;2098:5;2094:78;2083:89;;2029:149;;;:::o;2184:120::-;2256:23;2273:5;2256:23;:::i;:::-;2249:5;2246:34;2236:62;;2294:1;2291;2284:12;2236:62;2184:120;:::o;2310:137::-;2355:5;2393:6;2380:20;2371:29;;2409:32;2435:5;2409:32;:::i;:::-;2310:137;;;;:::o;2453:327::-;2511:6;2560:2;2548:9;2539:7;2535:23;2531:32;2528:119;;;2566:79;;:::i;:::-;2528:119;2686:1;2711:52;2755:7;2746:6;2735:9;2731:22;2711:52;:::i;:::-;2701:62;;2657:116;2453:327;;;;:::o;2786:90::-;2820:7;2863:5;2856:13;2849:21;2838:32;;2786:90;;;:::o;2882:109::-;2963:21;2978:5;2963:21;:::i;:::-;2958:3;2951:34;2882:109;;:::o;2997:210::-;3084:4;3122:2;3111:9;3107:18;3099:26;;3135:65;3197:1;3186:9;3182:17;3173:6;3135:65;:::i;:::-;2997:210;;;;:::o;3213:329::-;3272:6;3321:2;3309:9;3300:7;3296:23;3292:32;3289:119;;;3327:79;;:::i;:::-;3289:119;3447:1;3472:53;3517:7;3508:6;3497:9;3493:22;3472:53;:::i;:::-;3462:63;;3418:117;3213:329;;;;:::o;3548:99::-;3600:6;3634:5;3628:12;3618:22;;3548:99;;;:::o;3653:169::-;3737:11;3771:6;3766:3;3759:19;3811:4;3806:3;3802:14;3787:29;;3653:169;;;;:::o;3828:307::-;3896:1;3906:113;3920:6;3917:1;3914:13;3906:113;;;4005:1;4000:3;3996:11;3990:18;3986:1;3981:3;3977:11;3970:39;3942:2;3939:1;3935:10;3930:15;;3906:113;;;4037:6;4034:1;4031:13;4028:101;;;4117:1;4108:6;4103:3;4099:16;4092:27;4028:101;3877:258;3828:307;;;:::o;4141:102::-;4182:6;4233:2;4229:7;4224:2;4217:5;4213:14;4209:28;4199:38;;4141:102;;;:::o;4249:364::-;4337:3;4365:39;4398:5;4365:39;:::i;:::-;4420:71;4484:6;4479:3;4420:71;:::i;:::-;4413:78;;4500:52;4545:6;4540:3;4533:4;4526:5;4522:16;4500:52;:::i;:::-;4577:29;4599:6;4577:29;:::i;:::-;4572:3;4568:39;4561:46;;4341:272;4249:364;;;;:::o;4619:313::-;4732:4;4770:2;4759:9;4755:18;4747:26;;4819:9;4813:4;4809:20;4805:1;4794:9;4790:17;4783:47;4847:78;4920:4;4911:6;4847:78;:::i;:::-;4839:86;;4619:313;;;;:::o;4938:329::-;4997:6;5046:2;5034:9;5025:7;5021:23;5017:32;5014:119;;;5052:79;;:::i;:::-;5014:119;5172:1;5197:53;5242:7;5233:6;5222:9;5218:22;5197:53;:::i;:::-;5187:63;;5143:117;4938:329;;;;:::o;5273:114::-;5340:6;5374:5;5368:12;5358:22;;5273:114;;;:::o;5393:184::-;5492:11;5526:6;5521:3;5514:19;5566:4;5561:3;5557:14;5542:29;;5393:184;;;;:::o;5583:132::-;5650:4;5673:3;5665:11;;5703:4;5698:3;5694:14;5686:22;;5583:132;;;:::o;5721:108::-;5798:24;5816:5;5798:24;:::i;:::-;5793:3;5786:37;5721:108;;:::o;5835:179::-;5904:10;5925:46;5967:3;5959:6;5925:46;:::i;:::-;6003:4;5998:3;5994:14;5980:28;;5835:179;;;;:::o;6020:113::-;6090:4;6122;6117:3;6113:14;6105:22;;6020:113;;;:::o;6169:732::-;6288:3;6317:54;6365:5;6317:54;:::i;:::-;6387:86;6466:6;6461:3;6387:86;:::i;:::-;6380:93;;6497:56;6547:5;6497:56;:::i;:::-;6576:7;6607:1;6592:284;6617:6;6614:1;6611:13;6592:284;;;6693:6;6687:13;6720:63;6779:3;6764:13;6720:63;:::i;:::-;6713:70;;6806:60;6859:6;6806:60;:::i;:::-;6796:70;;6652:224;6639:1;6636;6632:9;6627:14;;6592:284;;;6596:14;6892:3;6885:10;;6293:608;;;6169:732;;;;:::o;6907:373::-;7050:4;7088:2;7077:9;7073:18;7065:26;;7137:9;7131:4;7127:20;7123:1;7112:9;7108:17;7101:47;7165:108;7268:4;7259:6;7165:108;:::i;:::-;7157:116;;6907:373;;;;:::o;7286:116::-;7356:21;7371:5;7356:21;:::i;:::-;7349:5;7346:32;7336:60;;7392:1;7389;7382:12;7336:60;7286:116;:::o;7408:133::-;7451:5;7489:6;7476:20;7467:29;;7505:30;7529:5;7505:30;:::i;:::-;7408:133;;;;:::o;7547:323::-;7603:6;7652:2;7640:9;7631:7;7627:23;7623:32;7620:119;;;7658:79;;:::i;:::-;7620:119;7778:1;7803:50;7845:7;7836:6;7825:9;7821:22;7803:50;:::i;:::-;7793:60;;7749:114;7547:323;;;;:::o;7876:77::-;7913:7;7942:5;7931:16;;7876:77;;;:::o;7959:122::-;8032:24;8050:5;8032:24;:::i;:::-;8025:5;8022:35;8012:63;;8071:1;8068;8061:12;8012:63;7959:122;:::o;8087:139::-;8133:5;8171:6;8158:20;8149:29;;8187:33;8214:5;8187:33;:::i;:::-;8087:139;;;;:::o;8232:329::-;8291:6;8340:2;8328:9;8319:7;8315:23;8311:32;8308:119;;;8346:79;;:::i;:::-;8308:119;8466:1;8491:53;8536:7;8527:6;8516:9;8512:22;8491:53;:::i;:::-;8481:63;;8437:117;8232:329;;;;:::o;8567:118::-;8654:24;8672:5;8654:24;:::i;:::-;8649:3;8642:37;8567:118;;:::o;8691:222::-;8784:4;8822:2;8811:9;8807:18;8799:26;;8835:71;8903:1;8892:9;8888:17;8879:6;8835:71;:::i;:::-;8691:222;;;;:::o;8919:117::-;9028:1;9025;9018:12;9042:180;9090:77;9087:1;9080:88;9187:4;9184:1;9177:15;9211:4;9208:1;9201:15;9228:281;9311:27;9333:4;9311:27;:::i;:::-;9303:6;9299:40;9441:6;9429:10;9426:22;9405:18;9393:10;9390:34;9387:62;9384:88;;;9452:18;;:::i;:::-;9384:88;9492:10;9488:2;9481:22;9271:238;9228:281;;:::o;9515:129::-;9549:6;9576:20;;:::i;:::-;9566:30;;9605:33;9633:4;9625:6;9605:33;:::i;:::-;9515:129;;;:::o;9650:311::-;9727:4;9817:18;9809:6;9806:30;9803:56;;;9839:18;;:::i;:::-;9803:56;9889:4;9881:6;9877:17;9869:25;;9949:4;9943;9939:15;9931:23;;9650:311;;;:::o;9967:117::-;10076:1;10073;10066:12;10107:710;10203:5;10228:81;10244:64;10301:6;10244:64;:::i;:::-;10228:81;:::i;:::-;10219:90;;10329:5;10358:6;10351:5;10344:21;10392:4;10385:5;10381:16;10374:23;;10445:4;10437:6;10433:17;10425:6;10421:30;10474:3;10466:6;10463:15;10460:122;;;10493:79;;:::i;:::-;10460:122;10608:6;10591:220;10625:6;10620:3;10617:15;10591:220;;;10700:3;10729:37;10762:3;10750:10;10729:37;:::i;:::-;10724:3;10717:50;10796:4;10791:3;10787:14;10780:21;;10667:144;10651:4;10646:3;10642:14;10635:21;;10591:220;;;10595:21;10209:608;;10107:710;;;;;:::o;10840:370::-;10911:5;10960:3;10953:4;10945:6;10941:17;10937:27;10927:122;;10968:79;;:::i;:::-;10927:122;11085:6;11072:20;11110:94;11200:3;11192:6;11185:4;11177:6;11173:17;11110:94;:::i;:::-;11101:103;;10917:293;10840:370;;;;:::o;11216:117::-;11325:1;11322;11315:12;11339:307;11400:4;11490:18;11482:6;11479:30;11476:56;;;11512:18;;:::i;:::-;11476:56;11550:29;11572:6;11550:29;:::i;:::-;11542:37;;11634:4;11628;11624:15;11616:23;;11339:307;;;:::o;11652:154::-;11736:6;11731:3;11726;11713:30;11798:1;11789:6;11784:3;11780:16;11773:27;11652:154;;;:::o;11812:410::-;11889:5;11914:65;11930:48;11971:6;11930:48;:::i;:::-;11914:65;:::i;:::-;11905:74;;12002:6;11995:5;11988:21;12040:4;12033:5;12029:16;12078:3;12069:6;12064:3;12060:16;12057:25;12054:112;;;12085:79;;:::i;:::-;12054:112;12175:41;12209:6;12204:3;12199;12175:41;:::i;:::-;11895:327;11812:410;;;;;:::o;12241:338::-;12296:5;12345:3;12338:4;12330:6;12326:17;12322:27;12312:122;;12353:79;;:::i;:::-;12312:122;12470:6;12457:20;12495:78;12569:3;12561:6;12554:4;12546:6;12542:17;12495:78;:::i;:::-;12486:87;;12302:277;12241:338;;;;:::o;12585:1509::-;12739:6;12747;12755;12763;12771;12820:3;12808:9;12799:7;12795:23;12791:33;12788:120;;;12827:79;;:::i;:::-;12788:120;12947:1;12972:53;13017:7;13008:6;12997:9;12993:22;12972:53;:::i;:::-;12962:63;;12918:117;13074:2;13100:53;13145:7;13136:6;13125:9;13121:22;13100:53;:::i;:::-;13090:63;;13045:118;13230:2;13219:9;13215:18;13202:32;13261:18;13253:6;13250:30;13247:117;;;13283:79;;:::i;:::-;13247:117;13388:78;13458:7;13449:6;13438:9;13434:22;13388:78;:::i;:::-;13378:88;;13173:303;13543:2;13532:9;13528:18;13515:32;13574:18;13566:6;13563:30;13560:117;;;13596:79;;:::i;:::-;13560:117;13701:78;13771:7;13762:6;13751:9;13747:22;13701:78;:::i;:::-;13691:88;;13486:303;13856:3;13845:9;13841:19;13828:33;13888:18;13880:6;13877:30;13874:117;;;13910:79;;:::i;:::-;13874:117;14015:62;14069:7;14060:6;14049:9;14045:22;14015:62;:::i;:::-;14005:72;;13799:288;12585:1509;;;;;;;;:::o;14100:474::-;14168:6;14176;14225:2;14213:9;14204:7;14200:23;14196:32;14193:119;;;14231:79;;:::i;:::-;14193:119;14351:1;14376:53;14421:7;14412:6;14401:9;14397:22;14376:53;:::i;:::-;14366:63;;14322:117;14478:2;14504:53;14549:7;14540:6;14529:9;14525:22;14504:53;:::i;:::-;14494:63;;14449:118;14100:474;;;;;:::o;14580:311::-;14657:4;14747:18;14739:6;14736:30;14733:56;;;14769:18;;:::i;:::-;14733:56;14819:4;14811:6;14807:17;14799:25;;14879:4;14873;14869:15;14861:23;;14580:311;;;:::o;14914:710::-;15010:5;15035:81;15051:64;15108:6;15051:64;:::i;:::-;15035:81;:::i;:::-;15026:90;;15136:5;15165:6;15158:5;15151:21;15199:4;15192:5;15188:16;15181:23;;15252:4;15244:6;15240:17;15232:6;15228:30;15281:3;15273:6;15270:15;15267:122;;;15300:79;;:::i;:::-;15267:122;15415:6;15398:220;15432:6;15427:3;15424:15;15398:220;;;15507:3;15536:37;15569:3;15557:10;15536:37;:::i;:::-;15531:3;15524:50;15603:4;15598:3;15594:14;15587:21;;15474:144;15458:4;15453:3;15449:14;15442:21;;15398:220;;;15402:21;15016:608;;14914:710;;;;;:::o;15647:370::-;15718:5;15767:3;15760:4;15752:6;15748:17;15744:27;15734:122;;15775:79;;:::i;:::-;15734:122;15892:6;15879:20;15917:94;16007:3;15999:6;15992:4;15984:6;15980:17;15917:94;:::i;:::-;15908:103;;15724:293;15647:370;;;;:::o;16023:894::-;16141:6;16149;16198:2;16186:9;16177:7;16173:23;16169:32;16166:119;;;16204:79;;:::i;:::-;16166:119;16352:1;16341:9;16337:17;16324:31;16382:18;16374:6;16371:30;16368:117;;;16404:79;;:::i;:::-;16368:117;16509:78;16579:7;16570:6;16559:9;16555:22;16509:78;:::i;:::-;16499:88;;16295:302;16664:2;16653:9;16649:18;16636:32;16695:18;16687:6;16684:30;16681:117;;;16717:79;;:::i;:::-;16681:117;16822:78;16892:7;16883:6;16872:9;16868:22;16822:78;:::i;:::-;16812:88;;16607:303;16023:894;;;;;:::o;16923:308::-;16985:4;17075:18;17067:6;17064:30;17061:56;;;17097:18;;:::i;:::-;17061:56;17135:29;17157:6;17135:29;:::i;:::-;17127:37;;17219:4;17213;17209:15;17201:23;;16923:308;;;:::o;17237:412::-;17315:5;17340:66;17356:49;17398:6;17356:49;:::i;:::-;17340:66;:::i;:::-;17331:75;;17429:6;17422:5;17415:21;17467:4;17460:5;17456:16;17505:3;17496:6;17491:3;17487:16;17484:25;17481:112;;;17512:79;;:::i;:::-;17481:112;17602:41;17636:6;17631:3;17626;17602:41;:::i;:::-;17321:328;17237:412;;;;;:::o;17669:340::-;17725:5;17774:3;17767:4;17759:6;17755:17;17751:27;17741:122;;17782:79;;:::i;:::-;17741:122;17899:6;17886:20;17924:79;17999:3;17991:6;17984:4;17976:6;17972:17;17924:79;:::i;:::-;17915:88;;17731:278;17669:340;;;;:::o;18015:509::-;18084:6;18133:2;18121:9;18112:7;18108:23;18104:32;18101:119;;;18139:79;;:::i;:::-;18101:119;18287:1;18276:9;18272:17;18259:31;18317:18;18309:6;18306:30;18303:117;;;18339:79;;:::i;:::-;18303:117;18444:63;18499:7;18490:6;18479:9;18475:22;18444:63;:::i;:::-;18434:73;;18230:287;18015:509;;;;:::o;18530:1039::-;18657:6;18665;18673;18722:2;18710:9;18701:7;18697:23;18693:32;18690:119;;;18728:79;;:::i;:::-;18690:119;18848:1;18873:53;18918:7;18909:6;18898:9;18894:22;18873:53;:::i;:::-;18863:63;;18819:117;19003:2;18992:9;18988:18;18975:32;19034:18;19026:6;19023:30;19020:117;;;19056:79;;:::i;:::-;19020:117;19161:78;19231:7;19222:6;19211:9;19207:22;19161:78;:::i;:::-;19151:88;;18946:303;19316:2;19305:9;19301:18;19288:32;19347:18;19339:6;19336:30;19333:117;;;19369:79;;:::i;:::-;19333:117;19474:78;19544:7;19535:6;19524:9;19520:22;19474:78;:::i;:::-;19464:88;;19259:303;18530:1039;;;;;:::o;19575:632::-;19766:4;19804:3;19793:9;19789:19;19781:27;;19818:65;19880:1;19869:9;19865:17;19856:6;19818:65;:::i;:::-;19893:72;19961:2;19950:9;19946:18;19937:6;19893:72;:::i;:::-;20012:9;20006:4;20002:20;19997:2;19986:9;19982:18;19975:48;20040:78;20113:4;20104:6;20040:78;:::i;:::-;20032:86;;20128:72;20196:2;20185:9;20181:18;20172:6;20128:72;:::i;:::-;19575:632;;;;;;;:::o;20213:468::-;20278:6;20286;20335:2;20323:9;20314:7;20310:23;20306:32;20303:119;;;20341:79;;:::i;:::-;20303:119;20461:1;20486:53;20531:7;20522:6;20511:9;20507:22;20486:53;:::i;:::-;20476:63;;20432:117;20588:2;20614:50;20656:7;20647:6;20636:9;20632:22;20614:50;:::i;:::-;20604:60;;20559:115;20213:468;;;;;:::o;20687:117::-;20796:1;20793;20786:12;20823:552;20880:8;20890:6;20940:3;20933:4;20925:6;20921:17;20917:27;20907:122;;20948:79;;:::i;:::-;20907:122;21061:6;21048:20;21038:30;;21091:18;21083:6;21080:30;21077:117;;;21113:79;;:::i;:::-;21077:117;21227:4;21219:6;21215:17;21203:29;;21281:3;21273:4;21265:6;21261:17;21251:8;21247:32;21244:41;21241:128;;;21288:79;;:::i;:::-;21241:128;20823:552;;;;;:::o;21381:672::-;21460:6;21468;21476;21525:2;21513:9;21504:7;21500:23;21496:32;21493:119;;;21531:79;;:::i;:::-;21493:119;21651:1;21676:53;21721:7;21712:6;21701:9;21697:22;21676:53;:::i;:::-;21666:63;;21622:117;21806:2;21795:9;21791:18;21778:32;21837:18;21829:6;21826:30;21823:117;;;21859:79;;:::i;:::-;21823:117;21972:64;22028:7;22019:6;22008:9;22004:22;21972:64;:::i;:::-;21954:82;;;;21749:297;21381:672;;;;;:::o;22059:474::-;22127:6;22135;22184:2;22172:9;22163:7;22159:23;22155:32;22152:119;;;22190:79;;:::i;:::-;22152:119;22310:1;22335:53;22380:7;22371:6;22360:9;22356:22;22335:53;:::i;:::-;22325:63;;22281:117;22437:2;22463:53;22508:7;22499:6;22488:9;22484:22;22463:53;:::i;:::-;22453:63;;22408:118;22059:474;;;;;:::o;22539:1089::-;22643:6;22651;22659;22667;22675;22724:3;22712:9;22703:7;22699:23;22695:33;22692:120;;;22731:79;;:::i;:::-;22692:120;22851:1;22876:53;22921:7;22912:6;22901:9;22897:22;22876:53;:::i;:::-;22866:63;;22822:117;22978:2;23004:53;23049:7;23040:6;23029:9;23025:22;23004:53;:::i;:::-;22994:63;;22949:118;23106:2;23132:53;23177:7;23168:6;23157:9;23153:22;23132:53;:::i;:::-;23122:63;;23077:118;23234:2;23260:53;23305:7;23296:6;23285:9;23281:22;23260:53;:::i;:::-;23250:63;;23205:118;23390:3;23379:9;23375:19;23362:33;23422:18;23414:6;23411:30;23408:117;;;23444:79;;:::i;:::-;23408:117;23549:62;23603:7;23594:6;23583:9;23579:22;23549:62;:::i;:::-;23539:72;;23333:288;22539:1089;;;;;;;;:::o;23634:619::-;23711:6;23719;23727;23776:2;23764:9;23755:7;23751:23;23747:32;23744:119;;;23782:79;;:::i;:::-;23744:119;23902:1;23927:53;23972:7;23963:6;23952:9;23948:22;23927:53;:::i;:::-;23917:63;;23873:117;24029:2;24055:53;24100:7;24091:6;24080:9;24076:22;24055:53;:::i;:::-;24045:63;;24000:118;24157:2;24183:53;24228:7;24219:6;24208:9;24204:22;24183:53;:::i;:::-;24173:63;;24128:118;23634:619;;;;;:::o;24259:230::-;24399:34;24395:1;24387:6;24383:14;24376:58;24468:13;24463:2;24455:6;24451:15;24444:38;24259:230;:::o;24495:366::-;24637:3;24658:67;24722:2;24717:3;24658:67;:::i;:::-;24651:74;;24734:93;24823:3;24734:93;:::i;:::-;24852:2;24847:3;24843:12;24836:19;;24495:366;;;:::o;24867:419::-;25033:4;25071:2;25060:9;25056:18;25048:26;;25120:9;25114:4;25110:20;25106:1;25095:9;25091:17;25084:47;25148:131;25274:4;25148:131;:::i;:::-;25140:139;;24867:419;;;:::o;25292:168::-;25432:20;25428:1;25420:6;25416:14;25409:44;25292:168;:::o;25466:366::-;25608:3;25629:67;25693:2;25688:3;25629:67;:::i;:::-;25622:74;;25705:93;25794:3;25705:93;:::i;:::-;25823:2;25818:3;25814:12;25807:19;;25466:366;;;:::o;25838:419::-;26004:4;26042:2;26031:9;26027:18;26019:26;;26091:9;26085:4;26081:20;26077:1;26066:9;26062:17;26055:47;26119:131;26245:4;26119:131;:::i;:::-;26111:139;;25838:419;;;:::o;26263:148::-;26365:11;26402:3;26387:18;;26263:148;;;;:::o;26417:377::-;26523:3;26551:39;26584:5;26551:39;:::i;:::-;26606:89;26688:6;26683:3;26606:89;:::i;:::-;26599:96;;26704:52;26749:6;26744:3;26737:4;26730:5;26726:16;26704:52;:::i;:::-;26781:6;26776:3;26772:16;26765:23;;26527:267;26417:377;;;;:::o;26800:435::-;26980:3;27002:95;27093:3;27084:6;27002:95;:::i;:::-;26995:102;;27114:95;27205:3;27196:6;27114:95;:::i;:::-;27107:102;;27226:3;27219:10;;26800:435;;;;;:::o;27241:182::-;27381:34;27377:1;27369:6;27365:14;27358:58;27241:182;:::o;27429:366::-;27571:3;27592:67;27656:2;27651:3;27592:67;:::i;:::-;27585:74;;27668:93;27757:3;27668:93;:::i;:::-;27786:2;27781:3;27777:12;27770:19;;27429:366;;;:::o;27801:419::-;27967:4;28005:2;27994:9;27990:18;27982:26;;28054:9;28048:4;28044:20;28040:1;28029:9;28025:17;28018:47;28082:131;28208:4;28082:131;:::i;:::-;28074:139;;27801:419;;;:::o;28226:237::-;28366:34;28362:1;28354:6;28350:14;28343:58;28435:20;28430:2;28422:6;28418:15;28411:45;28226:237;:::o;28469:366::-;28611:3;28632:67;28696:2;28691:3;28632:67;:::i;:::-;28625:74;;28708:93;28797:3;28708:93;:::i;:::-;28826:2;28821:3;28817:12;28810:19;;28469:366;;;:::o;28841:419::-;29007:4;29045:2;29034:9;29030:18;29022:26;;29094:9;29088:4;29084:20;29080:1;29069:9;29065:17;29058:47;29122:131;29248:4;29122:131;:::i;:::-;29114:139;;28841:419;;;:::o;29266:180::-;29314:77;29311:1;29304:88;29411:4;29408:1;29401:15;29435:4;29432:1;29425:15;29452:180;29500:77;29497:1;29490:88;29597:4;29594:1;29587:15;29621:4;29618:1;29611:15;29638:233;29677:3;29700:24;29718:5;29700:24;:::i;:::-;29691:33;;29746:66;29739:5;29736:77;29733:103;;;29816:18;;:::i;:::-;29733:103;29863:1;29856:5;29852:13;29845:20;;29638:233;;;:::o;29877:234::-;30017:34;30013:1;30005:6;30001:14;29994:58;30086:17;30081:2;30073:6;30069:15;30062:42;29877:234;:::o;30117:366::-;30259:3;30280:67;30344:2;30339:3;30280:67;:::i;:::-;30273:74;;30356:93;30445:3;30356:93;:::i;:::-;30474:2;30469:3;30465:12;30458:19;;30117:366;;;:::o;30489:419::-;30655:4;30693:2;30682:9;30678:18;30670:26;;30742:9;30736:4;30732:20;30728:1;30717:9;30713:17;30706:47;30770:131;30896:4;30770:131;:::i;:::-;30762:139;;30489:419;;;:::o;30914:228::-;31054:34;31050:1;31042:6;31038:14;31031:58;31123:11;31118:2;31110:6;31106:15;31099:36;30914:228;:::o;31148:366::-;31290:3;31311:67;31375:2;31370:3;31311:67;:::i;:::-;31304:74;;31387:93;31476:3;31387:93;:::i;:::-;31505:2;31500:3;31496:12;31489:19;;31148:366;;;:::o;31520:419::-;31686:4;31724:2;31713:9;31709:18;31701:26;;31773:9;31767:4;31763:20;31759:1;31748:9;31744:17;31737:47;31801:131;31927:4;31801:131;:::i;:::-;31793:139;;31520:419;;;:::o;31945:180::-;31993:77;31990:1;31983:88;32090:4;32087:1;32080:15;32114:4;32111:1;32104:15;32131:320;32175:6;32212:1;32206:4;32202:12;32192:22;;32259:1;32253:4;32249:12;32280:18;32270:81;;32336:4;32328:6;32324:17;32314:27;;32270:81;32398:2;32390:6;32387:14;32367:18;32364:38;32361:84;;;32417:18;;:::i;:::-;32361:84;32182:269;32131:320;;;:::o;32457:228::-;32597:34;32593:1;32585:6;32581:14;32574:58;32666:11;32661:2;32653:6;32649:15;32642:36;32457:228;:::o;32691:366::-;32833:3;32854:67;32918:2;32913:3;32854:67;:::i;:::-;32847:74;;32930:93;33019:3;32930:93;:::i;:::-;33048:2;33043:3;33039:12;33032:19;;32691:366;;;:::o;33063:419::-;33229:4;33267:2;33256:9;33252:18;33244:26;;33316:9;33310:4;33306:20;33302:1;33291:9;33287:17;33280:47;33344:131;33470:4;33344:131;:::i;:::-;33336:139;;33063:419;;;:::o;33488:228::-;33628:34;33624:1;33616:6;33612:14;33605:58;33697:11;33692:2;33684:6;33680:15;33673:36;33488:228;:::o;33722:366::-;33864:3;33885:67;33949:2;33944:3;33885:67;:::i;:::-;33878:74;;33961:93;34050:3;33961:93;:::i;:::-;34079:2;34074:3;34070:12;34063:19;;33722:366;;;:::o;34094:419::-;34260:4;34298:2;34287:9;34283:18;34275:26;;34347:9;34341:4;34337:20;34333:1;34322:9;34318:17;34311:47;34375:131;34501:4;34375:131;:::i;:::-;34367:139;;34094:419;;;:::o;34519:172::-;34659:24;34655:1;34647:6;34643:14;34636:48;34519:172;:::o;34697:366::-;34839:3;34860:67;34924:2;34919:3;34860:67;:::i;:::-;34853:74;;34936:93;35025:3;34936:93;:::i;:::-;35054:2;35049:3;35045:12;35038:19;;34697:366;;;:::o;35069:419::-;35235:4;35273:2;35262:9;35258:18;35250:26;;35322:9;35316:4;35312:20;35308:1;35297:9;35293:17;35286:47;35350:131;35476:4;35350:131;:::i;:::-;35342:139;;35069:419;;;:::o;35494:168::-;35634:20;35630:1;35622:6;35618:14;35611:44;35494:168;:::o;35668:366::-;35810:3;35831:67;35895:2;35890:3;35831:67;:::i;:::-;35824:74;;35907:93;35996:3;35907:93;:::i;:::-;36025:2;36020:3;36016:12;36009:19;;35668:366;;;:::o;36040:419::-;36206:4;36244:2;36233:9;36229:18;36221:26;;36293:9;36287:4;36283:20;36279:1;36268:9;36264:17;36257:47;36321:131;36447:4;36321:131;:::i;:::-;36313:139;;36040:419;;;:::o;36465:79::-;36504:7;36533:5;36522:16;;36465:79;;;:::o;36550:157::-;36655:45;36675:24;36693:5;36675:24;:::i;:::-;36655:45;:::i;:::-;36650:3;36643:58;36550:157;;:::o;36713:94::-;36746:8;36794:5;36790:2;36786:14;36765:35;;36713:94;;;:::o;36813:::-;36852:7;36881:20;36895:5;36881:20;:::i;:::-;36870:31;;36813:94;;;:::o;36913:100::-;36952:7;36981:26;37001:5;36981:26;:::i;:::-;36970:37;;36913:100;;;:::o;37019:157::-;37124:45;37144:24;37162:5;37144:24;:::i;:::-;37124:45;:::i;:::-;37119:3;37112:58;37019:157;;:::o;37182:538::-;37350:3;37365:75;37436:3;37427:6;37365:75;:::i;:::-;37465:2;37460:3;37456:12;37449:19;;37478:75;37549:3;37540:6;37478:75;:::i;:::-;37578:2;37573:3;37569:12;37562:19;;37591:75;37662:3;37653:6;37591:75;:::i;:::-;37691:2;37686:3;37682:12;37675:19;;37711:3;37704:10;;37182:538;;;;;;:::o;37726:180::-;37774:77;37771:1;37764:88;37871:4;37868:1;37861:15;37895:4;37892:1;37885:15;37912:176;37944:1;37961:20;37979:1;37961:20;:::i;:::-;37956:25;;37995:20;38013:1;37995:20;:::i;:::-;37990:25;;38034:1;38024:35;;38039:18;;:::i;:::-;38024:35;38080:1;38077;38073:9;38068:14;;37912:176;;;;:::o;38094:185::-;38134:1;38151:20;38169:1;38151:20;:::i;:::-;38146:25;;38185:20;38203:1;38185:20;:::i;:::-;38180:25;;38224:1;38214:35;;38229:18;;:::i;:::-;38214:35;38271:1;38268;38264:9;38259:14;;38094:185;;;;:::o;38285:191::-;38325:4;38345:20;38363:1;38345:20;:::i;:::-;38340:25;;38379:20;38397:1;38379:20;:::i;:::-;38374:25;;38418:1;38415;38412:8;38409:34;;;38423:18;;:::i;:::-;38409:34;38468:1;38465;38461:9;38453:17;;38285:191;;;;:::o;38482:305::-;38522:3;38541:20;38559:1;38541:20;:::i;:::-;38536:25;;38575:20;38593:1;38575:20;:::i;:::-;38570:25;;38729:1;38661:66;38657:74;38654:1;38651:81;38648:107;;;38735:18;;:::i;:::-;38648:107;38779:1;38776;38772:9;38765:16;;38482:305;;;;:::o;38793:227::-;38933:34;38929:1;38921:6;38917:14;38910:58;39002:10;38997:2;38989:6;38985:15;38978:35;38793:227;:::o;39026:366::-;39168:3;39189:67;39253:2;39248:3;39189:67;:::i;:::-;39182:74;;39265:93;39354:3;39265:93;:::i;:::-;39383:2;39378:3;39374:12;39367:19;;39026:366;;;:::o;39398:419::-;39564:4;39602:2;39591:9;39587:18;39579:26;;39651:9;39645:4;39641:20;39637:1;39626:9;39622:17;39615:47;39679:131;39805:4;39679:131;:::i;:::-;39671:139;;39398:419;;;:::o;39823:224::-;39963:34;39959:1;39951:6;39947:14;39940:58;40032:7;40027:2;40019:6;40015:15;40008:32;39823:224;:::o;40053:366::-;40195:3;40216:67;40280:2;40275:3;40216:67;:::i;:::-;40209:74;;40292:93;40381:3;40292:93;:::i;:::-;40410:2;40405:3;40401:12;40394:19;;40053:366;;;:::o;40425:419::-;40591:4;40629:2;40618:9;40614:18;40606:26;;40678:9;40672:4;40668:20;40664:1;40653:9;40649:17;40642:47;40706:131;40832:4;40706:131;:::i;:::-;40698:139;;40425:419;;;:::o;40850:229::-;40990:34;40986:1;40978:6;40974:14;40967:58;41059:12;41054:2;41046:6;41042:15;41035:37;40850:229;:::o;41085:366::-;41227:3;41248:67;41312:2;41307:3;41248:67;:::i;:::-;41241:74;;41324:93;41413:3;41324:93;:::i;:::-;41442:2;41437:3;41433:12;41426:19;;41085:366;;;:::o;41457:419::-;41623:4;41661:2;41650:9;41646:18;41638:26;;41710:9;41704:4;41700:20;41696:1;41685:9;41681:17;41674:47;41738:131;41864:4;41738:131;:::i;:::-;41730:139;;41457:419;;;:::o;41882:634::-;42103:4;42141:2;42130:9;42126:18;42118:26;;42190:9;42184:4;42180:20;42176:1;42165:9;42161:17;42154:47;42218:108;42321:4;42312:6;42218:108;:::i;:::-;42210:116;;42373:9;42367:4;42363:20;42358:2;42347:9;42343:18;42336:48;42401:108;42504:4;42495:6;42401:108;:::i;:::-;42393:116;;41882:634;;;;;:::o;42522:173::-;42662:25;42658:1;42650:6;42646:14;42639:49;42522:173;:::o;42701:402::-;42861:3;42882:85;42964:2;42959:3;42882:85;:::i;:::-;42875:92;;42976:93;43065:3;42976:93;:::i;:::-;43094:2;43089:3;43085:12;43078:19;;42701:402;;;:::o;43109:167::-;43249:19;43245:1;43237:6;43233:14;43226:43;43109:167;:::o;43282:402::-;43442:3;43463:85;43545:2;43540:3;43463:85;:::i;:::-;43456:92;;43557:93;43646:3;43557:93;:::i;:::-;43675:2;43670:3;43666:12;43659:19;;43282:402;;;:::o;43690:967::-;44072:3;44094:148;44238:3;44094:148;:::i;:::-;44087:155;;44259:95;44350:3;44341:6;44259:95;:::i;:::-;44252:102;;44371:148;44515:3;44371:148;:::i;:::-;44364:155;;44536:95;44627:3;44618:6;44536:95;:::i;:::-;44529:102;;44648:3;44641:10;;43690:967;;;;;:::o;44663:332::-;44784:4;44822:2;44811:9;44807:18;44799:26;;44835:71;44903:1;44892:9;44888:17;44879:6;44835:71;:::i;:::-;44916:72;44984:2;44973:9;44969:18;44960:6;44916:72;:::i;:::-;44663:332;;;;;:::o;45001:118::-;45088:24;45106:5;45088:24;:::i;:::-;45083:3;45076:37;45001:118;;:::o;45125:98::-;45176:6;45210:5;45204:12;45194:22;;45125:98;;;:::o;45229:168::-;45312:11;45346:6;45341:3;45334:19;45386:4;45381:3;45377:14;45362:29;;45229:168;;;;:::o;45403:360::-;45489:3;45517:38;45549:5;45517:38;:::i;:::-;45571:70;45634:6;45629:3;45571:70;:::i;:::-;45564:77;;45650:52;45695:6;45690:3;45683:4;45676:5;45672:16;45650:52;:::i;:::-;45727:29;45749:6;45727:29;:::i;:::-;45722:3;45718:39;45711:46;;45493:270;45403:360;;;;:::o;45769:1053::-;46092:4;46130:3;46119:9;46115:19;46107:27;;46144:71;46212:1;46201:9;46197:17;46188:6;46144:71;:::i;:::-;46225:72;46293:2;46282:9;46278:18;46269:6;46225:72;:::i;:::-;46344:9;46338:4;46334:20;46329:2;46318:9;46314:18;46307:48;46372:108;46475:4;46466:6;46372:108;:::i;:::-;46364:116;;46527:9;46521:4;46517:20;46512:2;46501:9;46497:18;46490:48;46555:108;46658:4;46649:6;46555:108;:::i;:::-;46547:116;;46711:9;46705:4;46701:20;46695:3;46684:9;46680:19;46673:49;46739:76;46810:4;46801:6;46739:76;:::i;:::-;46731:84;;45769:1053;;;;;;;;:::o;46828:141::-;46884:5;46915:6;46909:13;46900:22;;46931:32;46957:5;46931:32;:::i;:::-;46828:141;;;;:::o;46975:349::-;47044:6;47093:2;47081:9;47072:7;47068:23;47064:32;47061:119;;;47099:79;;:::i;:::-;47061:119;47219:1;47244:63;47299:7;47290:6;47279:9;47275:22;47244:63;:::i;:::-;47234:73;;47190:127;46975:349;;;;:::o;47330:106::-;47374:8;47423:5;47418:3;47414:15;47393:36;;47330:106;;;:::o;47442:183::-;47477:3;47515:1;47497:16;47494:23;47491:128;;;47553:1;47550;47547;47532:23;47575:34;47606:1;47600:8;47575:34;:::i;:::-;47568:41;;47491:128;47442:183;:::o;47631:711::-;47670:3;47708:4;47690:16;47687:26;47684:39;;;47716:5;;47684:39;47745:20;;:::i;:::-;47820:1;47802:16;47798:24;47795:1;47789:4;47774:49;47853:4;47847:11;47952:16;47945:4;47937:6;47933:17;47930:39;47897:18;47889:6;47886:30;47870:113;47867:146;;;47998:5;;;;47867:146;48044:6;48038:4;48034:17;48080:3;48074:10;48107:18;48099:6;48096:30;48093:43;;;48129:5;;;;;;48093:43;48177:6;48170:4;48165:3;48161:14;48157:27;48236:1;48218:16;48214:24;48208:4;48204:35;48199:3;48196:44;48193:57;;;48243:5;;;;;;;48193:57;48260;48308:6;48302:4;48298:17;48290:6;48286:30;48280:4;48260:57;:::i;:::-;48333:3;48326:10;;47674:668;;;;;47631:711;;:::o;48348:239::-;48488:34;48484:1;48476:6;48472:14;48465:58;48557:22;48552:2;48544:6;48540:15;48533:47;48348:239;:::o;48593:366::-;48735:3;48756:67;48820:2;48815:3;48756:67;:::i;:::-;48749:74;;48832:93;48921:3;48832:93;:::i;:::-;48950:2;48945:3;48941:12;48934:19;;48593:366;;;:::o;48965:419::-;49131:4;49169:2;49158:9;49154:18;49146:26;;49218:9;49212:4;49208:20;49204:1;49193:9;49189:17;49182:47;49246:131;49372:4;49246:131;:::i;:::-;49238:139;;48965:419;;;:::o;49390:227::-;49530:34;49526:1;49518:6;49514:14;49507:58;49599:10;49594:2;49586:6;49582:15;49575:35;49390:227;:::o;49623:366::-;49765:3;49786:67;49850:2;49845:3;49786:67;:::i;:::-;49779:74;;49862:93;49951:3;49862:93;:::i;:::-;49980:2;49975:3;49971:12;49964:19;;49623:366;;;:::o;49995:419::-;50161:4;50199:2;50188:9;50184:18;50176:26;;50248:9;50242:4;50238:20;50234:1;50223:9;50219:17;50212:47;50276:131;50402:4;50276:131;:::i;:::-;50268:139;;49995:419;;;:::o;50420:348::-;50460:7;50483:20;50501:1;50483:20;:::i;:::-;50478:25;;50517:20;50535:1;50517:20;:::i;:::-;50512:25;;50705:1;50637:66;50633:74;50630:1;50627:81;50622:1;50615:9;50608:17;50604:105;50601:131;;;50712:18;;:::i;:::-;50601:131;50760:1;50757;50753:9;50742:20;;50420:348;;;;:::o;50774:171::-;50813:3;50836:24;50854:5;50836:24;:::i;:::-;50827:33;;50882:4;50875:5;50872:15;50869:41;;;50890:18;;:::i;:::-;50869:41;50937:1;50930:5;50926:13;50919:20;;50774:171;;;:::o;50951:182::-;51091:34;51087:1;51079:6;51075:14;51068:58;50951:182;:::o;51139:366::-;51281:3;51302:67;51366:2;51361:3;51302:67;:::i;:::-;51295:74;;51378:93;51467:3;51378:93;:::i;:::-;51496:2;51491:3;51487:12;51480:19;;51139:366;;;:::o;51511:419::-;51677:4;51715:2;51704:9;51700:18;51692:26;;51764:9;51758:4;51754:20;51750:1;51739:9;51735:17;51728:47;51792:131;51918:4;51792:131;:::i;:::-;51784:139;;51511:419;;;:::o;51936:222::-;52076:34;52072:1;52064:6;52060:14;52053:58;52145:5;52140:2;52132:6;52128:15;52121:30;51936:222;:::o;52164:366::-;52306:3;52327:67;52391:2;52386:3;52327:67;:::i;:::-;52320:74;;52403:93;52492:3;52403:93;:::i;:::-;52521:2;52516:3;52512:12;52505:19;;52164:366;;;:::o;52536:419::-;52702:4;52740:2;52729:9;52725:18;52717:26;;52789:9;52783:4;52779:20;52775:1;52764:9;52760:17;52753:47;52817:131;52943:4;52817:131;:::i;:::-;52809:139;;52536:419;;;:::o;52961:223::-;53101:34;53097:1;53089:6;53085:14;53078:58;53170:6;53165:2;53157:6;53153:15;53146:31;52961:223;:::o;53190:366::-;53332:3;53353:67;53417:2;53412:3;53353:67;:::i;:::-;53346:74;;53429:93;53518:3;53429:93;:::i;:::-;53547:2;53542:3;53538:12;53531:19;;53190:366;;;:::o;53562:419::-;53728:4;53766:2;53755:9;53751:18;53743:26;;53815:9;53809:4;53805:20;53801:1;53790:9;53786:17;53779:47;53843:131;53969:4;53843:131;:::i;:::-;53835:139;;53562:419;;;:::o;53987:751::-;54210:4;54248:3;54237:9;54233:19;54225:27;;54262:71;54330:1;54319:9;54315:17;54306:6;54262:71;:::i;:::-;54343:72;54411:2;54400:9;54396:18;54387:6;54343:72;:::i;:::-;54425;54493:2;54482:9;54478:18;54469:6;54425:72;:::i;:::-;54507;54575:2;54564:9;54560:18;54551:6;54507:72;:::i;:::-;54627:9;54621:4;54617:20;54611:3;54600:9;54596:19;54589:49;54655:76;54726:4;54717:6;54655:76;:::i;:::-;54647:84;;53987:751;;;;;;;;:::o;54744:220::-;54884:34;54880:1;54872:6;54868:14;54861:58;54953:3;54948:2;54940:6;54936:15;54929:28;54744:220;:::o;54970:366::-;55112:3;55133:67;55197:2;55192:3;55133:67;:::i;:::-;55126:74;;55209:93;55298:3;55209:93;:::i;:::-;55327:2;55322:3;55318:12;55311:19;;54970:366;;;:::o;55342:419::-;55508:4;55546:2;55535:9;55531:18;55523:26;;55595:9;55589:4;55585:20;55581:1;55570:9;55566:17;55559:47;55623:131;55749:4;55623:131;:::i;:::-;55615:139;;55342:419;;;:::o

Swarm Source

ipfs://759d0383336bf0d360a82ae1ae8682022386fbf57cd5638446f4a267dab2fa99
[ 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.