6ae582f5103a8b27420c44a8f92f210969f65f4c
max
  Sat Jul 25 21:36:18 2026 -0700
hgc BLAT alignment viewer: table-free page, share dialog, chromAlias, block-count fix

refs #37893

Modern base-alignment page (showSomeAlignmentModern):
- Switch page chrome to webStartGbNoBanner()/webEndGb() (menubar + <main>, no legacy
nested section tables) and draw the gold title bar + grey Back/Share buttons in plain
HTML instead of injecting them with JS.
- Full-height "jump to" sidebar; its links are position:sticky so they stay visible while
scrolling the long alignment. The per-block "Block N" links use the block count the
renderer returns, not psl->blockCount. The DNA path (ffShAliPart) merges blocks
separated by gaps <= 8 bases, so raw psl->blockCount over-counted and produced links to
#N anchors that did not exist; the returned count matches the emitted anchors.
- Show the genomic sequence's chromAlias names ("Genome sequence chr7 is also known as:
..."), de-duplicated. Friendly assembly label (organism + accession) for hub databases
instead of the internal hub_NNN_ name.

Durable "Share a link":
- Opens the shared topLinks.js "Share a link" modal and hands it a durable
hgc?g=htcBlatAlign link. The link carries only the hit selectors (c/o/i) plus u=l&s=;
db and the browser window come from the saved session. htcBlatAlign rebuilds the one
alignment from the session's durable bigPsl custom track (no BLAT re-run).
- Restore the per-hit "Alignment" links on shared-session results tables (hgBlat.c).

lib/cart.c:
- cartWriteHeaderAndCont() is now idempotent (guards on cartDidContentType). hgc writes
the CGI header early, so a later webStartGb* would otherwise write a second
Set-Cookie/Content-Type into the page body.

diff --git src/hg/hgBlat/hgBlat.c src/hg/hgBlat/hgBlat.c
index 0463a8d0eda..2161cdbb03f 100644
--- src/hg/hgBlat/hgBlat.c
+++ src/hg/hgBlat/hgBlat.c
@@ -669,34 +669,34 @@
     jsonWriteNumber(jw, "qStart", psl->qStart + 1);
     jsonWriteNumber(jw, "qEnd", psl->qEnd);
     jsonWriteNumber(jw, "qSize", psl->qSize);
     jsonWriteNumber(jw, "matches", psl->match + psl->repMatch);
     jsonWriteNumber(jw, "misMatch", psl->misMatch);
     jsonWriteNumber(jw, "gaps", psl->qNumInsert + psl->tNumInsert);
     jsonWriteNumber(jw, "blocks", psl->blockCount);
     jsonWriteString(jw, "browserUrl", inTabUrl);
     jsonWriteString(jw, "newTabUrl", newTabUrl);
     if (pslName != NULL)
         jsonWriteStringf(jw, "detailsUrl", "%s?o=%d&g=htcUserAli&i=%s+%s+%s&c=%s&l=%d&r=%d&db=%s&%s",
             hgcUrl, psl->tStart, pslName, cgiEncode(faName), psl->qName, psl->tName,
             psl->tStart, psl->tEnd, database, uiState);
     else
         /* Shared-link reopen: there is no trash .pslx, but the durable bigPsl custom track (now in
-         * this cart) lets hgc's htcBlatAlign rebuild the base alignment from the stored query seq. */
-        jsonWriteStringf(jw, "detailsUrl", "%s?g=htcBlatAlign&db=%s&c=%s&o=%d&l=%d&r=%d&i=%s&%s",
-            hgcUrl, database, psl->tName, psl->tStart, psl->tStart, psl->tEnd,
-            cgiEncode(psl->qName), uiState);
+         * this cart) lets hgc's htcBlatAlign rebuild the base alignment from the stored query seq.
+         * chrom/start/qName select the hit; db and the browser window come from the loaded cart. */
+        jsonWriteStringf(jw, "detailsUrl", "%s?g=htcBlatAlign&db=%s&c=%s&o=%d&i=%s&%s",
+            hgcUrl, database, psl->tName, psl->tStart, cgiEncode(psl->qName), uiState);
     if (locusConn)
         {
         struct sqlResult *sr = hRangeQuery(locusConn, "locusName", psl->tName, psl->tStart, psl->tEnd, NULL, 0);
         char **row = sqlNextRow(sr);
         if (row != NULL)
             {
             char *raw = row[4];
             char *full = subTextString(subList, raw);
             jsonWriteString(jw, "locusText", full);
             freeMem(full);
             char *type = NULL, *genes = raw;
             if (startsWith("ig:", raw))
                 { type = "intergenic"; genes = raw + 3; }
             else if (startsWith("ex:", raw))
                 { type = "exon"; genes = raw + 3; }