9b015ea745e001ab48af46610af1b7724fd066cc
jrobinso
  Mon Sep 22 16:28:40 2025 -0700
Typo in filepicker text

diff --git src/hg/htdocs/admin/filePicker.html src/hg/htdocs/admin/filePicker.html
index 41daa88cc4e..34191ca7bdb 100644
--- src/hg/htdocs/admin/filePicker.html
+++ src/hg/htdocs/admin/filePicker.html
@@ -1,196 +1,196 @@
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>File Manager</title>
 
     <link rel="stylesheet" href="../../style/HGStyle.css" type="text/css">
     <style>
 
         .section-group {
             border: 2px solid #ccc;
             /*border-radius: 8px; */
             padding: 16px;
             margin-bottom: 24px;
             background: #fafafa;
         }
 
         .input-row {
             display: flex;
             align-items: center;
             margin-top: 8px;
             gap: 16px;
         }
 
         .input-row label {
             min-width: 100px;
         }
 
         .input-row input[type="url"] {
             width: 500px;
         }
     </style>
 
 </head>
 <body>
 
 <section class="section-group" style="text-align: center; margin-bottom: 32px; background: #e3f2fd;">
     <h2 style="margin: 0; font-size: 2em;">IGV File Manager</h2>
     <p style="font-size: 1.1em;">
         Please do not close this window, it is necessary to maintain access to the files that you open below. If
         you close this window, the Genome Browser's IGV track loses access to the files.</p>
 </section>
 
 <section class="section-group">
     <div id="message" style="color: red; font-weight: bold; display: none;">
         Please select the following files to restore access:
         <p>
         <ul id="restoreList"></ul>
         </p>
     </div>
     <h3>Local Files</h3>
     <p>
-        Click the "Chose Files" button to select track files in supported formats from your local file system. For
+        Click the "Choose Files" button to select track files in supported formats from your local file system. For
         indexed
         formats both data and index files must be selected.
     </p>
     <p>
         Selected files are loaded directly from your file system to the web browser. <b>No data is transfered to UCSC or
         any other server, it remains on your local computer</b>. If you make a session shortlink on the
         Genome Browser, these files will not be included and cannot be loaded by the person that
         opens the session link.
     </p>
     <p>
         If this window is closed file access is lost, and you must re-open this window with the "Add IGV Tracks" button
         and re-select the files to restore access.
     </p>
 
     <input type="file" id="fileInput" multiple>
     <p>
     <h4>Selected local files:</h4>
     <ul id="fileList"></ul>
     </p>
 </section>
 
 <section class="section-group">
     <h3>URL</h3>
     <p>
         Enter a 'https' URL to an IGV supported track file and its index, if applicable. Data from this URL is loaded
         directly to your web browser, <b>no data is sent to UCSC or any other server</b>.
     </p>
     <p>
         Note if this is a publicly accessible URL and public data, it is usually easier to load the file as a 'custom
         track' or 'track hub'.
     </p>
 
     <div class="input-row">
         <label for="urlInput">URL</label>
         <input type="url" id="urlInput">
     </div>
     <div class="input-row">
         <label for="indexURLInput">Index URL</label>
         <input type="url" id="indexURLInput">
     </div>
     <p>
         <button id="urlButton">Load</button>
     </p>
 </section>
 
 
 <script>
     const fileCache = new Map();
     const restoreCache = new Map();
     const channel = new BroadcastChannel('igv_file_channel');
 
     document.addEventListener('DOMContentLoaded', () => {
 
         channel.postMessage({type: 'filePickerReady'});
 
         document.getElementById('fileInput').addEventListener('change', function (event) {
             const files = [];
             for (let file of event.target.files) {
                 const id = `${file.name}_${file.size}`;
                 files.push({id, file}); //value)
                 fileCache.set(id, file);
                 restoreCache.delete(id);
                 refreshFileList();
             }
             event.target.value = "";
 
             channel.postMessage({type: 'selectedFiles', files: files});
         });
 
         document.getElementById("urlButton").addEventListener('click', event => {
             const url = document.getElementById("urlInput").value;
             if (url) {
                 let indexURL = document.getElementById("indexURLInput").value;
                 if (!indexURL) {
                     if (url.endsWith(".bam")) {
                         indexURL = url + ".bai";
                     } else if (url.endsWith(".cram")) {
                         indexURL = url + ".crai";
                     } else if (url.endsWith(".vcf.gz")) {
                         indexURL = url + ".tbi";
                     }
                 }
                 channel.postMessage({type: 'loadURL', config: {url, indexURL}});
             }
         });
 
         // Respond to messages from the browser page
         channel.onmessage = function (event) {
             const {id, type} = event.data;
             if (type === 'getFile') {
                 const selectedFile = fileCache.get(id);
                 channel.postMessage({type: 'file', id: id, data: selectedFile});   // TODO -- what if selectedFile is undefined?  Handle here or in browser?
             } else if (type === 'removeFile') {
                 fileCache.delete(id);
                 refreshFileList();
             } else if (type === 'restoreFiles') {
                 const failed = event.data.files;
                 for (const f of failed) {
                     restoreCache.set(f.id, f.name);
                 }
                 refreshFileList();
             } else if (type === 'removedTrack') {
                 // TODO -- might want to remove from restoreCache too
                 const config = event.data.config;
                 if (config.url && config.url.id) {
                     fileCache.delete(config.url.id);
                     restoreCache.delete(config.url.id);
                 }
                 if (config.indexURL && config.indexURL.id) {
                     fileCache.delete(config.indexURL.id);
                     restoreCache.delete(config.indexURL.id);
                 }
                 refreshFileList();
             } else if (type === 'ping') {
                 channel.postMessage({type: 'pong', id: window.name});
             }
             channel.postMessage({type: 'pong', id: window.name});
         };
     });
 
     function refreshFileList() {
 
         if (restoreCache.size > 0) {
             const ul = document.getElementById("restoreList");
             ul.innerHTML = "";
             for (let name of restoreCache.values()) {
                 ul.innerHTML += `<li>${name}</li>`;
             }
             document.getElementById("message").style.display = "block";
         } else {
             document.getElementById("message").style.display = "none";
         }
 
         const ul = document.getElementById("fileList");
         ul.innerHTML = "";
         for (let file of fileCache.values()) {
             ul.innerHTML += `<li>${file.name}</li>`;
         }
     }
 
 </script>
 </body>
 </html>