code: def refresh_available_extensions_from_data(
      hide_tags, sort_column, filter_text=""
  ):
      extlist = available_extensions["extensions"]
      installed_extensions = {
          extension.name for extension in extensions.extensions
      }
      installed_extension_urls = {
          normalize_git_url(extension.remote)
          for extension in extensions.extensions
          if extension.remote is not None
      }
  
      tags = available_extensions.get("tags", {})
      tags_to_hide = set(hide_tags)
      hidden = 0
  
      code = f"""<!-- {time.time()} -->
      <table id="available_extensions">
          <thead>
              <tr>
                  <th>Extension</th>
                  <th>Description</th>
                  <th>Action</th>
              </tr>
          </thead>
          <tbody>
      """
  
      sort_reverse, sort_function = sort_ordering[
          sort_column if 0 <= sort_column < len(sort_ordering) else 0
      ]
  
      for ext in sorted(
          extlist, key=sort_function, reverse=sort_reverse
      ):
          name = ext.get("name", "noname")
          stars = int(ext.get("stars", 0))
          added = ext.get("added", "unknown")
          update_time = get_date(ext, "commit_time")
          create_time = get_date(ext, "created_at")
          url = ext.get("url", None)
          description = ext.get("description", "")
          extension_tags = ext.get("tags", [])
  
          if url is None:
              continue
  
          existing = (
              get_extension_dirname_from_url(url)
              in installed_extensions
              or normalize_git_url(url) in installed_extension_urls
          )
          extension_tags = (
              extension_tags + ["installed"]
              if existing
              else extension_tags
          )
  
          if any(x for x in extension_tags if x in tags_to_hide):
              hidden += 1
              continue
  
          if filter_text and filter_text.strip():
              if (
                  filter_text.lower() not in html.escape(name).lower()
                  and filter_text.lower()
                  not in html.escape(description).lower()
              ):
                  hidden += 1
                  continue
  
          install_code = f"""<button onclick="install_extension_from_index(this, '{html.escape(url)}')" {"disabled=disabled" if existing else ""} class="lg secondary gradio-button custom-button">{"Install" if not existing else "Installed"}</button>"""
  
          tags_text = ", ".join(
              [
                  f"<span class='extension-tag' title='{tags.get(x, '')}'>{x}</span>"
                  for x in extension_tags
              ]
          )
  
          code += f"""
              <tr>
                  <td><a href="{html.escape(url)}" target="_blank">{html.escape(name)}</a><br />{tags_text}</td>
                  <td>{html.escape(description)}<p class="info">
                  <span class="date_added">Update: {html.escape(update_time)}  Added: {html.escape(added)}  Created: {html.escape(create_time)}</span><span class="star_count">stars: <b>{stars}</b></a></p></td>
                  <td>{install_code}</td>
              </tr>
  
          """
  
          for tag in [x for x in extension_tags if x not in tags]:
              tags[tag] = tag
  
      code += """
          </tbody>
      </table>
      """
  
      if hidden > 0:
          code += f"<p>Extension hidden: {hidden}</p>"
  
      return code, list(tags)
  
imports: import json
  import os
  import threading
  import time
  from datetime import datetime, timezone
  import git
  import gradio
  import html
  import shutil
  import errno
  from modules import extensions, shared, paths, config_states, errors, restart
  from modules.paths_internal import config_states_dir
  from modules.call_queue import wrap_gradio_gpu_call
label_desc: Use image node_id 17 for calling a global function with example usage: refresh_available_extensions_from_data(hide_tags, sort_column, filter_text) and returns: code,  list