c7fcdde6db52ba01fbabfa695b49205bf7261a33
max
  Tue Aug 4 07:40:32 2026 -0700
hgBlat/hgc: QA fixes for the new BLAT table view and alignment page

Address Gerardo's QA findings on the new BLAT UI:
- Table view: label each hit with its own query (new Query column +
"Queries" count in the summary) when the search has multiple queries,
reading cfg.multiQuery / hit.qName from the payload.
- Table view: strip the "hub_NNN_" prefix from the Assembly field so hub
assemblies no longer show a doubled prefix.
- Alignment page: strip the same prefix from the organism in the page title
for non-GenArk assembly hubs (blatAsmLabel fallback path).
- Table view: do not pre-select hit #1; show a prompt until the user clicks
a row, since top hits are often tied.
- Table view: add a divider between the Browser / New tab / Alignment links.
- Alignment page: sidebar link now reads "Side by Side Alignment" to match
the section heading.
- Alignment page: comma-format coordinates and base counts in the summary,
matching the table view and the rest of the browser.

refs #37893

diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 8ea4709b154..e8ae42ba93d 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -9014,31 +9014,34 @@
 htmlFramesetStart(title);
 /*showSomeAlignment(psl, qSeq, gftDnaX, psl->qStart, psl->qEnd, name, 0, 0); */
 showSomeAlignment(psl, qSeq, gftDnaX, psl->qStart, psl->qEnd, name, cdsStart, cdsEnd);
 }
 
 static char *blatAsmLabel(char *database)
 /* A user-facing assembly label for the page title.  For an assembly hub the internal
  * "hub_NNN_GCA_..." database name is not helpful, so use the assembly's friendly organism plus its
  * accession; for a native assembly just use the db name (e.g. "hg38"). */
 {
 if (!trackHubDatabase(database))
     return cloneString(database);
 char *acc = trackHubSkipHubName(database);   /* drop the "hub_NNN_" prefix -> the accession */
 char *org = hGenome(acc);                    /* GenArk table's friendly genome name for GC* accs */
 if (isEmpty(org))
+    {
     org = trackHubAssemblyField(database, "organism");   /* else the hub's genomes.txt organism */
+    org = trackHubSkipHubName(org);          /* strip the "hub_NNN_" prefix addHubName() baked in */
+    }
 if (isEmpty(org))
     return cloneString(acc);
 char buf[256];
 safef(buf, sizeof buf, "%s %s", org, acc);
 return cloneString(buf);
 }
 
 static void showSomeAlignmentModern(struct psl *psl, bioSeq *oSeq, enum gfType qType,
                        int qStart, int qEnd, char *qName, int cdsS, int cdsE)
 /* Modern single-page version of showSomeAlignment for hgBlat's new table mode: a gold title bar with
  * Back/Share buttons, a full-height "jump to" sidebar, then an "Alignment Summary" and the base-by-
  * base alignment inlined below with steel-blue section headers, so the whole page scrolls (no
  * <frameset>).  The alignment body itself is generated by the shared library as before.  The caller
  * supplies the page chrome via webStartGbNoBanner()/webEndGb() - a menubar and <main> with no legacy
  * section tables - so everything here is plain, table-free HTML. */
@@ -9122,53 +9125,60 @@
 printf("<span class='blatTtl'>BLAT Base Alignment: %s</span>", blatAsmLabel(database));
 printf("<span class='blatBtns'>");
 printf("<a href='hgBlat?blatReopen=1&hgsid=%s' class='blatBtn'>"
        "\xe2\x80\xb9 Back to results</a>", cartSessionId(cart));
 if (canShare)
     printf("<a href='#' id='blatShareBtn' class='blatBtn'>Share a link</a>");
 printf("</span></div>\n");
 
 /* one white panel laid out as two grid columns: a full-height "jump to" sidebar on the left, and on
  * the right an "Alignment Summary" header, the summary line, and the base-by-base alignment inlined
  * so the whole page scrolls */
 printf("<div id='blatAlnBody'>\n");
 
 printf("<div id='blatAlnContent'>\n");
 printf("<h4>Alignment Summary</h4>\n");
-printf("<p><b>%s</b> aligned to <b>%s:%d-%d</b>, "
+/* comma-format the coordinates and base counts, matching the new Table view (readable at the
+ * hundreds-of-millions scale of genomic coordinates, and the convention elsewhere in the browser) */
+char tStartC[32], tEndC[32], matchC[32], qSizeC[32];
+sprintLongWithCommas(tStartC, psl->tStart + 1);
+sprintLongWithCommas(tEndC, psl->tEnd);
+sprintLongWithCommas(matchC, psl->match + psl->repMatch);
+sprintLongWithCommas(qSizeC, psl->qSize);
+printf("<p><b>%s</b> aligned to <b>%s:%s-%s</b>, "
        "<b style='color:%s'>%.1f%% identity</b>, "
-       "%d of %d bases matched, strand <b>%s</b>.</p>\n",
-       qName, chrom, psl->tStart + 1, psl->tEnd, idColor, ident,
-       psl->match + psl->repMatch, psl->qSize, psl->strand);
+       "%s of %s bases matched, strand <b>%s</b>.</p>\n",
+       qName, chrom, tStartC, tEndC, idColor, ident,
+       matchC, qSizeC, psl->strand);
 if (isNotEmpty(aliasStr))
     printf("<p>Genome sequence %s is also known as: %s.</p>\n", chrom, aliasStr);
 /* The shared library returns the number of alignment blocks it actually shows.  The DNA path merges
  * blocks separated by gaps <= 8 bases, so this can be fewer than psl->blockCount; use it (not
  * psl->blockCount) so the sidebar's "Block N" links match the #1..#N anchors that were emitted. */
 int blockCount;
 if (qType == gftRna || qType == gftDna)
     blockCount = showPartialDnaAlignment(psl, oSeq, stdout, cdsS, cdsE, FALSE);
 else
     blockCount = showGfAlignment(psl, oSeq, stdout, qType, qStart, qEnd, qName);
 printf("</div>\n");   /* #blatAlnContent */
 
 /* Sidebar, emitted after the alignment so blockCount is known; CSS grid puts it back in column 1.
  * The inner div is position:sticky so the links stay in view as the long alignment scrolls. */
 printf("<div id='blatAlnNav'><div id='blatAlnNavInner'>\n");
 printf("<a href='#cDNA'>Only query sequence</a>\n"
        "<a href='#genomic'>Only genome sequence</a>\n"
-       "<a href='#ali'>Side-by-side alignment</a>\n");
+       "<a href='#ali'>Side by Side Alignment</a>\n");
 if (blockCount > 1)   /* per-block jump links, indented under the side-by-side item */
     {
     int bi;
     printf("<div id='blatAlnBlocks'>\n");
     for (bi = 1;  bi <= blockCount;  ++bi)
         printf("<a href='#%d'>Block %d</a>\n", bi, bi);
     printf("</div>\n");
     }
 printf("</div></div>\n");
 
 printf("</div>\n");   /* #blatAlnBody */
 
 /* The cDNA/Genomic section headers come from shared library code (fuzzyShow.c / pslShow.c) as
  * "cDNA <qName>" / "Genomic <chrom> :"; relabel them to the sidebar wording via JS (there is no C
  * hook for it), keeping the #cDNA/#genomic jump anchors.  qName and chrom are already sanitized. */