creation_sourcecode: {{
    "language": "Solidity",
    "settings": {
      "evmVersion": "london",
      "libraries": {},
      "metadata": {
        "bytecodeHash": "ipfs",
        "useLiteralContent": true
      },
      "optimizer": {
        "enabled": false,
        "runs": 200
      },
      "remappings": [],
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    },
    "sources": {
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                bytes32 lastvalue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastvalue;\n                // Update the index for the moved value\n                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        return _values(set._inner);\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"
      },
      "contracts/Automate.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.14;\n\nimport {\n    EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {Proxied} from \"./vendor/proxy/EIP173/Proxied.sol\";\nimport {AutomateStorage} from \"./AutomateStorage.sol\";\nimport {LibDataTypes} from \"./libraries/LibDataTypes.sol\";\nimport {LibEvents} from \"./libraries/LibEvents.sol\";\nimport {LibTaskId} from \"./libraries/LibTaskId.sol\";\nimport {LibTaskModule} from \"./libraries/LibTaskModule.sol\";\nimport {LibBypassModule} from \"./libraries/LibBypassModule.sol\";\nimport {IAutomate} from \"./interfaces/IAutomate.sol\";\n\n/**\n * @notice Automate enables everyone to have Gelato monitor and execute transactions.\n * @notice ExecAddress refers to the contract that has the function which Gelato will call.\n * @notice Modules allow users to customise conditions and specifications when creating a task.\n */\n//solhint-disable function-max-lines\n//solhint-disable no-empty-blocks\ncontract Automate is Gelatofied, Proxied, AutomateStorage, IAutomate {\n    using GelatoBytes for bytes;\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    // solhint-disable const-name-snakecase\n    string public constant version = \"7\";\n\n    constructor(address payable _gelato) Gelatofied(_gelato) {}\n\n    ///@inheritdoc IAutomate\n    function createTask(\n        address _execAddress,\n        bytes calldata _execDataOrSelector,\n        LibDataTypes.ModuleData calldata _moduleData,\n        address _feeToken\n    ) external override returns (bytes32 taskId) {\n        address taskCreator;\n\n        (taskCreator, _execAddress) = LibTaskModule.preCreateTask(\n            msg.sender,\n            _execAddress,\n            taskModuleAddresses\n        );\n\n        taskId = _createTask(\n            taskCreator,\n            _execAddress,\n            _execDataOrSelector,\n            _moduleData,\n            _feeToken\n        );\n    }\n\n    ///@inheritdoc IAutomate\n    function cancelTask(bytes32 _taskId) external {\n        address _taskCreator = LibTaskModule.preCancelTask(\n            _taskId,\n            msg.sender,\n            taskModuleAddresses\n        );\n\n        _cancelTask(_taskCreator, _taskId);\n    }\n\n    ///@inheritdoc IAutomate\n    function exec(\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execData,\n        LibDataTypes.ModuleData calldata _moduleData,\n        uint256 _txFee,\n        address _feeToken,\n        bool _revertOnFailure\n    ) external onlyGelato {\n        bytes32 taskId = LibTaskId.getTaskId(\n            _taskCreator,\n            _execAddress,\n            _execData.memorySliceSelector(),\n            _moduleData,\n            _feeToken\n        );\n\n        require(\n            _createdTasks[_taskCreator].contains(taskId),\n            \"Automate.exec: Task not found\"\n        );\n\n        fee = _txFee;\n        feeToken = _feeToken;\n\n        bool success = LibTaskModule.onExecTask(\n            taskId,\n            _taskCreator,\n            _execAddress,\n            _execData,\n            _moduleData.modules,\n            _revertOnFailure,\n            taskModuleAddresses\n        );\n\n        delete fee;\n        delete feeToken;\n\n        emit LibEvents.ExecSuccess(\n            _txFee,\n            _feeToken,\n            _execAddress,\n            _execData,\n            taskId,\n            success\n        );\n    }\n\n    ///@inheritdoc IAutomate\n    function exec1Balance(\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execData,\n        LibDataTypes.ModuleData calldata _moduleData,\n        Gelato1BalanceParam calldata _oneBalanceParam,\n        bool _revertOnFailure\n    ) external onlyGelato {\n        bytes32 taskId = LibTaskId.getTaskId(\n            _taskCreator,\n            _execAddress,\n            _execData.memorySliceSelector(),\n            _moduleData,\n            address(0)\n        );\n\n        require(\n            _createdTasks[_taskCreator].contains(taskId),\n            \"Automate.exec: Task not found\"\n        );\n\n        bool success = LibTaskModule.onExecTask(\n            taskId,\n            _taskCreator,\n            _execAddress,\n            _execData,\n            _moduleData.modules,\n            _revertOnFailure,\n            taskModuleAddresses\n        );\n\n        emit LibEvents.ExecSuccess(\n            0,\n            address(0),\n            _execAddress,\n            _execData,\n            taskId,\n            success\n        );\n\n        emit LogUseGelato1Balance(\n            _oneBalanceParam.sponsor,\n            _execAddress,\n            _oneBalanceParam.feeToken,\n            _oneBalanceParam.oneBalanceChainId,\n            _oneBalanceParam.nativeToFeeTokenXRateNumerator,\n            _oneBalanceParam.nativeToFeeTokenXRateDenominator,\n            _oneBalanceParam.correlationId\n        );\n    }\n\n    function execBypassModuleSyncFee(\n        address _taskCreator,\n        address _execAddress,\n        bytes32 _taskId,\n        uint256 _txFee,\n        address _feeToken,\n        bytes memory _execData,\n        bool _revertOnFailure,\n        bool _singleExec\n    ) external onlyGelato {\n        require(\n            _createdTasks[_taskCreator].contains(_taskId),\n            \"Automate.exec: Task not found\"\n        );\n\n        fee = _txFee;\n        feeToken = _feeToken;\n\n        bool success = LibBypassModule.onExecTask(\n            _taskId,\n            _taskCreator,\n            _execAddress,\n            _execData,\n            _revertOnFailure,\n            _singleExec,\n            _createdTasks\n        );\n\n        delete fee;\n        delete feeToken;\n\n        emit LibEvents.ExecBypassModuleSyncFeeSuccess(\n            _taskId,\n            _txFee,\n            _feeToken,\n            success\n        );\n    }\n\n    ///@inheritdoc IAutomate\n    function execBypassModule(\n        address _taskCreator,\n        address _execAddress,\n        bytes32 _taskId,\n        bytes32 _correlationId,\n        bytes memory _execData,\n        bool _revertOnFailure,\n        bool _singleExec\n    ) external onlyGelato {\n        require(\n            _createdTasks[_taskCreator].contains(_taskId),\n            \"Automate.exec: Task not found\"\n        );\n\n        bool success = LibBypassModule.onExecTask(\n            _taskId,\n            _taskCreator,\n            _execAddress,\n            _execData,\n            _revertOnFailure,\n            _singleExec,\n            _createdTasks\n        );\n\n        emit LibEvents.ExecBypassModuleSuccess(\n            _taskId,\n            _correlationId,\n            success\n        );\n    }\n\n    ///@inheritdoc IAutomate\n    function setModule(\n        LibDataTypes.Module[] calldata _modules,\n        address[] calldata _moduleAddresses\n    ) external onlyProxyAdmin {\n        uint256 length = _modules.length;\n        for (uint256 i; i < length; i++) {\n            taskModuleAddresses[_modules[i]] = _moduleAddresses[i];\n        }\n    }\n\n    ///@inheritdoc IAutomate\n    function getFeeDetails() external view returns (uint256, address) {\n        return (fee, feeToken);\n    }\n\n    ///@inheritdoc IAutomate\n    function getTaskIdsByUser(address _taskCreator)\n        external\n        view\n        returns (bytes32[] memory)\n    {\n        bytes32[] memory taskIds = _createdTasks[_taskCreator].values();\n\n        return taskIds;\n    }\n\n    ///@inheritdoc IAutomate\n    function getTaskId(\n        address taskCreator,\n        address execAddress,\n        bytes4 execSelector,\n        LibDataTypes.ModuleData memory moduleData,\n        address feeToken\n    ) external pure returns (bytes32 taskId) {\n        taskId = LibTaskId.getTaskId(\n            taskCreator,\n            execAddress,\n            execSelector,\n            moduleData,\n            feeToken\n        );\n    }\n\n    function _createTask(\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execDataOrSelector,\n        LibDataTypes.ModuleData memory _moduleData,\n        address _feeToken\n    ) private returns (bytes32 taskId) {\n        taskId = LibTaskId.getTaskId(\n            _taskCreator,\n            _execAddress,\n            _execDataOrSelector.memorySliceSelector(),\n            _moduleData,\n            _feeToken\n        );\n\n        require(\n            !_createdTasks[_taskCreator].contains(taskId),\n            \"Automate.createTask: Duplicate task\"\n        );\n\n        LibTaskModule.onCreateTask(\n            taskId,\n            _taskCreator,\n            _execAddress,\n            _execDataOrSelector,\n            _moduleData,\n            taskModuleAddresses\n        );\n\n        _createdTasks[_taskCreator].add(taskId);\n\n        emit LibEvents.TaskCreated(\n            _taskCreator,\n            _execAddress,\n            _execDataOrSelector,\n            _moduleData,\n            _feeToken,\n            taskId\n        );\n    }\n\n    function _cancelTask(address _taskCreator, bytes32 _taskId) private {\n        require(\n            _createdTasks[_taskCreator].contains(_taskId),\n            \"Automate.cancelTask: Task not found\"\n        );\n\n        _createdTasks[_taskCreator].remove(_taskId);\n\n        emit LibEvents.TaskCancelled(_taskId, _taskCreator);\n    }\n}\n"
      },
      "contracts/AutomateStorage.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {\n    EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {LibDataTypes} from \"./libraries/LibDataTypes.sol\";\n\n/**\n * @notice Storage layout of Automate smart contract.\n */\n// solhint-disable max-states-count\nabstract contract AutomateStorage {\n    mapping(bytes32 => address) public taskCreator; ///@dev Deprecated\n    mapping(bytes32 => address) public execAddresses; ///@dev Deprecated\n    mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n\n    uint256 public fee;\n    address public feeToken;\n\n    ///@dev Appended State\n    mapping(bytes32 => LibDataTypes.Time) public timedTask; ///@dev Deprecated\n    mapping(LibDataTypes.Module => address) public taskModuleAddresses;\n    mapping(bytes32 => uint256) public nonce1Balance; ///@dev Deprecated\n}\n"
      },
      "contracts/functions/FExec.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport {GelatoBytes} from \"../vendor/gelato/GelatoBytes.sol\";\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\n\nfunction _call(\n    address _add,\n    bytes memory _data,\n    uint256 _value,\n    bool _revertOnFailure,\n    string memory _tracingInfo\n) returns (bool success, bytes memory returnData) {\n    (success, returnData) = _add.call{value: _value}(_data);\n\n    if (!success && _revertOnFailure)\n        GelatoBytes.revertWithError(returnData, _tracingInfo);\n}\n\nfunction _delegateCall(\n    address _add,\n    bytes memory _data,\n    string memory _tracingInfo\n) returns (bool success, bytes memory returnData) {\n    (success, returnData) = _add.delegatecall(_data);\n\n    if (!success) GelatoBytes.revertWithError(returnData, _tracingInfo);\n}\n"
      },
      "contracts/functions/FUtils.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n    SafeERC20,\n    IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n    address payable _to,\n    address _paymentToken,\n    uint256 _amount\n) {\n    if (_paymentToken == ETH) {\n        (bool success, ) = _to.call{value: _amount}(\"\");\n        require(success, \"_transfer: ETH transfer failed\");\n    } else {\n        SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n    }\n}\n"
      },
      "contracts/interfaces/IAutomate.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {LibDataTypes} from \"../libraries/LibDataTypes.sol\";\nimport {IGelato1Balance} from \"./IGelato1Balance.sol\";\n\n// solhint-disable max-line-length\ninterface IAutomate is IGelato1Balance {\n    /**\n     * @notice Initiates a task with conditions which Gelato will monitor and execute when conditions are met.\n     *\n     * @param execAddress Address of contract that should be called by Gelato.\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData}\n     * @param feeToken Address of token to be used as payment. Use address(0) if Gelato 1Balance is being used, 0xeeeeee... for ETH or native tokens.\n     *\n     * @return taskId Unique hash of the task created.\n     */\n    function createTask(\n        address execAddress,\n        bytes calldata execData,\n        LibDataTypes.ModuleData calldata moduleData,\n        address feeToken\n    ) external returns (bytes32 taskId);\n\n    /**\n     * @notice Terminates a task that was created and Gelato can no longer execute it.\n     *\n     * @param taskId Unique hash of the task that is being cancelled. {See LibTaskId-getTaskId}\n     */\n    function cancelTask(bytes32 taskId) external;\n\n    /**\n     * @notice Execution API called by Gelato, using Sync Fee as fee payment method\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called by Gelato.\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData}\n     * @param txFee Fee paid to Gelato for execution, transfered to Gelato.feeCollector().\n     * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n     * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations)\n     */\n    function exec(\n        address taskCreator,\n        address execAddress,\n        bytes memory execData,\n        LibDataTypes.ModuleData calldata moduleData,\n        uint256 txFee,\n        address feeToken,\n        bool revertOnFailure\n    ) external;\n\n    /**\n     * @notice Execution API called by Gelato, using Gelato 1Balance as fee payment method.\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called by Gelato.\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData}\n     * @param oneBalanceParam Parameters required for fee payment with Gelato 1Balance.\n     * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations)\n     */\n    function exec1Balance(\n        address taskCreator,\n        address execAddress,\n        bytes memory execData,\n        LibDataTypes.ModuleData calldata moduleData,\n        Gelato1BalanceParam calldata oneBalanceParam,\n        bool revertOnFailure\n    ) external;\n\n    /**\n     * @notice Execution API called by Gelato, using Gelato 1Balance as fee payment method.\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called by Gelato.\n     * @param taskId Unique hash of the task.\n     * @param correlationId Id of the execution to be used for 1Balance settlement.\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations)\n     * @param singleExec If the task is a SingleExec task. If true, task will be cancelled after execution.\n     */\n    function execBypassModule(\n        address taskCreator,\n        address execAddress,\n        bytes32 taskId,\n        bytes32 correlationId,\n        bytes memory execData,\n        bool revertOnFailure,\n        bool singleExec\n    ) external;\n\n    /**\n     * @notice Execution API called by Gelato, using Gelato Sync fee as fee payment method.\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called by Gelato.\n     * @param taskId Unique hash of the task.\n     * @param txFee Fee paid to Gelato for execution, transfered to Gelato.feeCollector().\n     * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations)\n     * @param singleExec If the task is a SingleExec task. If true, task will be cancelled after execution.\n     */\n    function execBypassModuleSyncFee(\n        address taskCreator,\n        address execAddress,\n        bytes32 taskId,\n        uint256 txFee,\n        address feeToken,\n        bytes memory execData,\n        bool revertOnFailure,\n        bool singleExec\n    ) external;\n\n    /**\n     * @notice Sets the address of task modules. Only callable by proxy admin.\n     *\n     * @param modules List of modules to be set\n     * @param moduleAddresses List of addresses for respective modules.\n     */\n    function setModule(\n        LibDataTypes.Module[] calldata modules,\n        address[] calldata moduleAddresses\n    ) external;\n\n    /**\n     * @notice Helper function to query fee and feeToken to be used for payment. (For executions which pays itself)\n     *\n     * @return uint256 Fee amount to be paid.\n     * @return address Token to be paid. (Determined and passed by taskCreator during createTask)\n     */\n    function getFeeDetails() external view returns (uint256, address);\n\n    /**\n     * @notice Helper func to query all open tasks by a task creator.\n     *\n     * @param taskCreator Address of task creator to query.\n     *\n     * @return bytes32[] List of taskIds created.\n     */\n    function getTaskIdsByUser(address taskCreator)\n        external\n        view\n        returns (bytes32[] memory);\n\n    /**\n     * @notice Helper function to compute task id with module arguments\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that will be called by Gelato.\n     * @param execSelector Signature of the function which will be called by Gelato.\n     * @param moduleData  Conditional modules that will be used. {See LibDataTypes-ModuleData}\n     * @param feeToken Address of token to be used as payment. Use address(0) if Gelato 1Balance is being used, 0xeeeeee... for ETH or native tokens.\n     */\n    function getTaskId(\n        address taskCreator,\n        address execAddress,\n        bytes4 execSelector,\n        LibDataTypes.ModuleData memory moduleData,\n        address feeToken\n    ) external pure returns (bytes32 taskId);\n}\n"
      },
      "contracts/interfaces/IGelato1Balance.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IGelato1Balance {\n    struct Gelato1BalanceParam {\n        address sponsor;\n        address feeToken;\n        uint256 oneBalanceChainId;\n        uint256 nativeToFeeTokenXRateNumerator;\n        uint256 nativeToFeeTokenXRateDenominator;\n        bytes32 correlationId;\n    }\n\n    event LogUseGelato1Balance(\n        address indexed sponsor,\n        address indexed target,\n        address indexed feeToken,\n        uint256 oneBalanceChainId,\n        uint256 nativeToFeeTokenXRateNumerator,\n        uint256 nativeToFeeTokenXRateDenominator,\n        bytes32 correlationId\n    );\n}\n"
      },
      "contracts/interfaces/ITaskModule.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\n// solhint-disable max-line-length\ninterface ITaskModule {\n    /**\n     * @notice Called before generating taskId.\n     * @dev Modules can override execAddress or taskCreator. {See ProxyModule-preCreateTask}\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called.\n     *\n     * @return address Overriden or original taskCreator.\n     * @return address Overriden or original execAddress.\n     */\n    function preCreateTask(address taskCreator, address execAddress)\n        external\n        returns (address, address);\n\n    /**\n     * @notice Initiates task module whenever `createTask` is being called.\n     *\n     * @param taskId Unique hash of the task created.\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called.\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     * @param initModuleArg Encoded arguments for module if any.\n     */\n    function onCreateTask(\n        bytes32 taskId,\n        address taskCreator,\n        address execAddress,\n        bytes calldata execData,\n        bytes calldata initModuleArg\n    ) external;\n\n    /**\n     * @notice Called before taskId is removed from _createdTasks[].\n     * @dev Modules can override taskCreator.\n     *\n     * @param taskId Unique hash of the task created.\n     * @param taskCreator The address which created the task.\n     *\n     * @return address Overriden or original taskCreator.\n     */\n    function preCancelTask(bytes32 taskId, address taskCreator)\n        external\n        returns (address);\n\n    /**\n     * @notice Called during `exec` and before execAddress is called.\n     *\n     * @param taskId Unique hash of the task created.\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called.\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     *\n     * @return address Overriden or original execution address.\n     * @return bytes Overriden or original execution data.\n     */\n    function preExecCall(\n        bytes32 taskId,\n        address taskCreator,\n        address execAddress,\n        bytes calldata execData\n    ) external returns (address, bytes memory);\n\n    /**\n     * @notice Called during `exec` and after execAddress is called.\n     *\n     * @param taskId Unique hash of the task created.\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that should be called.\n     * @param execData Execution data to be called with / function selector if execution data is yet to be determined.\n     */\n    function postExecCall(\n        bytes32 taskId,\n        address taskCreator,\n        address execAddress,\n        bytes calldata execData\n    ) external;\n}\n"
      },
      "contracts/libraries/LibBypassModule.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport {\n    EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {_call, _delegateCall} from \"../functions/FExec.sol\";\nimport {LibDataTypes} from \"./LibDataTypes.sol\";\nimport {LibEvents} from \"./LibEvents.sol\";\nimport {LibTaskModule} from \"./LibTaskModule.sol\";\nimport {LibTaskModuleConfig} from \"./LibTaskModuleConfig.sol\";\nimport {ITaskModule} from \"../interfaces/ITaskModule.sol\";\n\n// solhint-disable function-max-lines\n/// @notice Simplified library for task executions\nlibrary LibBypassModule {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n    using LibTaskModuleConfig for LibDataTypes.Module;\n\n    /**\n     * @notice Delegate calls SingleExecModule on exec for single exec tasks.\n     *\n     * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param _taskCreator Address which created the task.\n     * @param _execAddress Address of contract that will be called by Gelato.\n     * @param _execData Execution data to be called with / function selector.\n     * @param _revertOnFailure To revert or not if call to execAddress fails.\n     * @param _singleExec If task is a single exec task.\n     * @param _createdTasks The storage reference of owner to the taskIds created mapping.\n     */\n    function onExecTask(\n        bytes32 _taskId,\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execData,\n        bool _revertOnFailure,\n        bool _singleExec,\n        mapping(address => EnumerableSet.Bytes32Set) storage _createdTasks\n    ) internal returns (bool callSuccess) {\n        (callSuccess, ) = _call(\n            _execAddress,\n            abi.encodePacked(_execData, _taskCreator),\n            0,\n            _revertOnFailure,\n            \"Automate.exec: \"\n        );\n\n        if (_singleExec) {\n            _createdTasks[_taskCreator].remove(_taskId);\n            emit LibEvents.TaskCancelled(_taskId, _taskCreator);\n        }\n    }\n}\n"
      },
      "contracts/libraries/LibDataTypes.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\n// solhint-disable max-line-length\nlibrary LibDataTypes {\n    /**\n     * @notice Whitelisted modules that are available for users to customise conditions and specifications of their tasks.\n     *\n     * @param RESOLVER Use dynamic condition & input data for execution. {See ResolverModule.sol}\n     * @param DEPRECATED_TIME deprecated\n     * @param PROXY Creates a dedicated caller (msg.sender) to be used when executing the task. {See ProxyModule.sol}\n     * @param SINGLE_EXEC Task is cancelled after one execution. {See SingleExecModule.sol}\n     * @param WEB3_FUNCTION Use off-chain condition & input data for execution. {See Web3FunctionModule.sol}\n     * @param TRIGGER Repeated execution of task ata a specified timing and interval or cron. {See TriggerModule.sol}\n     */\n    enum Module {\n        RESOLVER,\n        DEPRECATED_TIME, // @deprecated\n        PROXY,\n        SINGLE_EXEC,\n        WEB3_FUNCTION,\n        TRIGGER\n    }\n\n    /**\n     * @notice Struct to contain modules and their relative arguments that are used for task creation.\n     *\n     * @param modules List of selected modules.\n     * @param args Arguments of modules if any. Pass \"0x\" for modules which does not require args {See encodeModuleArg}\n     */\n    struct ModuleData {\n        Module[] modules;\n        bytes[] args;\n    }\n\n    /**\n     * @notice Struct for time module.\n     *\n     * @param nextExec Time when the next execution should occur.\n     * @param interval Time interval between each execution.\n     */\n    struct Time {\n        uint128 nextExec;\n        uint128 interval;\n    }\n\n    /**\n     * @notice Types of trigger\n     *\n     * @param TIME Time triggered tasks, starting at a specific time and triggered intervally\n     * @param CRON Cron triggered tasks, triggered according to the cron conditions\n     */\n    enum TriggerType {\n        TIME,\n        CRON,\n        EVENT,\n        BLOCK\n    }\n\n    /**\n     * @notice Struct for trigger module\n     *\n     * @param triggerType Type of the trigger\n     * @param triggerConfig Trigger configuration that shuold be parsed according to triggerType\n     */\n    struct TriggerModuleData {\n        TriggerType triggerType;\n        bytes triggerConfig;\n    }\n}\n"
      },
      "contracts/libraries/LibEvents.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport {LibDataTypes} from \"./LibDataTypes.sol\";\n\nlibrary LibEvents {\n    /**\n     * @notice Emitted when `createTask` is called.\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that is called by Gelato.\n     * @param execDataOrSelector Execution data / function selector.\n     * @param moduleData Conditional modules used. {See LibDataTypes-ModuleData}\n     * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n     * @param taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     */\n    event TaskCreated(\n        address indexed taskCreator,\n        address indexed execAddress,\n        bytes execDataOrSelector,\n        LibDataTypes.ModuleData moduleData,\n        address feeToken,\n        bytes32 indexed taskId\n    );\n\n    /**\n     * @notice Emitted when `cancelTask` is called.\n     *\n     * @param taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param taskCreator The address which owned the task.\n     */\n    event TaskCancelled(bytes32 taskId, address taskCreator);\n\n    /**\n     * @notice Emitted when `exec` is called.\n     *\n     * @param txFee Fee paid to Gelato for execution\n     * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n     * @param execAddress Address of contract that will be called by Gelato.\n     * @param execData Execution data / function selector.\n     * @param taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param callSuccess Status of the call to execAddress.\n     */\n    event ExecSuccess(\n        uint256 indexed txFee,\n        address indexed feeToken,\n        address indexed execAddress,\n        bytes execData,\n        bytes32 taskId,\n        bool callSuccess\n    );\n\n    /**\n     * @notice Emitted when `execBypassModule` is called.\n     *\n     * @param taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param correlationId Id of the execution to be used for 1Balance settlement.\n     * @param callSuccess Status of the call to execAddress.\n     */\n    event ExecBypassModuleSuccess(\n        bytes32 taskId,\n        bytes32 correlationId,\n        bool callSuccess\n    );\n\n    /**\n     * @notice Emitted when `execBypassModuleSyncFee` is called.\n     *\n     * @param taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param txFee Fee paid to Gelato for execution\n     * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n     * @param callSuccess Status of the call to execAddress.\n     */\n    event ExecBypassModuleSyncFeeSuccess(\n        bytes32 taskId,\n        uint256 txFee,\n        address feeToken,\n        bool callSuccess\n    );\n}\n"
      },
      "contracts/libraries/LibTaskId.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {LibDataTypes} from \"./LibDataTypes.sol\";\n\n/**\n * @notice Library to compute taskId of tasks.\n */\n// solhint-disable max-line-length\nlibrary LibTaskId {\n    /**\n     * @notice Returns taskId of taskCreator.\n     *\n     * @param taskCreator The address which created the task.\n     * @param execAddress Address of contract that will be called by Gelato.\n     * @param execSelector Signature of the function which will be called by Gelato.\n     * @param moduleData  Conditional modules that will be used. {See LibDataTypes-ModuleData}\n     * @param feeToken Address of token to be used as payment. Use address(0) if Gelato 1Balance is being used, 0xeeeeee... for ETH or native tokens.\n     */\n    function getTaskId(\n        address taskCreator,\n        address execAddress,\n        bytes4 execSelector,\n        LibDataTypes.ModuleData memory moduleData,\n        address feeToken\n    ) internal pure returns (bytes32 taskId) {\n        taskId = keccak256(\n            abi.encode(\n                taskCreator,\n                execAddress,\n                execSelector,\n                moduleData,\n                feeToken\n            )\n        );\n    }\n}\n"
      },
      "contracts/libraries/LibTaskModule.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport {_call, _delegateCall} from \"../functions/FExec.sol\";\nimport {LibDataTypes} from \"./LibDataTypes.sol\";\nimport {LibTaskModuleConfig} from \"./LibTaskModuleConfig.sol\";\nimport {ITaskModule} from \"../interfaces/ITaskModule.sol\";\n\n// solhint-disable function-max-lines\n/// @notice Library to call task modules on task creation and execution.\nlibrary LibTaskModule {\n    using LibTaskModuleConfig for LibDataTypes.Module;\n\n    /**\n     * @notice Delegate calls task modules before generating taskId.\n     *\n     * @param _execAddress Address of contract that will be called by Gelato.\n     * @param _taskCreator The address which created the task.\n     * @param taskModuleAddresses The storage reference to the mapping of modules to their address.\n     */\n    function preCreateTask(\n        address _taskCreator,\n        address _execAddress,\n        mapping(LibDataTypes.Module => address) storage taskModuleAddresses\n    ) internal returns (address, address) {\n        uint256 length = uint256(type(LibDataTypes.Module).max) + 1;\n\n        for (uint256 i; i < length; i++) {\n            LibDataTypes.Module module = LibDataTypes.Module(i);\n            if (!module.requirePreCreate()) continue;\n\n            address moduleAddress = taskModuleAddresses[module];\n            _moduleInitialised(moduleAddress);\n\n            bytes memory delegatecallData = abi.encodeWithSelector(\n                ITaskModule.preCreateTask.selector,\n                _taskCreator,\n                _execAddress\n            );\n\n            (, bytes memory returnData) = _delegateCall(\n                moduleAddress,\n                delegatecallData,\n                \"Automate.preCreateTask: \"\n            );\n\n            (_taskCreator, _execAddress) = abi.decode(\n                returnData,\n                (address, address)\n            );\n        }\n\n        return (_taskCreator, _execAddress);\n    }\n\n    /**\n     * @notice Delegate calls task modules on create task to initialise them.\n     *\n     * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param _taskCreator The address which created the task.\n     * @param _execAddress Address of contract that will be called by Gelato.\n     * @param _execData Execution data to be called with / function selector.\n     * @param _moduleData Modules that will be used for the task. {See LibDataTypes-ModuleData}\n     * @param taskModuleAddresses The storage reference to the mapping of modules to their address.\n     */\n    function onCreateTask(\n        bytes32 _taskId,\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execData,\n        LibDataTypes.ModuleData memory _moduleData,\n        mapping(LibDataTypes.Module => address) storage taskModuleAddresses\n    ) internal {\n        uint256 length = _moduleData.modules.length;\n\n        _validModules(_moduleData.modules);\n\n        for (uint256 i; i < length; i++) {\n            LibDataTypes.Module module = _moduleData.modules[i];\n            if (!module.requireOnCreate()) continue;\n\n            address moduleAddress = taskModuleAddresses[module];\n            _moduleInitialised(moduleAddress);\n\n            bytes memory delegatecallData = abi.encodeWithSelector(\n                ITaskModule.onCreateTask.selector,\n                _taskId,\n                _taskCreator,\n                _execAddress,\n                _execData,\n                _moduleData.args[i]\n            );\n\n            _delegateCall(\n                moduleAddress,\n                delegatecallData,\n                \"Automate.onCreateTask: \"\n            );\n        }\n    }\n\n    /**\n     * @notice Delegate calls task modules before removing task.\n     *\n     * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param _taskCreator The address which created the task.\n     * @param taskModuleAddresses The storage reference to the mapping of modules to their address.\n     */\n    function preCancelTask(\n        bytes32 _taskId,\n        address _taskCreator,\n        mapping(LibDataTypes.Module => address) storage taskModuleAddresses\n    ) internal returns (address) {\n        uint256 length = uint256(type(LibDataTypes.Module).max);\n\n        for (uint256 i; i <= length; i++) {\n            LibDataTypes.Module module = LibDataTypes.Module(i);\n\n            if (!module.requirePreCancel()) continue;\n\n            address moduleAddress = taskModuleAddresses[module];\n            _moduleInitialised(moduleAddress);\n\n            bytes memory delegatecallData = abi.encodeWithSelector(\n                ITaskModule.preCancelTask.selector,\n                _taskId,\n                _taskCreator\n            );\n\n            (, bytes memory returnData) = _delegateCall(\n                moduleAddress,\n                delegatecallData,\n                \"Automate.preCancelTask: \"\n            );\n\n            (_taskCreator) = abi.decode(returnData, (address));\n        }\n\n        return _taskCreator;\n    }\n\n    /**\n     * @notice Delegate calls task modules on exec.\n     *\n     * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId}\n     * @param _taskCreator Address which created the task.\n     * @param _execAddress Address of contract that will be called by Gelato.\n     * @param _execData Execution data to be called with / function selector.\n     * @param _modules Modules that is used for the task. {See LibDataTypes-Module}\n     * @param _revertOnFailure To revert or not if call to execAddress fails.\n     * @param taskModuleAddresses The storage reference to the mapping of modules to their address.\n     */\n    function onExecTask(\n        bytes32 _taskId,\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execData,\n        LibDataTypes.Module[] memory _modules,\n        bool _revertOnFailure,\n        mapping(LibDataTypes.Module => address) storage taskModuleAddresses\n    ) internal returns (bool callSuccess) {\n        address[] memory moduleAddresses = _getModuleAddresses(\n            _modules,\n            taskModuleAddresses\n        );\n\n        (_execAddress, _execData) = preExecCall(\n            _taskId,\n            _taskCreator,\n            _execAddress,\n            _execData,\n            _modules,\n            moduleAddresses\n        );\n\n        (callSuccess, ) = _call(\n            _execAddress,\n            abi.encodePacked(_execData, _taskCreator),\n            0,\n            _revertOnFailure,\n            \"Automate.exec: \"\n        );\n\n        postExecCall(\n            _taskId,\n            _taskCreator,\n            _execAddress,\n            _execData,\n            _modules,\n            moduleAddresses\n        );\n    }\n\n    function preExecCall(\n        bytes32 _taskId,\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execData,\n        LibDataTypes.Module[] memory _modules,\n        address[] memory _moduleAddresses\n    ) internal returns (address, bytes memory) {\n        uint256 length = _modules.length;\n\n        for (uint256 i; i < length; i++) {\n            if (!_modules[i].requirePreExec()) continue;\n\n            bytes memory delegatecallData = abi.encodeWithSelector(\n                ITaskModule.preExecCall.selector,\n                _taskId,\n                _taskCreator,\n                _execAddress,\n                _execData\n            );\n\n            (, bytes memory returnData) = _delegateCall(\n                _moduleAddresses[i],\n                delegatecallData,\n                \"Automate.preExecCall: \"\n            );\n\n            (_execAddress, _execData) = abi.decode(\n                returnData,\n                (address, bytes)\n            );\n        }\n        return (_execAddress, _execData);\n    }\n\n    function postExecCall(\n        bytes32 _taskId,\n        address _taskCreator,\n        address _execAddress,\n        bytes memory _execData,\n        LibDataTypes.Module[] memory _modules,\n        address[] memory _moduleAddresses\n    ) internal {\n        uint256 length = _moduleAddresses.length;\n\n        for (uint256 i; i < length; i++) {\n            if (!_modules[i].requirePostExec()) continue;\n\n            bytes memory delegatecallData = abi.encodeWithSelector(\n                ITaskModule.postExecCall.selector,\n                _taskId,\n                _taskCreator,\n                _execAddress,\n                _execData\n            );\n\n            _delegateCall(\n                _moduleAddresses[i],\n                delegatecallData,\n                \"Automate.postExecCall: \"\n            );\n        }\n    }\n\n    function _getModuleAddresses(\n        LibDataTypes.Module[] memory _modules,\n        mapping(LibDataTypes.Module => address) storage taskModuleAddresses\n    ) private view returns (address[] memory) {\n        uint256 length = _modules.length;\n        address[] memory moduleAddresses = new address[](length);\n\n        for (uint256 i; i < length; i++) {\n            moduleAddresses[i] = taskModuleAddresses[_modules[i]];\n        }\n\n        return moduleAddresses;\n    }\n\n    function _moduleInitialised(address _moduleAddress) private pure {\n        require(\n            _moduleAddress != address(0),\n            \"Automate._moduleInitialised: Not init\"\n        );\n    }\n\n    /**\n     * @dev\n     * - No duplicate modules\n     * - No deprecated TIME\n     * - No RESOLVER && WEB3_FUNCTION\n     * - PROXY is required\n     */\n    function _validModules(LibDataTypes.Module[] memory _modules) private pure {\n        uint256 length = _modules.length;\n\n        uint256 existsLength = uint256(type(LibDataTypes.Module).max) + 1;\n        bool[] memory exists = new bool[](existsLength);\n\n        for (uint256 i = 0; i < length; i++) {\n            if (i > 0) {\n                require(\n                    _modules[i] > _modules[i - 1],\n                    \"Automate._validModules: Asc only\"\n                );\n            }\n\n            exists[uint256(_modules[i])] = true;\n        }\n\n        require(\n            !exists[uint256(LibDataTypes.Module.DEPRECATED_TIME)],\n            \"Automate._validModules: TIME is deprecated\"\n        );\n\n        require(\n            !(exists[uint256(LibDataTypes.Module.RESOLVER)] &&\n                exists[uint256(LibDataTypes.Module.WEB3_FUNCTION)]),\n            \"Automate._validModules: Only RESOLVER or WEB3_FUNCTION\"\n        );\n\n        require(\n            exists[uint256(LibDataTypes.Module.PROXY)],\n            \"Automate._validModules: PROXY is required\"\n        );\n    }\n}\n"
      },
      "contracts/libraries/LibTaskModuleConfig.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport {LibDataTypes} from \"./LibDataTypes.sol\";\n\n/**\n * @notice Library to determine wether to call task modules to reduce unnecessary calls.\n */\nlibrary LibTaskModuleConfig {\n    function requirePreCreate(LibDataTypes.Module _module)\n        internal\n        pure\n        returns (bool)\n    {\n        if (_module == LibDataTypes.Module.PROXY) return true;\n\n        return false;\n    }\n\n    function requirePreCancel(LibDataTypes.Module _module)\n        internal\n        pure\n        returns (bool)\n    {\n        if (_module == LibDataTypes.Module.PROXY) return true;\n\n        return false;\n    }\n\n    function requireOnCreate(LibDataTypes.Module _module)\n        internal\n        pure\n        returns (bool)\n    {\n        if (_module == LibDataTypes.Module.PROXY) return true;\n\n        return false;\n    }\n\n    function requirePreExec(LibDataTypes.Module _module)\n        internal\n        pure\n        returns (bool)\n    {\n        if (_module == LibDataTypes.Module.PROXY) return true;\n\n        return false;\n    }\n\n    function requirePostExec(LibDataTypes.Module _module)\n        internal\n        pure\n        returns (bool)\n    {\n        if (_module == LibDataTypes.Module.SINGLE_EXEC) return true;\n\n        return false;\n    }\n}\n"
      },
      "contracts/vendor/gelato/GelatoBytes.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n    function calldataSliceSelector(bytes calldata _bytes)\n        internal\n        pure\n        returns (bytes4 selector)\n    {\n        selector =\n            _bytes[0] |\n            (bytes4(_bytes[1]) >> 8) |\n            (bytes4(_bytes[2]) >> 16) |\n            (bytes4(_bytes[3]) >> 24);\n    }\n\n    function memorySliceSelector(bytes memory _bytes)\n        internal\n        pure\n        returns (bytes4 selector)\n    {\n        selector =\n            _bytes[0] |\n            (bytes4(_bytes[1]) >> 8) |\n            (bytes4(_bytes[2]) >> 16) |\n            (bytes4(_bytes[3]) >> 24);\n    }\n\n    function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n        internal\n        pure\n    {\n        // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n        if (_bytes.length % 32 == 4) {\n            bytes4 selector;\n            assembly {\n                selector := mload(add(0x20, _bytes))\n            }\n            if (selector == 0x08c379a0) {\n                // Function selector for Error(string)\n                assembly {\n                    _bytes := add(_bytes, 68)\n                }\n                revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n            } else {\n                revert(\n                    string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n                );\n            }\n        } else {\n            revert(\n                string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n            );\n        }\n    }\n\n    function returnError(bytes memory _bytes, string memory _tracingInfo)\n        internal\n        pure\n        returns (string memory)\n    {\n        // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n        if (_bytes.length % 32 == 4) {\n            bytes4 selector;\n            assembly {\n                selector := mload(add(0x20, _bytes))\n            }\n            if (selector == 0x08c379a0) {\n                // Function selector for Error(string)\n                assembly {\n                    _bytes := add(_bytes, 68)\n                }\n                return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n            } else {\n                return\n                    string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n            }\n        } else {\n            return\n                string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n        }\n    }\n}\n"
      },
      "contracts/vendor/gelato/Gelatofied.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n    SafeERC20,\n    IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"../../functions/FUtils.sol\";\n\nabstract contract Gelatofied {\n    address payable public immutable gelato;\n\n    modifier gelatofy(uint256 _amount, address _paymentToken) {\n        require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n        _;\n        _transfer(gelato, _paymentToken, _amount);\n    }\n\n    modifier onlyGelato() {\n        require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n        _;\n    }\n\n    constructor(address payable _gelato) {\n        gelato = _gelato;\n    }\n}\n"
      },
      "contracts/vendor/proxy/EIP173/Proxied.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n    /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n    /// It also allows these functions to be called inside a contructor\n    /// even if the contract is meant to be used without proxy\n    modifier proxied() {\n        address proxyAdminAddress = _proxyAdmin();\n        // With hardhat-deploy proxies\n        // the proxyAdminAddress is zero only for the implementation contract\n        // if the implementation contract want to be used as a standalone/immutable contract\n        // it simply has to execute the `proxied` function\n        // This ensure the proxyAdminAddress is never zero post deployment\n        // And allow you to keep the same code for both proxied contract and immutable contract\n        if (proxyAdminAddress == address(0)) {\n            // ensure can not be called twice when used outside of proxy : no admin\n            // solhint-disable-next-line security/no-inline-assembly\n            assembly {\n                sstore(\n                    0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n                    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n                )\n            }\n        } else {\n            require(msg.sender == proxyAdminAddress);\n        }\n        _;\n    }\n\n    modifier onlyProxyAdmin() {\n        require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n        _;\n    }\n\n    function _proxyAdmin() internal view returns (address adminAddress) {\n        // solhint-disable-next-line security/no-inline-assembly\n        assembly {\n            adminAddress := sload(\n                0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n            )\n        }\n    }\n}\n"
      }
    }
  }}