{"thread":{"id":"56603","subject":"[PATCH 0/5] refs: remove long-dead code","startedAt":"2021-09-28T13:02:31Z","lastAt":"2021-09-28T22:12:38Z","messageCount":8,"participants":["Ævar Arnfjörð Bjarmason","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"437286","messageId":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","threadId":"56603","inReplyTo":null,"subject":"[PATCH 0/5] refs: remove long-dead code","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-28T13:02:19Z","receivedAt":"2021-09-28T13:02:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This removes dead code in the refs backend, mainly in the\nref-cache. By line count this is mostly a straightforward follow-up to\n9939b33d6a3 (packed-backend: rip out some now-unused code, 2017-09-08)\nand 9dd389f3d8d (packed_ref_store: get rid of the `ref_cache`\nentirely, 2017-09-25).\n\nÆvar Arnfjörð Bjarmason (5):\n  refs.[ch]: remove unused ref_storage_backend_exists()\n  refs/ref-cache.[ch]: remove unused remove_entry_from_dir()\n  refs/ref-cache.[ch]: remove unused add_ref_entry()\n  refs/ref-cache.c: remove \"mkdir\" parameter from find_containing_dir()\n  refs/ref-cache.[ch]: remove \"incomplete\" from create_dir_entry()\n\n refs.c               |  5 ---\n refs.h               |  2 -\n refs/files-backend.c |  6 +--\n refs/ref-cache.c     | 87 ++++++++------------------------------------\n refs/ref-cache.h     | 26 +------------\n 5 files changed, 19 insertions(+), 107 deletions(-)\n\n-- \n2.33.0.1340.ge9f77250f2b\n\n"},{"id":"437287","messageId":"patch-1.5-7a252061b51-20210928T130032Z-avarab@gmail.com","threadId":"56603","inReplyTo":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","subject":"[PATCH 1/5] refs.[ch]: remove unused ref_storage_backend_exists()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-28T13:02:20Z","receivedAt":"2021-09-28T13:02:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This function was added in 3dce444f178 (refs: add a backend method\nstructure, 2016-09-04), but has never been used by anything. The only\ncaller that might care uses find_ref_storage_backend() directly.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n refs.c | 5 -----\n refs.h | 2 --\n 2 files changed, 7 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex 8b9f7c3a80a..32349a5585f 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -33,11 +33,6 @@ static struct ref_storage_be *find_ref_storage_backend(const char *name)\n \treturn NULL;\n }\n \n-int ref_storage_backend_exists(const char *name)\n-{\n-\treturn find_ref_storage_backend(name) != NULL;\n-}\n-\n /*\n  * How to handle various characters in refnames:\n  * 0: An acceptable character for refs\ndiff --git a/refs.h b/refs.h\nindex 48970dfc7e0..573b69863d3 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -836,8 +836,6 @@ int reflog_expire(const char *refname, const struct object_id *oid,\n \t\t  reflog_expiry_cleanup_fn cleanup_fn,\n \t\t  void *policy_cb_data);\n \n-int ref_storage_backend_exists(const char *name);\n-\n struct ref_store *get_main_ref_store(struct repository *r);\n \n /**\n-- \n2.33.0.1340.ge9f77250f2b\n\n"},{"id":"437288","messageId":"patch-2.5-001a1335ab4-20210928T130032Z-avarab@gmail.com","threadId":"56603","inReplyTo":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","subject":"[PATCH 2/5] refs/ref-cache.[ch]: remove unused remove_entry_from_dir()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-28T13:02:21Z","receivedAt":"2021-09-28T13:02:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This function was missed in 9939b33d6a3 (packed-backend: rip out some\nnow-unused code, 2017-09-08), and has been orphaned since then. Let's\ndelete it.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n refs/ref-cache.c | 35 -----------------------------------\n refs/ref-cache.h | 16 ----------------\n 2 files changed, 51 deletions(-)\n\ndiff --git a/refs/ref-cache.c b/refs/ref-cache.c\nindex 49d732f6db9..e0feebf628f 100644\n--- a/refs/ref-cache.c\n+++ b/refs/ref-cache.c\n@@ -212,41 +212,6 @@ struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname)\n \treturn (entry->flag & REF_DIR) ? NULL : entry;\n }\n \n-int remove_entry_from_dir(struct ref_dir *dir, const char *refname)\n-{\n-\tint refname_len = strlen(refname);\n-\tint entry_index;\n-\tstruct ref_entry *entry;\n-\tint is_dir = refname[refname_len - 1] == '/';\n-\tif (is_dir) {\n-\t\t/*\n-\t\t * refname represents a reference directory.  Remove\n-\t\t * the trailing slash; otherwise we will get the\n-\t\t * directory *representing* refname rather than the\n-\t\t * one *containing* it.\n-\t\t */\n-\t\tchar *dirname = xmemdupz(refname, refname_len - 1);\n-\t\tdir = find_containing_dir(dir, dirname, 0);\n-\t\tfree(dirname);\n-\t} else {\n-\t\tdir = find_containing_dir(dir, refname, 0);\n-\t}\n-\tif (!dir)\n-\t\treturn -1;\n-\tentry_index = search_ref_dir(dir, refname, refname_len);\n-\tif (entry_index == -1)\n-\t\treturn -1;\n-\tentry = dir->entries[entry_index];\n-\n-\tMOVE_ARRAY(&dir->entries[entry_index],\n-\t\t   &dir->entries[entry_index + 1], dir->nr - entry_index - 1);\n-\tdir->nr--;\n-\tif (dir->sorted > entry_index)\n-\t\tdir->sorted--;\n-\tfree_ref_entry(entry);\n-\treturn dir->nr;\n-}\n-\n int add_ref_entry(struct ref_dir *dir, struct ref_entry *ref)\n {\n \tdir = find_containing_dir(dir, ref->name, 1);\ndiff --git a/refs/ref-cache.h b/refs/ref-cache.h\nindex 3bfb89d2b34..bd1ff578ea2 100644\n--- a/refs/ref-cache.h\n+++ b/refs/ref-cache.h\n@@ -199,22 +199,6 @@ void free_ref_cache(struct ref_cache *cache);\n  */\n void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry);\n \n-/*\n- * Remove the entry with the given name from dir, recursing into\n- * subdirectories as necessary.  If refname is the name of a directory\n- * (i.e., ends with '/'), then remove the directory and its contents.\n- * If the removal was successful, return the number of entries\n- * remaining in the directory entry that contained the deleted entry.\n- * If the name was not found, return -1.  Please note that this\n- * function only deletes the entry from the cache; it does not delete\n- * it from the filesystem or ensure that other cache entries (which\n- * might be symbolic references to the removed entry) are updated.\n- * Nor does it remove any containing dir entries that might be made\n- * empty by the removal.  dir must represent the top-level directory\n- * and must already be complete.\n- */\n-int remove_entry_from_dir(struct ref_dir *dir, const char *refname);\n-\n /*\n  * Add a ref_entry to the ref_dir (unsorted), recursing into\n  * subdirectories as necessary.  dir must represent the top-level\n-- \n2.33.0.1340.ge9f77250f2b\n\n"},{"id":"437289","messageId":"patch-3.5-962c1bffa21-20210928T130032Z-avarab@gmail.com","threadId":"56603","inReplyTo":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","subject":"[PATCH 3/5] refs/ref-cache.[ch]: remove unused add_ref_entry()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-28T13:02:22Z","receivedAt":"2021-09-28T13:02:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This function has not been used since 9dd389f3d8d (packed_ref_store:\nget rid of the `ref_cache` entirely, 2017-09-25).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n refs/ref-cache.c | 9 ---------\n refs/ref-cache.h | 7 -------\n 2 files changed, 16 deletions(-)\n\ndiff --git a/refs/ref-cache.c b/refs/ref-cache.c\nindex e0feebf628f..a28883768c9 100644\n--- a/refs/ref-cache.c\n+++ b/refs/ref-cache.c\n@@ -212,15 +212,6 @@ struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname)\n \treturn (entry->flag & REF_DIR) ? NULL : entry;\n }\n \n-int add_ref_entry(struct ref_dir *dir, struct ref_entry *ref)\n-{\n-\tdir = find_containing_dir(dir, ref->name, 1);\n-\tif (!dir)\n-\t\treturn -1;\n-\tadd_entry_to_dir(dir, ref);\n-\treturn 0;\n-}\n-\n /*\n  * Emit a warning and return true iff ref1 and ref2 have the same name\n  * and the same oid. Die if they have the same name but different\ndiff --git a/refs/ref-cache.h b/refs/ref-cache.h\nindex bd1ff578ea2..580d4038f62 100644\n--- a/refs/ref-cache.h\n+++ b/refs/ref-cache.h\n@@ -199,13 +199,6 @@ void free_ref_cache(struct ref_cache *cache);\n  */\n void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry);\n \n-/*\n- * Add a ref_entry to the ref_dir (unsorted), recursing into\n- * subdirectories as necessary.  dir must represent the top-level\n- * directory.  Return 0 on success.\n- */\n-int add_ref_entry(struct ref_dir *dir, struct ref_entry *ref);\n-\n /*\n  * Find the value entry with the given name in dir, sorting ref_dirs\n  * and recursing into subdirectories as necessary.  If the name is not\n-- \n2.33.0.1340.ge9f77250f2b\n\n"},{"id":"437290","messageId":"patch-4.5-a6f9c19f658-20210928T130032Z-avarab@gmail.com","threadId":"56603","inReplyTo":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","subject":"[PATCH 4/5] refs/ref-cache.c: remove \"mkdir\" parameter from find_containing_dir()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-28T13:02:23Z","receivedAt":"2021-09-28T13:02:41Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the \"mkdir\" parameter from the find_containing_dir() function,\nthe add_ref_entry() function removed in the preceding commit was its\nlast user.\n\nSince \"mkdir\" is always \"0\" we can also remove the parameter from\nsearch_for_subdir(), which in turn means that we can delete most of\nthat function.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n refs/ref-cache.c | 36 ++++++++++++------------------------\n 1 file changed, 12 insertions(+), 24 deletions(-)\n\ndiff --git a/refs/ref-cache.c b/refs/ref-cache.c\nindex a28883768c9..73b338f5ff2 100644\n--- a/refs/ref-cache.c\n+++ b/refs/ref-cache.c\n@@ -144,30 +144,19 @@ int search_ref_dir(struct ref_dir *dir, const char *refname, size_t len)\n /*\n  * Search for a directory entry directly within dir (without\n  * recursing).  Sort dir if necessary.  subdirname must be a directory\n- * name (i.e., end in '/').  If mkdir is set, then create the\n- * directory if it is missing; otherwise, return NULL if the desired\n+ * name (i.e., end in '/'). Returns NULL if the desired\n  * directory cannot be found.  dir must already be complete.\n  */\n static struct ref_dir *search_for_subdir(struct ref_dir *dir,\n-\t\t\t\t\t const char *subdirname, size_t len,\n-\t\t\t\t\t int mkdir)\n+\t\t\t\t\t const char *subdirname, size_t len)\n {\n \tint entry_index = search_ref_dir(dir, subdirname, len);\n \tstruct ref_entry *entry;\n-\tif (entry_index == -1) {\n-\t\tif (!mkdir)\n-\t\t\treturn NULL;\n-\t\t/*\n-\t\t * Since dir is complete, the absence of a subdir\n-\t\t * means that the subdir really doesn't exist;\n-\t\t * therefore, create an empty record for it but mark\n-\t\t * the record complete.\n-\t\t */\n-\t\tentry = create_dir_entry(dir->cache, subdirname, len, 0);\n-\t\tadd_entry_to_dir(dir, entry);\n-\t} else {\n-\t\tentry = dir->entries[entry_index];\n-\t}\n+\n+\tif (entry_index == -1)\n+\t\treturn NULL;\n+\n+\tentry = dir->entries[entry_index];\n \treturn get_ref_dir(entry);\n }\n \n@@ -176,18 +165,17 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir,\n  * tree that should hold refname. If refname is a directory name\n  * (i.e., it ends in '/'), then return that ref_dir itself. dir must\n  * represent the top-level directory and must already be complete.\n- * Sort ref_dirs and recurse into subdirectories as necessary. If\n- * mkdir is set, then create any missing directories; otherwise,\n+ * Sort ref_dirs and recurse into subdirectories as necessary. Will\n  * return NULL if the desired directory cannot be found.\n  */\n static struct ref_dir *find_containing_dir(struct ref_dir *dir,\n-\t\t\t\t\t   const char *refname, int mkdir)\n+\t\t\t\t\t   const char *refname)\n {\n \tconst char *slash;\n \tfor (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {\n \t\tsize_t dirnamelen = slash - refname + 1;\n \t\tstruct ref_dir *subdir;\n-\t\tsubdir = search_for_subdir(dir, refname, dirnamelen, mkdir);\n+\t\tsubdir = search_for_subdir(dir, refname, dirnamelen);\n \t\tif (!subdir) {\n \t\t\tdir = NULL;\n \t\t\tbreak;\n@@ -202,7 +190,7 @@ struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname)\n {\n \tint entry_index;\n \tstruct ref_entry *entry;\n-\tdir = find_containing_dir(dir, refname, 0);\n+\tdir = find_containing_dir(dir, refname);\n \tif (!dir)\n \t\treturn NULL;\n \tentry_index = search_ref_dir(dir, refname, strlen(refname));\n@@ -478,7 +466,7 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,\n \n \tdir = get_ref_dir(cache->root);\n \tif (prefix && *prefix)\n-\t\tdir = find_containing_dir(dir, prefix, 0);\n+\t\tdir = find_containing_dir(dir, prefix);\n \tif (!dir)\n \t\t/* There's nothing to iterate over. */\n \t\treturn empty_ref_iterator_begin();\n-- \n2.33.0.1340.ge9f77250f2b\n\n"},{"id":"437291","messageId":"patch-5.5-1623819fb56-20210928T130032Z-avarab@gmail.com","threadId":"56603","inReplyTo":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","subject":"[PATCH 5/5] refs/ref-cache.[ch]: remove \"incomplete\" from create_dir_entry()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-28T13:02:24Z","receivedAt":"2021-09-28T13:02:45Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the now-unused \"incomplete\" parameter from create_dir_entry(),\nall its callers specify it as \"1\", so let's drop the \"incomplete=0\"\ncase. The last caller to use it was search_for_subdir(), but that code\nwas removed in the preceding commit.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n refs/files-backend.c | 6 +++---\n refs/ref-cache.c     | 7 +++----\n refs/ref-cache.h     | 3 +--\n 3 files changed, 7 insertions(+), 9 deletions(-)\n\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 74c03858736..8fa328108ac 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -227,7 +227,7 @@ static void add_per_worktree_entries_to_dir(struct ref_dir *dir, const char *dir\n \t\tpos = search_ref_dir(dir, prefix, prefix_len);\n \t\tif (pos >= 0)\n \t\t\tcontinue;\n-\t\tchild_entry = create_dir_entry(dir->cache, prefix, prefix_len, 1);\n+\t\tchild_entry = create_dir_entry(dir->cache, prefix, prefix_len);\n \t\tadd_entry_to_dir(dir, child_entry);\n \t}\n }\n@@ -278,7 +278,7 @@ static void loose_fill_ref_dir(struct ref_store *ref_store,\n \t\t\tstrbuf_addch(&refname, '/');\n \t\t\tadd_entry_to_dir(dir,\n \t\t\t\t\t create_dir_entry(dir->cache, refname.buf,\n-\t\t\t\t\t\t\t  refname.len, 1));\n+\t\t\t\t\t\t\t  refname.len));\n \t\t} else {\n \t\t\tif (!refs_resolve_ref_unsafe(&refs->base,\n \t\t\t\t\t\t     refname.buf,\n@@ -336,7 +336,7 @@ static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs)\n \t\t * lazily):\n \t\t */\n \t\tadd_entry_to_dir(get_ref_dir(refs->loose->root),\n-\t\t\t\t create_dir_entry(refs->loose, \"refs/\", 5, 1));\n+\t\t\t\t create_dir_entry(refs->loose, \"refs/\", 5));\n \t}\n \treturn refs->loose;\n }\ndiff --git a/refs/ref-cache.c b/refs/ref-cache.c\nindex 73b338f5ff2..a5ad8a39fb4 100644\n--- a/refs/ref-cache.c\n+++ b/refs/ref-cache.c\n@@ -49,7 +49,7 @@ struct ref_cache *create_ref_cache(struct ref_store *refs,\n \n \tret->ref_store = refs;\n \tret->fill_ref_dir = fill_ref_dir;\n-\tret->root = create_dir_entry(ret, \"\", 0, 1);\n+\tret->root = create_dir_entry(ret, \"\", 0);\n \treturn ret;\n }\n \n@@ -86,14 +86,13 @@ static void clear_ref_dir(struct ref_dir *dir)\n }\n \n struct ref_entry *create_dir_entry(struct ref_cache *cache,\n-\t\t\t\t   const char *dirname, size_t len,\n-\t\t\t\t   int incomplete)\n+\t\t\t\t   const char *dirname, size_t len)\n {\n \tstruct ref_entry *direntry;\n \n \tFLEX_ALLOC_MEM(direntry, name, dirname, len);\n \tdirentry->u.subdir.cache = cache;\n-\tdirentry->flag = REF_DIR | (incomplete ? REF_INCOMPLETE : 0);\n+\tdirentry->flag = REF_DIR | REF_INCOMPLETE;\n \treturn direntry;\n }\n \ndiff --git a/refs/ref-cache.h b/refs/ref-cache.h\nindex 580d4038f62..5c042ae718c 100644\n--- a/refs/ref-cache.h\n+++ b/refs/ref-cache.h\n@@ -169,8 +169,7 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry);\n  * \"refs/heads/\") or \"\" for the top-level directory.\n  */\n struct ref_entry *create_dir_entry(struct ref_cache *cache,\n-\t\t\t\t   const char *dirname, size_t len,\n-\t\t\t\t   int incomplete);\n+\t\t\t\t   const char *dirname, size_t len);\n \n struct ref_entry *create_ref_entry(const char *refname,\n \t\t\t\t   const struct object_id *oid, int flag);\n-- \n2.33.0.1340.ge9f77250f2b\n\n"},{"id":"437339","messageId":"YVNX2QrdR7XZFfqA@coredump.intra.peff.net","threadId":"56603","inReplyTo":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","subject":"Re: [PATCH 0/5] refs: remove long-dead code","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2021-09-28T17:58:49Z","receivedAt":"2021-09-28T17:58:55Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Sep 28, 2021 at 03:02:19PM +0200, Ævar Arnfjörð Bjarmason wrote:\n\n> This removes dead code in the refs backend, mainly in the\n> ref-cache. By line count this is mostly a straightforward follow-up to\n> 9939b33d6a3 (packed-backend: rip out some now-unused code, 2017-09-08)\n> and 9dd389f3d8d (packed_ref_store: get rid of the `ref_cache`\n> entirely, 2017-09-25).\n\nThanks, all five look good to me.\n\nReading through I was surprised the loose backend didn't use\nadd_ref_entry(), but that's because it uses add_entry_to_dir() more\ndirectly. And that also explains why the \"incomplete\" parameter in the\nfinal patch was always 1: in the loose world, we are always reading as\nincrementally as possible.\n\nSo patches 2-4 are really just fallout from switching the packed-refs\nreading away from ref-cache. Makes sense.\n\n-Peff\n"},{"id":"437369","messageId":"xmqqv92kic3c.fsf@gitster.g","threadId":"56603","inReplyTo":"cover-0.5-00000000000-20210928T130032Z-avarab@gmail.com","subject":"Re: [PATCH 0/5] refs: remove long-dead code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-28T22:12:23Z","receivedAt":"2021-09-28T22:12:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> This removes dead code in the refs backend, mainly in the\n> ref-cache. By line count this is mostly a straightforward follow-up to\n> 9939b33d6a3 (packed-backend: rip out some now-unused code, 2017-09-08)\n> and 9dd389f3d8d (packed_ref_store: get rid of the `ref_cache`\n> entirely, 2017-09-25).\n>\n> Ævar Arnfjörð Bjarmason (5):\n>   refs.[ch]: remove unused ref_storage_backend_exists()\n>   refs/ref-cache.[ch]: remove unused remove_entry_from_dir()\n>   refs/ref-cache.[ch]: remove unused add_ref_entry()\n>   refs/ref-cache.c: remove \"mkdir\" parameter from find_containing_dir()\n>   refs/ref-cache.[ch]: remove \"incomplete\" from create_dir_entry()\n\nLooking good.  Thanks.\n"}]}