igv 3.1.1 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/igv.js CHANGED
@@ -19437,7 +19437,7 @@
19437
19437
  ctx.closePath();
19438
19438
  }
19439
19439
 
19440
- /*! @license DOMPurify 3.2.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.1/LICENSE */
19440
+ /*! @license DOMPurify 3.2.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.3/LICENSE */
19441
19441
 
19442
19442
  const {
19443
19443
  entries,
@@ -19612,7 +19612,6 @@
19612
19612
  }
19613
19613
 
19614
19614
  const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
19615
- // SVG
19616
19615
  const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
19617
19616
  const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
19618
19617
  // List of SVG elements that are disallowed by default.
@@ -19634,8 +19633,8 @@
19634
19633
  // eslint-disable-next-line unicorn/better-regex
19635
19634
  const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
19636
19635
  const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
19637
- const TMPLIT_EXPR = seal(/\${[\w\W]*}/gm);
19638
- const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
19636
+ const TMPLIT_EXPR = seal(/\$\{[\w\W]*}/gm); // eslint-disable-line unicorn/better-regex
19637
+ const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
19639
19638
  const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
19640
19639
  const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
19641
19640
  );
@@ -19718,10 +19717,23 @@
19718
19717
  return null;
19719
19718
  }
19720
19719
  };
19720
+ const _createHooksMap = function _createHooksMap() {
19721
+ return {
19722
+ afterSanitizeAttributes: [],
19723
+ afterSanitizeElements: [],
19724
+ afterSanitizeShadowDOM: [],
19725
+ beforeSanitizeAttributes: [],
19726
+ beforeSanitizeElements: [],
19727
+ beforeSanitizeShadowDOM: [],
19728
+ uponSanitizeAttribute: [],
19729
+ uponSanitizeElement: [],
19730
+ uponSanitizeShadowNode: []
19731
+ };
19732
+ };
19721
19733
  function createDOMPurify() {
19722
19734
  let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
19723
19735
  const DOMPurify = root => createDOMPurify(root);
19724
- DOMPurify.version = '3.2.1';
19736
+ DOMPurify.version = '3.2.3';
19725
19737
  DOMPurify.removed = [];
19726
19738
  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
19727
19739
  // Not running in a browser, provide a factory function
@@ -19774,7 +19786,7 @@
19774
19786
  const {
19775
19787
  importNode
19776
19788
  } = originalDocument;
19777
- let hooks = {};
19789
+ let hooks = _createHooksMap();
19778
19790
  /**
19779
19791
  * Expose whether this browser supports running the full DOMPurify.
19780
19792
  */
@@ -20203,8 +20215,8 @@
20203
20215
  });
20204
20216
  }
20205
20217
  element.removeAttribute(name);
20206
- // We void attribute values for unremovable "is"" attributes
20207
- if (name === 'is' && !ALLOWED_ATTR[name]) {
20218
+ // We void attribute values for unremovable "is" attributes
20219
+ if (name === 'is') {
20208
20220
  if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
20209
20221
  try {
20210
20222
  _forceRemove(element);
@@ -20295,11 +20307,8 @@
20295
20307
  const _isNode = function _isNode(value) {
20296
20308
  return typeof Node === 'function' && value instanceof Node;
20297
20309
  };
20298
- function _executeHook(entryPoint, currentNode, data) {
20299
- if (!hooks[entryPoint]) {
20300
- return;
20301
- }
20302
- arrayForEach(hooks[entryPoint], hook => {
20310
+ function _executeHooks(hooks, currentNode, data) {
20311
+ arrayForEach(hooks, hook => {
20303
20312
  hook.call(DOMPurify, currentNode, data, CONFIG);
20304
20313
  });
20305
20314
  }
@@ -20315,7 +20324,7 @@
20315
20324
  const _sanitizeElements = function _sanitizeElements(currentNode) {
20316
20325
  let content = null;
20317
20326
  /* Execute a hook if present */
20318
- _executeHook('beforeSanitizeElements', currentNode, null);
20327
+ _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
20319
20328
  /* Check if element is clobbered or can clobber */
20320
20329
  if (_isClobbered(currentNode)) {
20321
20330
  _forceRemove(currentNode);
@@ -20324,7 +20333,7 @@
20324
20333
  /* Now let's check the element's type and name */
20325
20334
  const tagName = transformCaseFunc(currentNode.nodeName);
20326
20335
  /* Execute a hook if present */
20327
- _executeHook('uponSanitizeElement', currentNode, {
20336
+ _executeHooks(hooks.uponSanitizeElement, currentNode, {
20328
20337
  tagName,
20329
20338
  allowedTags: ALLOWED_TAGS
20330
20339
  });
@@ -20395,7 +20404,7 @@
20395
20404
  }
20396
20405
  }
20397
20406
  /* Execute a hook if present */
20398
- _executeHook('afterSanitizeElements', currentNode, null);
20407
+ _executeHooks(hooks.afterSanitizeElements, currentNode, null);
20399
20408
  return false;
20400
20409
  };
20401
20410
  /**
@@ -20456,12 +20465,12 @@
20456
20465
  */
20457
20466
  const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
20458
20467
  /* Execute a hook if present */
20459
- _executeHook('beforeSanitizeAttributes', currentNode, null);
20468
+ _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
20460
20469
  const {
20461
20470
  attributes
20462
20471
  } = currentNode;
20463
20472
  /* Check if we have attributes; if not we might have a text node */
20464
- if (!attributes) {
20473
+ if (!attributes || _isClobbered(currentNode)) {
20465
20474
  return;
20466
20475
  }
20467
20476
  const hookEvent = {
@@ -20487,7 +20496,7 @@
20487
20496
  hookEvent.attrValue = value;
20488
20497
  hookEvent.keepAttr = true;
20489
20498
  hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
20490
- _executeHook('uponSanitizeAttribute', currentNode, hookEvent);
20499
+ _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
20491
20500
  value = hookEvent.attrValue;
20492
20501
  /* Full DOM Clobbering protection via namespace isolation,
20493
20502
  * Prefix id and name attributes with `user-content-`
@@ -20562,7 +20571,7 @@
20562
20571
  } catch (_) {}
20563
20572
  }
20564
20573
  /* Execute a hook if present */
20565
- _executeHook('afterSanitizeAttributes', currentNode, null);
20574
+ _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
20566
20575
  };
20567
20576
  /**
20568
20577
  * _sanitizeShadowDOM
@@ -20573,23 +20582,21 @@
20573
20582
  let shadowNode = null;
20574
20583
  const shadowIterator = _createNodeIterator(fragment);
20575
20584
  /* Execute a hook if present */
20576
- _executeHook('beforeSanitizeShadowDOM', fragment, null);
20585
+ _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
20577
20586
  while (shadowNode = shadowIterator.nextNode()) {
20578
20587
  /* Execute a hook if present */
20579
- _executeHook('uponSanitizeShadowNode', shadowNode, null);
20588
+ _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
20580
20589
  /* Sanitize tags and elements */
20581
- if (_sanitizeElements(shadowNode)) {
20582
- continue;
20583
- }
20590
+ _sanitizeElements(shadowNode);
20591
+ /* Check attributes next */
20592
+ _sanitizeAttributes(shadowNode);
20584
20593
  /* Deep shadow DOM detected */
20585
20594
  if (shadowNode.content instanceof DocumentFragment) {
20586
20595
  _sanitizeShadowDOM(shadowNode.content);
20587
20596
  }
20588
- /* Check attributes, sanitize if necessary */
20589
- _sanitizeAttributes(shadowNode);
20590
20597
  }
20591
20598
  /* Execute a hook if present */
20592
- _executeHook('afterSanitizeShadowDOM', fragment, null);
20599
+ _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
20593
20600
  };
20594
20601
  // eslint-disable-next-line complexity
20595
20602
  DOMPurify.sanitize = function (dirty) {
@@ -20675,15 +20682,13 @@
20675
20682
  /* Now start iterating over the created document */
20676
20683
  while (currentNode = nodeIterator.nextNode()) {
20677
20684
  /* Sanitize tags and elements */
20678
- if (_sanitizeElements(currentNode)) {
20679
- continue;
20680
- }
20685
+ _sanitizeElements(currentNode);
20686
+ /* Check attributes next */
20687
+ _sanitizeAttributes(currentNode);
20681
20688
  /* Shadow DOM detected, sanitize it */
20682
20689
  if (currentNode.content instanceof DocumentFragment) {
20683
20690
  _sanitizeShadowDOM(currentNode.content);
20684
20691
  }
20685
- /* Check attributes, sanitize if necessary */
20686
- _sanitizeAttributes(currentNode);
20687
20692
  }
20688
20693
  /* If we sanitized `dirty` in-place, return it. */
20689
20694
  if (IN_PLACE) {
@@ -20747,21 +20752,16 @@
20747
20752
  if (typeof hookFunction !== 'function') {
20748
20753
  return;
20749
20754
  }
20750
- hooks[entryPoint] = hooks[entryPoint] || [];
20751
20755
  arrayPush(hooks[entryPoint], hookFunction);
20752
20756
  };
20753
20757
  DOMPurify.removeHook = function (entryPoint) {
20754
- if (hooks[entryPoint]) {
20755
- return arrayPop(hooks[entryPoint]);
20756
- }
20758
+ return arrayPop(hooks[entryPoint]);
20757
20759
  };
20758
20760
  DOMPurify.removeHooks = function (entryPoint) {
20759
- if (hooks[entryPoint]) {
20760
- hooks[entryPoint] = [];
20761
- }
20761
+ hooks[entryPoint] = [];
20762
20762
  };
20763
20763
  DOMPurify.removeAllHooks = function () {
20764
- hooks = {};
20764
+ hooks = _createHooksMap();
20765
20765
  };
20766
20766
  return DOMPurify;
20767
20767
  }
@@ -28394,7 +28394,7 @@
28394
28394
  while ((line = await dataWrapper.nextLine()) !== undefined) {
28395
28395
  if (line && !line.startsWith("#")) {
28396
28396
 
28397
- const tokens = line.split("\t");
28397
+ const tokens = line.trim().split("\t");
28398
28398
  if (tokens.length === nExpectedColumns) {
28399
28399
  const variant = new Variant(tokens);
28400
28400
  variant.header = this.header; // Keep a pointer to the header to interpret fields for popup text
@@ -33163,7 +33163,7 @@
33163
33163
  if (this.type === "bigwig") {
33164
33164
  return "wig"
33165
33165
  } else {
33166
- return this.autoSql && this.autoSql.table === "chromatinInteract" ? "interact" : "annotation"
33166
+ return this.autoSql && ("interact" === this.autoSql.table || "chromatinInteract" === this.autoSql.table) ? "interact" : "annotation"
33167
33167
  }
33168
33168
  }
33169
33169
 
@@ -34853,7 +34853,7 @@
34853
34853
  // indicating whole chromosome should be read at once.
34854
34854
  if ((!visibilityWindow || visibilityWindow <= 0) && this.config.expandQuery !== false) {
34855
34855
  // Whole chromosome
34856
- const chromosome = this.genome ? this.genome.getChromosome(queryChr) : undefined;
34856
+ const chromosome = this.genome ? this.genome.getChromosome(chr) : undefined;
34857
34857
  intervalStart = 0;
34858
34858
  intervalEnd = Math.max(chromosome ? chromosome.bpLength : Number.MAX_SAFE_INTEGER, end);
34859
34859
  } else if (visibilityWindow > (end - start) && this.config.expandQuery !== false) {
@@ -40063,8 +40063,8 @@
40063
40063
  checkZoomIn() {
40064
40064
 
40065
40065
  const zoomedOutOfWindow = () => {
40066
- if (this.referenceFrame.chr.toLowerCase() === "all" && !this.trackView.track.supportsWholeGenome) {
40067
- return true
40066
+ if (this.referenceFrame.chr.toLowerCase() === "all") {
40067
+ return !this.trackView.track.supportsWholeGenome
40068
40068
  } else {
40069
40069
  const visibilityWindow = this.trackView.track.visibilityWindow;
40070
40070
  return (
@@ -60028,7 +60028,7 @@
60028
60028
  }
60029
60029
 
60030
60030
  get supportsWholeGenome() {
60031
- return true
60031
+ return typeof this.featureSource.supportsWholeGenome === 'function' ? this.featureSource.supportsWholeGenome() : true;
60032
60032
  }
60033
60033
 
60034
60034
  async getFeatures(chr, start, end) {
@@ -72574,7 +72574,7 @@
72574
72574
  })
72575
72575
  }
72576
72576
 
72577
- const _version = "3.1.1";
72577
+ const _version = "3.1.3";
72578
72578
  function version() {
72579
72579
  return _version
72580
72580
  }
@@ -75192,6 +75192,188 @@
75192
75192
 
75193
75193
  }
75194
75194
 
75195
+ /**
75196
+ * Default chromosome aliases, mostly 1<->chr1 etc. Used if chrom alias file is not supplied.
75197
+ *
75198
+ */
75199
+
75200
+ class ChromAliasDefaults {
75201
+
75202
+ aliasRecordCache = new Map()
75203
+
75204
+ constructor(id, chromosomeNames) {
75205
+ this.genomeID = id;
75206
+ this.update(id, chromosomeNames);
75207
+ }
75208
+
75209
+ async preload() {
75210
+ // no-op
75211
+ }
75212
+
75213
+ /**
75214
+ * Return the canonical chromosome name for the alias. If none found return the alias
75215
+ *
75216
+ * @param alias
75217
+ * @returns {*}
75218
+ */
75219
+ getChromosomeName(alias) {
75220
+ return this.aliasRecordCache.has(alias) ? this.aliasRecordCache.get(alias).chr : alias
75221
+ }
75222
+
75223
+ /**
75224
+ * Return an alternate chromosome name (alias).
75225
+ *
75226
+ * @param chr
75227
+ * @param nameSet -- The name set, e.g. "ucsc"
75228
+ * @returns {*|undefined}
75229
+ */
75230
+ getChromosomeAlias(chr, nameSet) {
75231
+ const aliasRecord = this.aliasRecordCache.get(chr);
75232
+ return aliasRecord ? aliasRecord[nameSet] || chr : chr
75233
+ }
75234
+
75235
+ update(id, chromosomeNames) {
75236
+
75237
+ if (chromosomeNames) {
75238
+ const aliasRecords = [];
75239
+ for (let name of chromosomeNames) {
75240
+
75241
+ if(this.aliasRecordCache.has(name)) {
75242
+ continue;
75243
+ }
75244
+
75245
+ const record = {chr: name};
75246
+ aliasRecords.push(record);
75247
+
75248
+ if (name.startsWith("gi|")) {
75249
+ // NCBI
75250
+ const alias = ChromAliasDefaults.getNCBIName(name);
75251
+ record["ncbi-gi-versioned"] = alias;
75252
+
75253
+ // Also strip version number out, if present
75254
+ const dotIndex = alias.lastIndexOf('.');
75255
+ if (dotIndex > 0) {
75256
+ const alias = alias.substring(0, dotIndex);
75257
+ record["ncbi-gi"] = alias;
75258
+ }
75259
+ } else {
75260
+
75261
+ if (name === "chrM") {
75262
+ record["ncbi"] = "MT";
75263
+ } else if (name === "MT") {
75264
+ record["ucsc"] = "chrM";
75265
+ } else if (name.toLowerCase().startsWith("chr") && Number.isInteger(Number(name.substring(3)))) {
75266
+ record["ncbi"] = name.substring(3);
75267
+ } else if (Number.isInteger(Number(name))) {
75268
+ record["ucsc"] = "chr" + name;
75269
+ }
75270
+
75271
+ // Special cases for human and mouse
75272
+ if (id.startsWith("hg") || id.startsWith("GRCh") || id === "1kg_ref" || id === "b37") {
75273
+ switch (name) {
75274
+ case "23":
75275
+ record["ucsc"] = "chrX";
75276
+ record["assembly"] = "X";
75277
+ break
75278
+ case "24":
75279
+ record["ucsc"] = "chrY";
75280
+ record["assembly"] = "Y";
75281
+ break
75282
+ case "chrX":
75283
+ record["ncbi"] = "23";
75284
+ record["assembly"] = "X";
75285
+ break
75286
+ case "chrY":
75287
+ record["ncbi"] = "24";
75288
+ record["assembly"] = "Y";
75289
+ break
75290
+ case "X":
75291
+ record["ucsc"] = "chrX";
75292
+ record["ncbi"] = "23";
75293
+ break
75294
+ case "Y":
75295
+ record["ucsc"] = "chrY";
75296
+ record["ncbi"] = "24";
75297
+ break
75298
+
75299
+ }
75300
+ } else if (id.startsWith("mm") || id.startsWith("GRCm") || id.startsWith("rheMac")) {
75301
+ switch (name) {
75302
+ case "21":
75303
+ record["ucsc"] = "chrX";
75304
+ record["assembly"] = "X";
75305
+ break
75306
+ case "22":
75307
+ record["ucsc"] = "chrY";
75308
+ record["assembly"] = "Y";
75309
+ break
75310
+ case "chrX":
75311
+ record["ncbi"] = "21";
75312
+ record["assembly"] = "X";
75313
+ break
75314
+ case "chrY":
75315
+ record["ncbi"] = "22";
75316
+ record["assembly"] = "Y";
75317
+ break
75318
+ case "X":
75319
+ record["ucsc"] = "chrX";
75320
+ record["ncbi"] = "21";
75321
+ break
75322
+ case "Y":
75323
+ record["ucsc"] = "chrY";
75324
+ record["ncbi"] = "22";
75325
+ break
75326
+
75327
+ }
75328
+ }
75329
+ }
75330
+ }
75331
+
75332
+
75333
+ for (let rec of aliasRecords) {
75334
+ ChromAliasDefaults.addCaseAliases(rec);
75335
+ for (let a of Object.values(rec)) {
75336
+ this.aliasRecordCache.set(a, rec);
75337
+ }
75338
+ }
75339
+
75340
+ }
75341
+ }
75342
+
75343
+ search(alias) {
75344
+ return this.aliasRecordCache.get(alias)
75345
+
75346
+ }
75347
+
75348
+ /**
75349
+ * Extract the user friendly name from an NCBI accession
75350
+ * example: gi|125745044|ref|NC_002229.3| => NC_002229.3
75351
+ */
75352
+ static getNCBIName(name) {
75353
+ const tokens = name.split("\\|");
75354
+ return tokens[tokens.length - 1]
75355
+ }
75356
+
75357
+ static addCaseAliases(aliasRecord) {
75358
+
75359
+ // Add some aliases for case insensitivy
75360
+ const upper = aliasRecord.chr.toUpperCase();
75361
+ const lower = aliasRecord.chr.toLowerCase();
75362
+ const cap = aliasRecord.chr.charAt(0).toUpperCase() + aliasRecord.chr.slice(1);
75363
+ if(aliasRecord.chr !== upper) {
75364
+ aliasRecord["_uppercase"] = upper;
75365
+ }
75366
+ if(aliasRecord.chr !== lower) {
75367
+ aliasRecord["_lowercase"] = lower;
75368
+ }
75369
+ if(aliasRecord.chr !== cap) {
75370
+ aliasRecord["_cap"] = cap;
75371
+ }
75372
+
75373
+ }
75374
+
75375
+ }
75376
+
75195
75377
  /**
75196
75378
  * Chromosome alias source backed by a UCSC bigbed file
75197
75379
  *
@@ -75254,6 +75436,7 @@
75254
75436
  if (!this.aliasRecordCache.has(alias)) {
75255
75437
  const aliasRecord = await this.reader.search(alias);
75256
75438
  if (aliasRecord) {
75439
+ ChromAliasDefaults.addCaseAliases(aliasRecord);
75257
75440
  for (let key of Object.keys(aliasRecord)) {
75258
75441
  if ("start" !== key && "end" !== key) {
75259
75442
  this.aliasRecordCache.set(aliasRecord[key], aliasRecord);
@@ -75344,14 +75527,16 @@
75344
75527
  }
75345
75528
 
75346
75529
  const aliasRecord = {chr};
75530
+ ChromAliasDefaults.addCaseAliases(aliasRecord);
75347
75531
  for (let i = 0; i < tokens.length; i++) {
75348
75532
  const key = this.headings ? this.headings[i] : i;
75349
75533
  aliasRecord[key] = tokens[i];
75350
- this.aliasRecordCache.set(tokens[i], aliasRecord);
75351
75534
  }
75352
75535
 
75353
- this.aliasRecordCache.set(chr.toLowerCase(), aliasRecord);
75354
- this.aliasRecordCache.set(chr.toUpperCase(), aliasRecord);
75536
+ for (let a of Object.values(aliasRecord)) {
75537
+ this.aliasRecordCache.set(a, aliasRecord);
75538
+ }
75539
+
75355
75540
  }
75356
75541
  }
75357
75542
  }
@@ -75509,170 +75694,6 @@
75509
75694
 
75510
75695
  }
75511
75696
 
75512
- /**
75513
- * Default chromosome aliases, mostly 1<->chr1 etc. Used if chrom alias file is not supplied.
75514
- *
75515
- */
75516
-
75517
- class ChromAliasDefaults {
75518
-
75519
- aliasRecordCache = new Map()
75520
-
75521
- constructor(id, chromosomeNames) {
75522
- this.genomeID = id;
75523
- this.update(id, chromosomeNames);
75524
- }
75525
-
75526
- async preload() {
75527
- // no-op
75528
- }
75529
-
75530
- /**
75531
- * Return the canonical chromosome name for the alias. If none found return the alias
75532
- *
75533
- * @param alias
75534
- * @returns {*}
75535
- */
75536
- getChromosomeName(alias) {
75537
- return this.aliasRecordCache.has(alias) ? this.aliasRecordCache.get(alias).chr : alias
75538
- }
75539
-
75540
- /**
75541
- * Return an alternate chromosome name (alias).
75542
- *
75543
- * @param chr
75544
- * @param nameSet -- The name set, e.g. "ucsc"
75545
- * @returns {*|undefined}
75546
- */
75547
- getChromosomeAlias(chr, nameSet) {
75548
- const aliasRecord = this.aliasRecordCache.get(chr);
75549
- return aliasRecord ? aliasRecord[nameSet] || chr : chr
75550
- }
75551
-
75552
- update(id, chromosomeNames) {
75553
-
75554
- if (chromosomeNames) {
75555
- const aliasRecords = [];
75556
- for (let name of chromosomeNames) {
75557
-
75558
- if(this.aliasRecordCache.has(name)) {
75559
- continue;
75560
- }
75561
-
75562
- const record = {chr: name};
75563
- aliasRecords.push(record);
75564
-
75565
- if (name.startsWith("gi|")) {
75566
- // NCBI
75567
- const alias = ChromAliasDefaults.getNCBIName(name);
75568
- record["ncbi-gi-versioned"] = alias;
75569
-
75570
- // Also strip version number out, if present
75571
- const dotIndex = alias.lastIndexOf('.');
75572
- if (dotIndex > 0) {
75573
- const alias = alias.substring(0, dotIndex);
75574
- record["ncbi-gi"] = alias;
75575
- }
75576
- } else {
75577
-
75578
- if (name === "chrM") {
75579
- record["ncbi"] = "MT";
75580
- } else if (name === "MT") {
75581
- record["ucsc"] = "chrM";
75582
- } else if (name.toLowerCase().startsWith("chr") && Number.isInteger(Number(name.substring(3)))) {
75583
- record["ncbi"] = name.substring(3);
75584
- } else if (Number.isInteger(Number(name))) {
75585
- record["ucsc"] = "chr" + name;
75586
- }
75587
-
75588
- // Special cases for human and mouse
75589
- if (id.startsWith("hg") || id.startsWith("GRCh") || id === "1kg_ref" || id === "b37") {
75590
- switch (name) {
75591
- case "23":
75592
- record["ucsc"] = "chrX";
75593
- record["assembly"] = "X";
75594
- break
75595
- case "24":
75596
- record["ucsc"] = "chrY";
75597
- record["assembly"] = "Y";
75598
- break
75599
- case "chrX":
75600
- record["ncbi"] = "23";
75601
- record["assembly"] = "X";
75602
- break
75603
- case "chrY":
75604
- record["ncbi"] = "24";
75605
- record["assembly"] = "Y";
75606
- break
75607
- case "X":
75608
- record["ucsc"] = "chrX";
75609
- record["ncbi"] = "23";
75610
- break
75611
- case "Y":
75612
- record["ucsc"] = "chrY";
75613
- record["ncbi"] = "24";
75614
- break
75615
-
75616
- }
75617
- } else if (id.startsWith("mm") || id.startsWith("GRCm") || id.startsWith("rheMac")) {
75618
- switch (name) {
75619
- case "21":
75620
- record["ucsc"] = "chrX";
75621
- record["assembly"] = "X";
75622
- break
75623
- case "22":
75624
- record["ucsc"] = "chrY";
75625
- record["assembly"] = "Y";
75626
- break
75627
- case "chrX":
75628
- record["ncbi"] = "21";
75629
- record["assembly"] = "X";
75630
- break
75631
- case "chrY":
75632
- record["ncbi"] = "22";
75633
- record["assembly"] = "Y";
75634
- break
75635
- case "X":
75636
- record["ucsc"] = "chrX";
75637
- record["ncbi"] = "21";
75638
- break
75639
- case "Y":
75640
- record["ucsc"] = "chrY";
75641
- record["ncbi"] = "22";
75642
- break
75643
-
75644
- }
75645
- }
75646
- }
75647
- }
75648
-
75649
- for (let rec of aliasRecords) {
75650
- for (let a of Object.values(rec)) {
75651
- this.aliasRecordCache.set(a, rec);
75652
- }
75653
- this.aliasRecordCache.set(rec.chr.toLowerCase(), rec);
75654
- this.aliasRecordCache.set(rec.chr.toUpperCase(), rec);
75655
- }
75656
-
75657
- }
75658
- }
75659
-
75660
- search(alias) {
75661
- return this.aliasRecordCache.get(alias)
75662
-
75663
- }
75664
-
75665
- /**
75666
- * Extract the user friendly name from an NCBI accession
75667
- * example: gi|125745044|ref|NC_002229.3| => NC_002229.3
75668
- */
75669
- static getNCBIName(name) {
75670
- const tokens = name.split("\\|");
75671
- return tokens[tokens.length - 1]
75672
- }
75673
-
75674
- }
75675
-
75676
75697
  /**
75677
75698
  * The Genome class represents an assembly and consists of the following elements
75678
75699
  * sequence - Object representing the DNA sequence
@@ -75854,6 +75875,21 @@
75854
75875
  if (!aliasRecord && chr !== chr.toLowerCase()) {
75855
75876
  aliasRecord = await this.chromAlias.search(chr.toLowerCase());
75856
75877
  }
75878
+ if(aliasRecord) {
75879
+ // Add some aliases for case insensitivy
75880
+ const upper = aliasRecord.chr.toUpperCase();
75881
+ const lower = aliasRecord.chr.toLowerCase();
75882
+ const cap = aliasRecord.chr.charAt(0).toUpperCase() + aliasRecord.chr.slice(1);
75883
+ if(aliasRecord.chr !== upper) {
75884
+ aliasRecord["_uppercase"] = upper;
75885
+ }
75886
+ if(aliasRecord.chr !== lower) {
75887
+ aliasRecord["_lowercase"] = lower;
75888
+ }
75889
+ if(aliasRecord.chr !== cap) {
75890
+ aliasRecord["_cap"] = cap;
75891
+ }
75892
+ }
75857
75893
  this.#aliasRecordCache.set(chr, aliasRecord); // Set even if undefined to prevent recurrent searches
75858
75894
  return aliasRecord
75859
75895
  }