{"action":"created","comment":{"url":"https://api.github.com/repos/solettaproject/soletta/pulls/comments/46875656","id":46875656,"diff_hunk":"@@ -480,6 +480,181 @@ int sol_json_token_get_unescaped_string(const struct sol_json_token *token, stru\n char *sol_json_token_get_unescaped_string_copy(const struct sol_json_token *value);\n \n /**\n+ * @brief Get the value of the JSON Object child element pointed by @a key_slice.\n+ *\n+ * @param scanner An initialized scanner, which is pointing to a JSON Object.\n+ * @param key_slice The key of the desired element.\n+ * @param value A pointer to the structure that will be filled with the value\n+ *        of the element pointed by @a key_slice.\n+ *\n+ * @return If any parameter is invalid, or if @a scanner is not pointing to a\n+ *         JSON Object, return -EINVAL. If @a key_slice is not present in the\n+ *         JSON Object, -ENOENT. If @a key was found, and @a value was update\n+ *         successfully with the value pointed by @a key, return 0.\n+ *\n+ * @see sol_json_array_get_at_index()\n+ */\n+int sol_json_object_get_key(struct sol_json_scanner *scanner, const struct sol_str_slice key_slice, struct sol_json_token *value);\n+\n+/**\n+ * @brief Get the element in position @a i in JSON Array pointed by @a scanner\n+ *\n+ * @param scanner An initialized scanner, which is pointing to a JSON Array.\n+ * @param value A pointer to the structure that will be filled with the value\n+ *        of the element at position @a i.\n+ * @param i The position of the desired element.\n+ *\n+ * @return If any parameter is invalid, or if @a scanner is not pointing to a\n+ *         JSON Array, return -EINVAL. If @a i is larger than the array's\n+ *         length, -ENOENT. If @a value was updated successfully with the value\n+ *         in position @a i, return 0.\n+ *\n+ * @see sol_json_object_get_key()\n+ */\n+int sol_json_array_get_at_index(struct sol_json_scanner *scanner, uint16_t i, struct sol_json_token *value);\n+\n+/**\n+ * @struct sol_json_path_scanner\n+ *\n+ * @brief Scanner used to go through segments of a JSON Path.\n+ *\n+ * @note JSONPath syntax is available at http://goessner.net/articles/JsonPath/.\n+ *\n+ * @see sol_json_path_scanner_init()\n+ * @see sol_json_path_get_next_segment()\n+ * @see SOL_JSON_PATH_FOREACH()\n+ */\n+struct sol_json_path_scanner {\n+    const char *path; /**< @brief The JSONPath string. */\n+    const char *end; /**< @brief Points to last character from path. */\n+    /**\n+     * @brief Points to last visited position from path and the beginning of\n+     * next segment.\n+     */\n+    const char *current;\n+};\n+\n+/**\n+ * @brief Get the element pointed by the JSON Path @a path in @a scanner.\n+ *\n+ * @param scanner An initialized scanner, which is pointing to a JSON Object\n+ *        or a JSON Array.\n+ * @param path The JSON Path of the desired element.\n+ * @param value A pointer to the structure that will be filled with the value\n+ *        of the element pointed by @a path.\n+ *\n+ * @return If any parameter is invalid, or if @a scanner is not pointing to a\n+ *         JSON Object or JSON Array, or if @a path is not a valid JSON Path,\n+ *         return -EINVAL. If @a path is pointing to an invalid position in a\n+ *         JSON Object or in a JSON Array, -ENOENT. If @a value was\n+ *         successfully updated with the value of the element pointed by @a\n+ *         path, return 0.\n+ *\n+ * @see sol_json_path_scanner\n+ */\n+int sol_json_get_path(struct sol_json_scanner *scanner, struct sol_str_slice path, struct sol_json_token *value);\n+\n+/**\n+ * @brief Initialize a JSON Path @a scanner with @a path.\n+ *\n+ * JSON path scanner can be used to go through segments of a JSON Path using\n+ * SOL_JSON_PATH_FOREACH() or sol_json_path_get_next_segment() functions.\n+ *\n+ * @param scanner An uninitialized JSON Path scanner.\n+ * @param path A valid JSON Path string.\n+ *\n+ * @return 0 on success, -EINVAL if scanner is NULL.\n+ *\n+ * @see sol_json_path_scanner\n+ */\n+int sol_json_path_scanner_init(struct sol_json_path_scanner *scanner, struct sol_str_slice path) SOL_ATTR_NONNULL(1);\n+\n+/**\n+ * @brief Get next segment from JSON Path in @a scanner.\n+ *\n+ * Update @a slice with the next valid JSON Path segment in @a scanner.\n+ *\n+ * @param scanner An initialized JSON Path scanner.\n+ * @param slice A pointer to the slicer structure to be filled with next\n+ *        JSON Path segment.\n+ * @param end_reason A pointer to the field to be filled with the reason this\n+ *        function termination. SOL_JSON_LOOP_REASON_INVALID if an error\n+ *        occured when parsing the JSON Path. SOL_JSON_LOOP_REASON_OK if the\n+ *        next segment was updated in @a slice or if there is no more segments\n+ *        in this JSON Path.\n+ *\n+ * @return True if next segment was updated in @a value. False if an error\n+ *         ocurred or if there is no more segments available.\n+ */\n+bool sol_json_path_get_next_segment(struct sol_json_path_scanner *scanner, struct sol_str_slice *slice, enum sol_json_loop_reason *end_reason) SOL_ATTR_NONNULL(1, 2, 3);\n+\n+/**\n+ * @brief Get the integer index from a JSON Path array segment.\n+ *\n+ * This function expects a valid JSON Path segment with format: [NUMBER],\n+ * where NUMBER is an integer and returns NUMBER converted to an integer\n+ * variable.\n+ *\n+ * @param key The key to extract the integer index.\n+ *\n+ * @return If key is a valid array segment in the format expecified,\n+ *         returns the converted index. If key is invalid, returns\n+ *         -EINVAL and if number is out of range, returns -ERANGE.\n+ */\n+int32_t sol_json_path_array_get_segment_index(struct sol_str_slice key);\n+\n+/**\n+ * @brief Check if @a slice is a valid JSON Path array segment.\n+ *\n+ * @param slice A JSON Path segment.\n+ *\n+ * @return True if @a slice is a valid JSON Path array segment. False\n+ *         otherwise.\n+ */\n+static inline bool\n+sol_json_path_is_array_key(struct sol_str_slice slice)\n+{\n+    return slice.data && slice.len >= 2 &&\n+           slice.data[0] == '[' &&  //is between brackets or\n+           slice.data[1] != '\\''; //index is not a string\n+}\n+\n+/**\n+ * @def SOL_JSON_PATH_FOREACH(scanner, key, end_reason)\n+ *\n+ * @brief Go through all segments of a JSON Path.\n+ *\n+ * @param scanner An initialized struct sol_json_path_scanner.\n+ * @param key A pointer to struct sol_str_slice, that is going to be filled\n+ *        with the current key being visited.\n+ * @param end_reason A pointer to the field to be filled with the reason this\n+ *        macro termination. SOL_JSON_LOOP_REASON_INVALID if an error\n+ *        occured when parsing the JSON Path. SOL_JSON_LOOP_REASON_OK if\n+ *        we reached the end of the JSON Path.\n+ *\n+ * Usage example:\n+ * @code\n+ *\n+ * struct sol_json_path_scanner path_scanner;\n+ * enum sol_json_loop_reason reason;\n+ * struct sol_str_slice key_slice;\n+ *\n+ * sol_json_path_scanner_init(&path_scanner, path);\n+ * SOL_JSON_PATH_FOREACH(path_scanner, key_slice, reason) {\n+ *     //Do something\n+ * }\n+ *\n+ * if (end_reason != SOL_JSON_LOOP_REASON_OK) {\n+ *     //Error Handling\n+ * }\n+ *\n+ * @endcode","path":"src/lib/parsers/include/sol-json.h","position":172,"original_position":172,"commit_id":"fedd6e0e27af040d58fed7b18d4b6ba7b504d498","original_commit_id":"fedd6e0e27af040d58fed7b18d4b6ba7b504d498","user":{"login":"otaviobp","id":36560,"avatar_url":"https://avatars.githubusercontent.com/u/36560?v=3","gravatar_id":"","url":"https://api.github.com/users/otaviobp","html_url":"https://github.com/otaviobp","followers_url":"https://api.github.com/users/otaviobp/followers","following_url":"https://api.github.com/users/otaviobp/following{/other_user}","gists_url":"https://api.github.com/users/otaviobp/gists{/gist_id}","starred_url":"https://api.github.com/users/otaviobp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/otaviobp/subscriptions","organizations_url":"https://api.github.com/users/otaviobp/orgs","repos_url":"https://api.github.com/users/otaviobp/repos","events_url":"https://api.github.com/users/otaviobp/events{/privacy}","received_events_url":"https://api.github.com/users/otaviobp/received_events","type":"User","site_admin":false},"body":"Good.","created_at":"2015-12-07T20:54:28Z","updated_at":"2015-12-07T20:54:28Z","html_url":"https://github.com/solettaproject/soletta/pull/1162#discussion_r46875656","pull_request_url":"https://api.github.com/repos/solettaproject/soletta/pulls/1162","_links":{"self":{"href":"https://api.github.com/repos/solettaproject/soletta/pulls/comments/46875656"},"html":{"href":"https://github.com/solettaproject/soletta/pull/1162#discussion_r46875656"},"pull_request":{"href":"https://api.github.com/repos/solettaproject/soletta/pulls/1162"}}},"pull_request":{"url":"https://api.github.com/repos/solettaproject/soletta/pulls/1162","id":52887814,"html_url":"https://github.com/solettaproject/soletta/pull/1162","diff_url":"https://github.com/solettaproject/soletta/pull/1162.diff","patch_url":"https://github.com/solettaproject/soletta/pull/1162.patch","issue_url":"https://api.github.com/repos/solettaproject/soletta/issues/1162","number":1162,"state":"open","locked":false,"title":"json: Export JSON Path API","user":{"login":"otaviobp","id":36560,"avatar_url":"https://avatars.githubusercontent.com/u/36560?v=3","gravatar_id":"","url":"https://api.github.com/users/otaviobp","html_url":"https://github.com/otaviobp","followers_url":"https://api.github.com/users/otaviobp/followers","following_url":"https://api.github.com/users/otaviobp/following{/other_user}","gists_url":"https://api.github.com/users/otaviobp/gists{/gist_id}","starred_url":"https://api.github.com/users/otaviobp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/otaviobp/subscriptions","organizations_url":"https://api.github.com/users/otaviobp/orgs","repos_url":"https://api.github.com/users/otaviobp/repos","events_url":"https://api.github.com/users/otaviobp/events{/privacy}","received_events_url":"https://api.github.com/users/otaviobp/received_events","type":"User","site_admin":false},"body":"Export API to handle JSON Path strings and to get an element from a JSON\nArray or an JSON Object using a JSON Path string.\n\nThis code was private in json flow node, but it may be usefull to export\nit.\n\n@edersondisouza, as you are a possible user, can you review that?\n\nSigned-off-by: Otavio Pontes <otavio.pontes@intel.com>","created_at":"2015-12-07T19:18:58Z","updated_at":"2015-12-07T20:54:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2b67470019aed8606e8be4b9bad47fa89a86023e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/solettaproject/soletta/pulls/1162/commits","review_comments_url":"https://api.github.com/repos/solettaproject/soletta/pulls/1162/comments","review_comment_url":"https://api.github.com/repos/solettaproject/soletta/pulls/comments{/number}","comments_url":"https://api.github.com/repos/solettaproject/soletta/issues/1162/comments","statuses_url":"https://api.github.com/repos/solettaproject/soletta/statuses/fedd6e0e27af040d58fed7b18d4b6ba7b504d498","head":{"label":"otaviobp:json_path","ref":"json_path","sha":"fedd6e0e27af040d58fed7b18d4b6ba7b504d498","user":{"login":"otaviobp","id":36560,"avatar_url":"https://avatars.githubusercontent.com/u/36560?v=3","gravatar_id":"","url":"https://api.github.com/users/otaviobp","html_url":"https://github.com/otaviobp","followers_url":"https://api.github.com/users/otaviobp/followers","following_url":"https://api.github.com/users/otaviobp/following{/other_user}","gists_url":"https://api.github.com/users/otaviobp/gists{/gist_id}","starred_url":"https://api.github.com/users/otaviobp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/otaviobp/subscriptions","organizations_url":"https://api.github.com/users/otaviobp/orgs","repos_url":"https://api.github.com/users/otaviobp/repos","events_url":"https://api.github.com/users/otaviobp/events{/privacy}","received_events_url":"https://api.github.com/users/otaviobp/received_events","type":"User","site_admin":false},"repo":{"id":37671839,"name":"soletta","full_name":"otaviobp/soletta","owner":{"login":"otaviobp","id":36560,"avatar_url":"https://avatars.githubusercontent.com/u/36560?v=3","gravatar_id":"","url":"https://api.github.com/users/otaviobp","html_url":"https://github.com/otaviobp","followers_url":"https://api.github.com/users/otaviobp/followers","following_url":"https://api.github.com/users/otaviobp/following{/other_user}","gists_url":"https://api.github.com/users/otaviobp/gists{/gist_id}","starred_url":"https://api.github.com/users/otaviobp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/otaviobp/subscriptions","organizations_url":"https://api.github.com/users/otaviobp/orgs","repos_url":"https://api.github.com/users/otaviobp/repos","events_url":"https://api.github.com/users/otaviobp/events{/privacy}","received_events_url":"https://api.github.com/users/otaviobp/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/otaviobp/soletta","description":"Soletta Project is a framework for making IoT devices.  With Soletta Project's libraries developers can easily write software for devices that control actuators/sensors and communicate using standard technologies. It enables adding smartness even on the smallest edge devices.  ","fork":true,"url":"https://api.github.com/repos/otaviobp/soletta","forks_url":"https://api.github.com/repos/otaviobp/soletta/forks","keys_url":"https://api.github.com/repos/otaviobp/soletta/keys{/key_id}","collaborators_url":"https://api.github.com/repos/otaviobp/soletta/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/otaviobp/soletta/teams","hooks_url":"https://api.github.com/repos/otaviobp/soletta/hooks","issue_events_url":"https://api.github.com/repos/otaviobp/soletta/issues/events{/number}","events_url":"https://api.github.com/repos/otaviobp/soletta/events","assignees_url":"https://api.github.com/repos/otaviobp/soletta/assignees{/user}","branches_url":"https://api.github.com/repos/otaviobp/soletta/branches{/branch}","tags_url":"https://api.github.com/repos/otaviobp/soletta/tags","blobs_url":"https://api.github.com/repos/otaviobp/soletta/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/otaviobp/soletta/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/otaviobp/soletta/git/refs{/sha}","trees_url":"https://api.github.com/repos/otaviobp/soletta/git/trees{/sha}","statuses_url":"https://api.github.com/repos/otaviobp/soletta/statuses/{sha}","languages_url":"https://api.github.com/repos/otaviobp/soletta/languages","stargazers_url":"https://api.github.com/repos/otaviobp/soletta/stargazers","contributors_url":"https://api.github.com/repos/otaviobp/soletta/contributors","subscribers_url":"https://api.github.com/repos/otaviobp/soletta/subscribers","subscription_url":"https://api.github.com/repos/otaviobp/soletta/subscription","commits_url":"https://api.github.com/repos/otaviobp/soletta/commits{/sha}","git_commits_url":"https://api.github.com/repos/otaviobp/soletta/git/commits{/sha}","comments_url":"https://api.github.com/repos/otaviobp/soletta/comments{/number}","issue_comment_url":"https://api.github.com/repos/otaviobp/soletta/issues/comments{/number}","contents_url":"https://api.github.com/repos/otaviobp/soletta/contents/{+path}","compare_url":"https://api.github.com/repos/otaviobp/soletta/compare/{base}...{head}","merges_url":"https://api.github.com/repos/otaviobp/soletta/merges","archive_url":"https://api.github.com/repos/otaviobp/soletta/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/otaviobp/soletta/downloads","issues_url":"https://api.github.com/repos/otaviobp/soletta/issues{/number}","pulls_url":"https://api.github.com/repos/otaviobp/soletta/pulls{/number}","milestones_url":"https://api.github.com/repos/otaviobp/soletta/milestones{/number}","notifications_url":"https://api.github.com/repos/otaviobp/soletta/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/otaviobp/soletta/labels{/name}","releases_url":"https://api.github.com/repos/otaviobp/soletta/releases{/id}","created_at":"2015-06-18T16:42:28Z","updated_at":"2015-06-18T16:42:29Z","pushed_at":"2015-12-07T19:18:57Z","git_url":"git://github.com/otaviobp/soletta.git","ssh_url":"git@github.com:otaviobp/soletta.git","clone_url":"https://github.com/otaviobp/soletta.git","svn_url":"https://github.com/otaviobp/soletta","homepage":"","size":10289,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"solettaproject:master","ref":"master","sha":"3172bee5d9d3c9d328efa41b1d3f5c6c5243c6c4","user":{"login":"solettaproject","id":12736897,"avatar_url":"https://avatars.githubusercontent.com/u/12736897?v=3","gravatar_id":"","url":"https://api.github.com/users/solettaproject","html_url":"https://github.com/solettaproject","followers_url":"https://api.github.com/users/solettaproject/followers","following_url":"https://api.github.com/users/solettaproject/following{/other_user}","gists_url":"https://api.github.com/users/solettaproject/gists{/gist_id}","starred_url":"https://api.github.com/users/solettaproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solettaproject/subscriptions","organizations_url":"https://api.github.com/users/solettaproject/orgs","repos_url":"https://api.github.com/users/solettaproject/repos","events_url":"https://api.github.com/users/solettaproject/events{/privacy}","received_events_url":"https://api.github.com/users/solettaproject/received_events","type":"Organization","site_admin":false},"repo":{"id":37087063,"name":"soletta","full_name":"solettaproject/soletta","owner":{"login":"solettaproject","id":12736897,"avatar_url":"https://avatars.githubusercontent.com/u/12736897?v=3","gravatar_id":"","url":"https://api.github.com/users/solettaproject","html_url":"https://github.com/solettaproject","followers_url":"https://api.github.com/users/solettaproject/followers","following_url":"https://api.github.com/users/solettaproject/following{/other_user}","gists_url":"https://api.github.com/users/solettaproject/gists{/gist_id}","starred_url":"https://api.github.com/users/solettaproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solettaproject/subscriptions","organizations_url":"https://api.github.com/users/solettaproject/orgs","repos_url":"https://api.github.com/users/solettaproject/repos","events_url":"https://api.github.com/users/solettaproject/events{/privacy}","received_events_url":"https://api.github.com/users/solettaproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/solettaproject/soletta","description":"Soletta Project is a framework for making IoT devices.  With Soletta Project's libraries developers can easily write software for devices that control actuators/sensors and communicate using standard technologies. It enables adding smartness even on the smallest edge devices.  ","fork":false,"url":"https://api.github.com/repos/solettaproject/soletta","forks_url":"https://api.github.com/repos/solettaproject/soletta/forks","keys_url":"https://api.github.com/repos/solettaproject/soletta/keys{/key_id}","collaborators_url":"https://api.github.com/repos/solettaproject/soletta/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/solettaproject/soletta/teams","hooks_url":"https://api.github.com/repos/solettaproject/soletta/hooks","issue_events_url":"https://api.github.com/repos/solettaproject/soletta/issues/events{/number}","events_url":"https://api.github.com/repos/solettaproject/soletta/events","assignees_url":"https://api.github.com/repos/solettaproject/soletta/assignees{/user}","branches_url":"https://api.github.com/repos/solettaproject/soletta/branches{/branch}","tags_url":"https://api.github.com/repos/solettaproject/soletta/tags","blobs_url":"https://api.github.com/repos/solettaproject/soletta/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/solettaproject/soletta/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/solettaproject/soletta/git/refs{/sha}","trees_url":"https://api.github.com/repos/solettaproject/soletta/git/trees{/sha}","statuses_url":"https://api.github.com/repos/solettaproject/soletta/statuses/{sha}","languages_url":"https://api.github.com/repos/solettaproject/soletta/languages","stargazers_url":"https://api.github.com/repos/solettaproject/soletta/stargazers","contributors_url":"https://api.github.com/repos/solettaproject/soletta/contributors","subscribers_url":"https://api.github.com/repos/solettaproject/soletta/subscribers","subscription_url":"https://api.github.com/repos/solettaproject/soletta/subscription","commits_url":"https://api.github.com/repos/solettaproject/soletta/commits{/sha}","git_commits_url":"https://api.github.com/repos/solettaproject/soletta/git/commits{/sha}","comments_url":"https://api.github.com/repos/solettaproject/soletta/comments{/number}","issue_comment_url":"https://api.github.com/repos/solettaproject/soletta/issues/comments{/number}","contents_url":"https://api.github.com/repos/solettaproject/soletta/contents/{+path}","compare_url":"https://api.github.com/repos/solettaproject/soletta/compare/{base}...{head}","merges_url":"https://api.github.com/repos/solettaproject/soletta/merges","archive_url":"https://api.github.com/repos/solettaproject/soletta/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/solettaproject/soletta/downloads","issues_url":"https://api.github.com/repos/solettaproject/soletta/issues{/number}","pulls_url":"https://api.github.com/repos/solettaproject/soletta/pulls{/number}","milestones_url":"https://api.github.com/repos/solettaproject/soletta/milestones{/number}","notifications_url":"https://api.github.com/repos/solettaproject/soletta/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/solettaproject/soletta/labels{/name}","releases_url":"https://api.github.com/repos/solettaproject/soletta/releases{/id}","created_at":"2015-06-08T19:13:18Z","updated_at":"2015-11-30T20:47:12Z","pushed_at":"2015-12-07T20:43:05Z","git_url":"git://github.com/solettaproject/soletta.git","ssh_url":"git@github.com:solettaproject/soletta.git","clone_url":"https://github.com/solettaproject/soletta.git","svn_url":"https://github.com/solettaproject/soletta","homepage":"http://solettaproject.org","size":16268,"stargazers_count":56,"watchers_count":56,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":34,"mirror_url":null,"open_issues_count":56,"forks":34,"open_issues":56,"watchers":56,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/solettaproject/soletta/pulls/1162"},"html":{"href":"https://github.com/solettaproject/soletta/pull/1162"},"issue":{"href":"https://api.github.com/repos/solettaproject/soletta/issues/1162"},"comments":{"href":"https://api.github.com/repos/solettaproject/soletta/issues/1162/comments"},"review_comments":{"href":"https://api.github.com/repos/solettaproject/soletta/pulls/1162/comments"},"review_comment":{"href":"https://api.github.com/repos/solettaproject/soletta/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/solettaproject/soletta/pulls/1162/commits"},"statuses":{"href":"https://api.github.com/repos/solettaproject/soletta/statuses/fedd6e0e27af040d58fed7b18d4b6ba7b504d498"}}}}