@teselagen/ove 0.7.34 → 0.7.36

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/README.md CHANGED
@@ -713,6 +713,6 @@ you can either add your test to an existing cypress file or make a new test file
713
713
 
714
714
  once you're satisfied, make a pull request back to tg-oss and mention @tnrich
715
715
 
716
- ```
716
+ ## Running unit tests
717
717
 
718
- ```
718
+ Run `bun test` from the root of the repo to execute all unit tests.
package/index.cjs.js CHANGED
@@ -36818,6 +36818,9 @@ const defaultValidators = {
36818
36818
  }, "dropdownMulti"),
36819
36819
  number: /* @__PURE__ */ __name((newVal2, field) => {
36820
36820
  if (isValueEmpty(newVal2) && !field.isRequired) return;
36821
+ if (field.allowNaN && Number.isNaN(newVal2)) {
36822
+ return;
36823
+ }
36821
36824
  if (isNaN(newVal2) || !isNumber$2(newVal2)) {
36822
36825
  return "Must be a number";
36823
36826
  }
@@ -82982,6 +82985,14 @@ const proteinAlphabet = {
82982
82985
  color: "hsl(264.7, 100%, 69%)",
82983
82986
  mass: 128.17228
82984
82987
  },
82988
+ O: {
82989
+ value: "O",
82990
+ name: "Pyrrolysine",
82991
+ threeLettersName: "Pyl",
82992
+ colorByFamily: "#FFC0CB",
82993
+ color: "hsl(264.7, 100%, 69%)",
82994
+ mass: 255.313
82995
+ },
82985
82996
  M: {
82986
82997
  value: "M",
82987
82998
  name: "Methionine",
@@ -83128,7 +83139,7 @@ const proteinAlphabet = {
83128
83139
  mass: 0
83129
83140
  }
83130
83141
  };
83131
- const threeLetterSequenceStringToAminoAcidMap = {
83142
+ const initThreeLetterSequenceStringToAminoAcidMap = {
83132
83143
  gct: proteinAlphabet.A,
83133
83144
  gcc: proteinAlphabet.A,
83134
83145
  gca: proteinAlphabet.A,
@@ -83227,9 +83238,74 @@ const threeLetterSequenceStringToAminoAcidMap = {
83227
83238
  taa: proteinAlphabet["*"],
83228
83239
  tag: proteinAlphabet["*"],
83229
83240
  tga: proteinAlphabet["*"],
83241
+ uaa: proteinAlphabet["*"],
83242
+ uag: proteinAlphabet["*"],
83243
+ uga: proteinAlphabet["*"],
83230
83244
  "...": proteinAlphabet["."],
83231
83245
  "---": proteinAlphabet["-"]
83232
83246
  };
83247
+ const IUPAC = {
83248
+ A: ["A"],
83249
+ C: ["C"],
83250
+ G: ["G"],
83251
+ T: ["T"],
83252
+ U: ["U"],
83253
+ R: ["A", "G"],
83254
+ Y: ["C", "T", "U"],
83255
+ K: ["G", "T", "U"],
83256
+ M: ["A", "C"],
83257
+ S: ["G", "C"],
83258
+ W: ["A", "T", "U"],
83259
+ B: ["C", "G", "T", "U"],
83260
+ D: ["A", "G", "T", "U"],
83261
+ H: ["A", "C", "T", "U"],
83262
+ V: ["A", "C", "G"],
83263
+ N: ["A", "C", "G", "T", "U"],
83264
+ X: ["A", "C", "G", "T", "U"]
83265
+ };
83266
+ function expandAndResolve(threeLetterCodon) {
83267
+ var _a2, _b2;
83268
+ const chars = threeLetterCodon.toUpperCase().split("");
83269
+ const picks = chars.map((c2) => IUPAC[c2] || [c2]);
83270
+ let allPossibleThreeLetterCodons = [""];
83271
+ for (const set6 of picks) {
83272
+ const next = [];
83273
+ for (const prefix2 of allPossibleThreeLetterCodons) for (const b3 of set6) next.push(prefix2 + b3);
83274
+ allPossibleThreeLetterCodons = next;
83275
+ }
83276
+ let foundAminoAcid = null;
83277
+ for (const codon of allPossibleThreeLetterCodons) {
83278
+ const lowerCodon = codon.toLowerCase();
83279
+ const aminoAcidObj = (_b2 = (_a2 = initThreeLetterSequenceStringToAminoAcidMap[lowerCodon]) != null ? _a2 : initThreeLetterSequenceStringToAminoAcidMap[lowerCodon.replace(/u/g, "t")]) != null ? _b2 : initThreeLetterSequenceStringToAminoAcidMap[lowerCodon.replace(/t/g, "u")];
83280
+ if (aminoAcidObj) {
83281
+ if (!foundAminoAcid) {
83282
+ foundAminoAcid = aminoAcidObj;
83283
+ } else if (foundAminoAcid.value !== aminoAcidObj.value) {
83284
+ return null;
83285
+ }
83286
+ } else {
83287
+ return null;
83288
+ }
83289
+ }
83290
+ return foundAminoAcid;
83291
+ }
83292
+ __name(expandAndResolve, "expandAndResolve");
83293
+ function getCodonToAminoAcidMap() {
83294
+ const map3 = initThreeLetterSequenceStringToAminoAcidMap;
83295
+ const codes = Object.keys(IUPAC);
83296
+ for (const a2 of codes)
83297
+ for (const b3 of codes)
83298
+ for (const c2 of codes) {
83299
+ const codon = a2 + b3 + c2;
83300
+ const lowerCodon = codon.toLowerCase();
83301
+ if (map3[lowerCodon]) continue;
83302
+ const aminoAcidObj = expandAndResolve(codon);
83303
+ if (aminoAcidObj) map3[lowerCodon] = aminoAcidObj;
83304
+ }
83305
+ return map3;
83306
+ }
83307
+ __name(getCodonToAminoAcidMap, "getCodonToAminoAcidMap");
83308
+ const threeLetterSequenceStringToAminoAcidMap = getCodonToAminoAcidMap();
83233
83309
  const degenerateDnaToAminoAcidMap = invert(aminoAcidToDegenerateDnaMap);
83234
83310
  function getAminoAcidFromSequenceTriplet(sequenceString) {
83235
83311
  sequenceString = sequenceString.toLowerCase();
@@ -83342,7 +83418,7 @@ function getAminoAcidDataForEachBaseOfDna(originalSequenceString, forward, optio
83342
83418
  const aminoAcidDataForEachBaseOfDNA = [];
83343
83419
  for (let index2 = 0; index2 < sequenceStringLength; index2 += 3) {
83344
83420
  let aminoAcid;
83345
- const aminoAcidIndex = index2 / 3;
83421
+ const aminoAcidIndex = Math.floor(index2 / 3);
83346
83422
  let codonPositionsInCDS;
83347
83423
  let basesRead;
83348
83424
  if (isProteinSequence) {
@@ -83516,7 +83592,7 @@ function getAcceptedChars({
83516
83592
  isRna: isRna2,
83517
83593
  isMixedRnaAndDna
83518
83594
  } = {}) {
83519
- return isProtein2 ? `${extended_protein_letters.toLowerCase()}}` : isOligo2 ? ambiguous_rna_letters.toLowerCase() + "t" : isRna2 ? ambiguous_rna_letters.toLowerCase() + "t" : isMixedRnaAndDna ? ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase() : (
83595
+ return isProtein2 ? `${extended_protein_letters.toLowerCase()}` : isOligo2 ? ambiguous_rna_letters.toLowerCase() + "t" : isRna2 ? ambiguous_rna_letters.toLowerCase() + "t" : isMixedRnaAndDna ? ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase() : (
83520
83596
  //just plain old dna
83521
83597
  ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase()
83522
83598
  );
@@ -84530,7 +84606,7 @@ function adjustAnnotationsToDelete(annotationsToBeAdjusted, range2, maxLength) {
84530
84606
  return __spreadValues(__spreadProps(__spreadValues({}, newRange), {
84531
84607
  start: newLocations[0].start,
84532
84608
  end: newLocations[newLocations.length - 1].end
84533
- }), newLocations.length > 1 && { locations: newLocations });
84609
+ }), newLocations.length > 0 && { locations: newLocations });
84534
84610
  } else {
84535
84611
  return newRange;
84536
84612
  }
@@ -117456,6 +117532,7 @@ function SelectionLayer$2(props) {
117456
117532
  __spreadValues({
117457
117533
  key: key + "caret1"
117458
117534
  }, {
117535
+ isProtein: isProtein2,
117459
117536
  leftMargin,
117460
117537
  onClick: _onClick || preventDefaultStopPropagation,
117461
117538
  onRightClick: onSelectionContextMenu,
@@ -117475,6 +117552,7 @@ function SelectionLayer$2(props) {
117475
117552
  __spreadValues({
117476
117553
  key: key + "caret2"
117477
117554
  }, {
117555
+ isProtein: isProtein2,
117478
117556
  leftMargin,
117479
117557
  onClick: _onClick || preventDefaultStopPropagation,
117480
117558
  onRightClick: onSelectionContextMenu,
@@ -122498,7 +122576,8 @@ function Chromatogram(props) {
122498
122576
  noQualityScores: !showChromQualScores
122499
122577
  }),
122500
122578
  style: {
122501
- position: "relative"
122579
+ position: "relative",
122580
+ textAlign: "left"
122502
122581
  },
122503
122582
  onContextMenu: /* @__PURE__ */ __name((e) => {
122504
122583
  showContextMenu([chromatogramMenu], void 0, e);
@@ -123355,7 +123434,8 @@ function RowItem(props) {
123355
123434
  ), caretPosition2 > -1 && /* @__PURE__ */ React.createElement(
123356
123435
  Caret$2,
123357
123436
  __spreadProps(__spreadValues({
123358
- caretPosition: caretPosition2
123437
+ caretPosition: caretPosition2,
123438
+ isProtein: isProtein2
123359
123439
  }, __spreadValues(__spreadValues({}, annotationCommonProps), { getGaps: void 0 })), {
123360
123440
  row: alignmentData ? { start: 0, end: alignmentData.sequence.length - 1 } : row
123361
123441
  })
@@ -124880,7 +124960,7 @@ function showFileDialog({ multiple = false, onSelect }) {
124880
124960
  input.click();
124881
124961
  }
124882
124962
  __name(showFileDialog, "showFileDialog");
124883
- const version = "0.7.33";
124963
+ const version = "0.7.35";
124884
124964
  const packageJson = {
124885
124965
  version
124886
124966
  };
@@ -128593,7 +128673,8 @@ const _SequenceInputNoHotkeys = class _SequenceInputNoHotkeys extends React.Comp
128593
128673
  return;
128594
128674
  }
128595
128675
  const seqToInsert = isProtein2 ? {
128596
- proteinSequence: charsToInsert
128676
+ proteinSequence: charsToInsert,
128677
+ isProtein: true
128597
128678
  } : {
128598
128679
  sequence: charsToInsert
128599
128680
  };
@@ -128655,10 +128736,9 @@ const _SequenceInputNoHotkeys = class _SequenceInputNoHotkeys extends React.Comp
128655
128736
  });
128656
128737
  }, 200);
128657
128738
  }
128658
- if (maxInsertSize && sanitizedVal.lenth > maxInsertSize) {
128739
+ if (maxInsertSize && sanitizedVal.length > maxInsertSize) {
128659
128740
  return window.toastr.error(
128660
- "Sorry, your insert is greater than ",
128661
- maxInsertSize
128741
+ `Sorry, your insert is greater than ${maxInsertSize}`
128662
128742
  );
128663
128743
  }
128664
128744
  e.target.value = sanitizedVal;
@@ -129518,7 +129598,8 @@ function VectorInteractionHOC(Component) {
129518
129598
  readOnly: readOnly2,
129519
129599
  onPaste,
129520
129600
  disableBpEditing,
129521
- sequenceData: sequenceData2
129601
+ sequenceData: sequenceData2,
129602
+ maxInsertSize
129522
129603
  } = this.props;
129523
129604
  if (disableBpEditing) {
129524
129605
  return this.createDisableBpEditingMsg();
@@ -129545,6 +129626,11 @@ function VectorInteractionHOC(Component) {
129545
129626
  if (sequenceData2.isProtein && !seqDataToInsert.proteinSequence) {
129546
129627
  seqDataToInsert.proteinSequence = seqDataToInsert.sequence;
129547
129628
  }
129629
+ if (maxInsertSize && (seqDataToInsert.proteinSequence || seqDataToInsert.sequence).length > maxInsertSize) {
129630
+ return window.toastr.error(
129631
+ `Sorry, the pasted sequence exceeds the maximum allowed length of ${maxInsertSize}`
129632
+ );
129633
+ }
129548
129634
  seqDataToInsert = tidyUpSequenceData(seqDataToInsert, {
129549
129635
  topLevelSeqData: sequenceData2,
129550
129636
  provideNewIdsForAnnotations: true,
@@ -129659,7 +129745,8 @@ function VectorInteractionHOC(Component) {
129659
129745
  selectionLayer: selectionLayer2 = { start: -1, end: -1 },
129660
129746
  sequenceData: sequenceData2 = { sequence: "" },
129661
129747
  readOnly: readOnly2,
129662
- disableBpEditing
129748
+ disableBpEditing,
129749
+ maxInsertSize
129663
129750
  // updateSequenceData,
129664
129751
  // wrappedInsertSequenceDataAtPositionOrRange
129665
129752
  // handleInsert
@@ -129680,6 +129767,7 @@ function VectorInteractionHOC(Component) {
129680
129767
  selectionLayer: selectionLayer2,
129681
129768
  sequenceLength,
129682
129769
  caretPosition: caretPosition2,
129770
+ maxInsertSize,
129683
129771
  handleInsert: /* @__PURE__ */ __name((seqDataToInsert) => __async(this, null, function* () {
129684
129772
  yield insertAndSelectHelper({
129685
129773
  props: this.props,
@@ -130038,6 +130126,8 @@ function VectorInteractionHOC(Component) {
130038
130126
  [this.commandEnhancer],
130039
130127
  e,
130040
130128
  () => {
130129
+ document.body.removeEventListener("cut", this.handleCut);
130130
+ document.body.removeEventListener("copy", this.handleCopy);
130041
130131
  if (lastFocusedEl) {
130042
130132
  lastFocusedEl.focus();
130043
130133
  }
@@ -133585,6 +133675,7 @@ function SelectionLayer({
133585
133675
  onClick: onClick ? noop$4 : preventDefaultStopPropagation,
133586
133676
  selectionMessage,
133587
133677
  caretPosition: start2,
133678
+ isProtein: isProtein2,
133588
133679
  sequenceLength,
133589
133680
  innerRadius,
133590
133681
  outerRadius: radius
@@ -133599,6 +133690,7 @@ function SelectionLayer({
133599
133690
  onClick: onClick ? noop$4 : preventDefaultStopPropagation,
133600
133691
  selectionMessage,
133601
133692
  caretPosition: end2 + 1,
133693
+ isProtein: isProtein2,
133602
133694
  sequenceLength,
133603
133695
  innerRadius,
133604
133696
  outerRadius: radius
@@ -152958,6 +153050,7 @@ const _Editor = class _Editor extends React.Component {
152958
153050
  hideStatusBar,
152959
153051
  hoveredId,
152960
153052
  isFullscreen,
153053
+ maxInsertSize,
152961
153054
  maxAnnotationsToDisplay,
152962
153055
  minHeight = 400,
152963
153056
  onlyShowLabelsThatDoNotFit = true,
@@ -153145,6 +153238,7 @@ const _Editor = class _Editor extends React.Component {
153145
153238
  doubleClickOverrides: this.props.doubleClickOverrides
153146
153239
  }), panelPropsToSpread), {
153147
153240
  editorName,
153241
+ maxInsertSize,
153148
153242
  isProtein: sequenceData2.isProtein,
153149
153243
  onlyShowLabelsThatDoNotFit,
153150
153244
  tabHeight,
package/index.es.js CHANGED
@@ -36800,6 +36800,9 @@ const defaultValidators = {
36800
36800
  }, "dropdownMulti"),
36801
36801
  number: /* @__PURE__ */ __name((newVal2, field) => {
36802
36802
  if (isValueEmpty(newVal2) && !field.isRequired) return;
36803
+ if (field.allowNaN && Number.isNaN(newVal2)) {
36804
+ return;
36805
+ }
36803
36806
  if (isNaN(newVal2) || !isNumber$2(newVal2)) {
36804
36807
  return "Must be a number";
36805
36808
  }
@@ -82964,6 +82967,14 @@ const proteinAlphabet = {
82964
82967
  color: "hsl(264.7, 100%, 69%)",
82965
82968
  mass: 128.17228
82966
82969
  },
82970
+ O: {
82971
+ value: "O",
82972
+ name: "Pyrrolysine",
82973
+ threeLettersName: "Pyl",
82974
+ colorByFamily: "#FFC0CB",
82975
+ color: "hsl(264.7, 100%, 69%)",
82976
+ mass: 255.313
82977
+ },
82967
82978
  M: {
82968
82979
  value: "M",
82969
82980
  name: "Methionine",
@@ -83110,7 +83121,7 @@ const proteinAlphabet = {
83110
83121
  mass: 0
83111
83122
  }
83112
83123
  };
83113
- const threeLetterSequenceStringToAminoAcidMap = {
83124
+ const initThreeLetterSequenceStringToAminoAcidMap = {
83114
83125
  gct: proteinAlphabet.A,
83115
83126
  gcc: proteinAlphabet.A,
83116
83127
  gca: proteinAlphabet.A,
@@ -83209,9 +83220,74 @@ const threeLetterSequenceStringToAminoAcidMap = {
83209
83220
  taa: proteinAlphabet["*"],
83210
83221
  tag: proteinAlphabet["*"],
83211
83222
  tga: proteinAlphabet["*"],
83223
+ uaa: proteinAlphabet["*"],
83224
+ uag: proteinAlphabet["*"],
83225
+ uga: proteinAlphabet["*"],
83212
83226
  "...": proteinAlphabet["."],
83213
83227
  "---": proteinAlphabet["-"]
83214
83228
  };
83229
+ const IUPAC = {
83230
+ A: ["A"],
83231
+ C: ["C"],
83232
+ G: ["G"],
83233
+ T: ["T"],
83234
+ U: ["U"],
83235
+ R: ["A", "G"],
83236
+ Y: ["C", "T", "U"],
83237
+ K: ["G", "T", "U"],
83238
+ M: ["A", "C"],
83239
+ S: ["G", "C"],
83240
+ W: ["A", "T", "U"],
83241
+ B: ["C", "G", "T", "U"],
83242
+ D: ["A", "G", "T", "U"],
83243
+ H: ["A", "C", "T", "U"],
83244
+ V: ["A", "C", "G"],
83245
+ N: ["A", "C", "G", "T", "U"],
83246
+ X: ["A", "C", "G", "T", "U"]
83247
+ };
83248
+ function expandAndResolve(threeLetterCodon) {
83249
+ var _a2, _b2;
83250
+ const chars = threeLetterCodon.toUpperCase().split("");
83251
+ const picks = chars.map((c2) => IUPAC[c2] || [c2]);
83252
+ let allPossibleThreeLetterCodons = [""];
83253
+ for (const set6 of picks) {
83254
+ const next = [];
83255
+ for (const prefix2 of allPossibleThreeLetterCodons) for (const b3 of set6) next.push(prefix2 + b3);
83256
+ allPossibleThreeLetterCodons = next;
83257
+ }
83258
+ let foundAminoAcid = null;
83259
+ for (const codon of allPossibleThreeLetterCodons) {
83260
+ const lowerCodon = codon.toLowerCase();
83261
+ const aminoAcidObj = (_b2 = (_a2 = initThreeLetterSequenceStringToAminoAcidMap[lowerCodon]) != null ? _a2 : initThreeLetterSequenceStringToAminoAcidMap[lowerCodon.replace(/u/g, "t")]) != null ? _b2 : initThreeLetterSequenceStringToAminoAcidMap[lowerCodon.replace(/t/g, "u")];
83262
+ if (aminoAcidObj) {
83263
+ if (!foundAminoAcid) {
83264
+ foundAminoAcid = aminoAcidObj;
83265
+ } else if (foundAminoAcid.value !== aminoAcidObj.value) {
83266
+ return null;
83267
+ }
83268
+ } else {
83269
+ return null;
83270
+ }
83271
+ }
83272
+ return foundAminoAcid;
83273
+ }
83274
+ __name(expandAndResolve, "expandAndResolve");
83275
+ function getCodonToAminoAcidMap() {
83276
+ const map3 = initThreeLetterSequenceStringToAminoAcidMap;
83277
+ const codes = Object.keys(IUPAC);
83278
+ for (const a2 of codes)
83279
+ for (const b3 of codes)
83280
+ for (const c2 of codes) {
83281
+ const codon = a2 + b3 + c2;
83282
+ const lowerCodon = codon.toLowerCase();
83283
+ if (map3[lowerCodon]) continue;
83284
+ const aminoAcidObj = expandAndResolve(codon);
83285
+ if (aminoAcidObj) map3[lowerCodon] = aminoAcidObj;
83286
+ }
83287
+ return map3;
83288
+ }
83289
+ __name(getCodonToAminoAcidMap, "getCodonToAminoAcidMap");
83290
+ const threeLetterSequenceStringToAminoAcidMap = getCodonToAminoAcidMap();
83215
83291
  const degenerateDnaToAminoAcidMap = invert(aminoAcidToDegenerateDnaMap);
83216
83292
  function getAminoAcidFromSequenceTriplet(sequenceString) {
83217
83293
  sequenceString = sequenceString.toLowerCase();
@@ -83324,7 +83400,7 @@ function getAminoAcidDataForEachBaseOfDna(originalSequenceString, forward, optio
83324
83400
  const aminoAcidDataForEachBaseOfDNA = [];
83325
83401
  for (let index2 = 0; index2 < sequenceStringLength; index2 += 3) {
83326
83402
  let aminoAcid;
83327
- const aminoAcidIndex = index2 / 3;
83403
+ const aminoAcidIndex = Math.floor(index2 / 3);
83328
83404
  let codonPositionsInCDS;
83329
83405
  let basesRead;
83330
83406
  if (isProteinSequence) {
@@ -83498,7 +83574,7 @@ function getAcceptedChars({
83498
83574
  isRna: isRna2,
83499
83575
  isMixedRnaAndDna
83500
83576
  } = {}) {
83501
- return isProtein2 ? `${extended_protein_letters.toLowerCase()}}` : isOligo2 ? ambiguous_rna_letters.toLowerCase() + "t" : isRna2 ? ambiguous_rna_letters.toLowerCase() + "t" : isMixedRnaAndDna ? ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase() : (
83577
+ return isProtein2 ? `${extended_protein_letters.toLowerCase()}` : isOligo2 ? ambiguous_rna_letters.toLowerCase() + "t" : isRna2 ? ambiguous_rna_letters.toLowerCase() + "t" : isMixedRnaAndDna ? ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase() : (
83502
83578
  //just plain old dna
83503
83579
  ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase()
83504
83580
  );
@@ -84512,7 +84588,7 @@ function adjustAnnotationsToDelete(annotationsToBeAdjusted, range2, maxLength) {
84512
84588
  return __spreadValues(__spreadProps(__spreadValues({}, newRange), {
84513
84589
  start: newLocations[0].start,
84514
84590
  end: newLocations[newLocations.length - 1].end
84515
- }), newLocations.length > 1 && { locations: newLocations });
84591
+ }), newLocations.length > 0 && { locations: newLocations });
84516
84592
  } else {
84517
84593
  return newRange;
84518
84594
  }
@@ -117438,6 +117514,7 @@ function SelectionLayer$2(props) {
117438
117514
  __spreadValues({
117439
117515
  key: key + "caret1"
117440
117516
  }, {
117517
+ isProtein: isProtein2,
117441
117518
  leftMargin,
117442
117519
  onClick: _onClick || preventDefaultStopPropagation,
117443
117520
  onRightClick: onSelectionContextMenu,
@@ -117457,6 +117534,7 @@ function SelectionLayer$2(props) {
117457
117534
  __spreadValues({
117458
117535
  key: key + "caret2"
117459
117536
  }, {
117537
+ isProtein: isProtein2,
117460
117538
  leftMargin,
117461
117539
  onClick: _onClick || preventDefaultStopPropagation,
117462
117540
  onRightClick: onSelectionContextMenu,
@@ -122480,7 +122558,8 @@ function Chromatogram(props) {
122480
122558
  noQualityScores: !showChromQualScores
122481
122559
  }),
122482
122560
  style: {
122483
- position: "relative"
122561
+ position: "relative",
122562
+ textAlign: "left"
122484
122563
  },
122485
122564
  onContextMenu: /* @__PURE__ */ __name((e) => {
122486
122565
  showContextMenu([chromatogramMenu], void 0, e);
@@ -123337,7 +123416,8 @@ function RowItem(props) {
123337
123416
  ), caretPosition2 > -1 && /* @__PURE__ */ React__default.createElement(
123338
123417
  Caret$2,
123339
123418
  __spreadProps(__spreadValues({
123340
- caretPosition: caretPosition2
123419
+ caretPosition: caretPosition2,
123420
+ isProtein: isProtein2
123341
123421
  }, __spreadValues(__spreadValues({}, annotationCommonProps), { getGaps: void 0 })), {
123342
123422
  row: alignmentData ? { start: 0, end: alignmentData.sequence.length - 1 } : row
123343
123423
  })
@@ -124862,7 +124942,7 @@ function showFileDialog({ multiple = false, onSelect }) {
124862
124942
  input.click();
124863
124943
  }
124864
124944
  __name(showFileDialog, "showFileDialog");
124865
- const version = "0.7.33";
124945
+ const version = "0.7.35";
124866
124946
  const packageJson = {
124867
124947
  version
124868
124948
  };
@@ -128575,7 +128655,8 @@ const _SequenceInputNoHotkeys = class _SequenceInputNoHotkeys extends React__def
128575
128655
  return;
128576
128656
  }
128577
128657
  const seqToInsert = isProtein2 ? {
128578
- proteinSequence: charsToInsert
128658
+ proteinSequence: charsToInsert,
128659
+ isProtein: true
128579
128660
  } : {
128580
128661
  sequence: charsToInsert
128581
128662
  };
@@ -128637,10 +128718,9 @@ const _SequenceInputNoHotkeys = class _SequenceInputNoHotkeys extends React__def
128637
128718
  });
128638
128719
  }, 200);
128639
128720
  }
128640
- if (maxInsertSize && sanitizedVal.lenth > maxInsertSize) {
128721
+ if (maxInsertSize && sanitizedVal.length > maxInsertSize) {
128641
128722
  return window.toastr.error(
128642
- "Sorry, your insert is greater than ",
128643
- maxInsertSize
128723
+ `Sorry, your insert is greater than ${maxInsertSize}`
128644
128724
  );
128645
128725
  }
128646
128726
  e.target.value = sanitizedVal;
@@ -129500,7 +129580,8 @@ function VectorInteractionHOC(Component2) {
129500
129580
  readOnly: readOnly2,
129501
129581
  onPaste,
129502
129582
  disableBpEditing,
129503
- sequenceData: sequenceData2
129583
+ sequenceData: sequenceData2,
129584
+ maxInsertSize
129504
129585
  } = this.props;
129505
129586
  if (disableBpEditing) {
129506
129587
  return this.createDisableBpEditingMsg();
@@ -129527,6 +129608,11 @@ function VectorInteractionHOC(Component2) {
129527
129608
  if (sequenceData2.isProtein && !seqDataToInsert.proteinSequence) {
129528
129609
  seqDataToInsert.proteinSequence = seqDataToInsert.sequence;
129529
129610
  }
129611
+ if (maxInsertSize && (seqDataToInsert.proteinSequence || seqDataToInsert.sequence).length > maxInsertSize) {
129612
+ return window.toastr.error(
129613
+ `Sorry, the pasted sequence exceeds the maximum allowed length of ${maxInsertSize}`
129614
+ );
129615
+ }
129530
129616
  seqDataToInsert = tidyUpSequenceData(seqDataToInsert, {
129531
129617
  topLevelSeqData: sequenceData2,
129532
129618
  provideNewIdsForAnnotations: true,
@@ -129641,7 +129727,8 @@ function VectorInteractionHOC(Component2) {
129641
129727
  selectionLayer: selectionLayer2 = { start: -1, end: -1 },
129642
129728
  sequenceData: sequenceData2 = { sequence: "" },
129643
129729
  readOnly: readOnly2,
129644
- disableBpEditing
129730
+ disableBpEditing,
129731
+ maxInsertSize
129645
129732
  // updateSequenceData,
129646
129733
  // wrappedInsertSequenceDataAtPositionOrRange
129647
129734
  // handleInsert
@@ -129662,6 +129749,7 @@ function VectorInteractionHOC(Component2) {
129662
129749
  selectionLayer: selectionLayer2,
129663
129750
  sequenceLength,
129664
129751
  caretPosition: caretPosition2,
129752
+ maxInsertSize,
129665
129753
  handleInsert: /* @__PURE__ */ __name((seqDataToInsert) => __async(this, null, function* () {
129666
129754
  yield insertAndSelectHelper({
129667
129755
  props: this.props,
@@ -130020,6 +130108,8 @@ function VectorInteractionHOC(Component2) {
130020
130108
  [this.commandEnhancer],
130021
130109
  e,
130022
130110
  () => {
130111
+ document.body.removeEventListener("cut", this.handleCut);
130112
+ document.body.removeEventListener("copy", this.handleCopy);
130023
130113
  if (lastFocusedEl) {
130024
130114
  lastFocusedEl.focus();
130025
130115
  }
@@ -133567,6 +133657,7 @@ function SelectionLayer({
133567
133657
  onClick: onClick ? noop$4 : preventDefaultStopPropagation,
133568
133658
  selectionMessage,
133569
133659
  caretPosition: start2,
133660
+ isProtein: isProtein2,
133570
133661
  sequenceLength,
133571
133662
  innerRadius,
133572
133663
  outerRadius: radius
@@ -133581,6 +133672,7 @@ function SelectionLayer({
133581
133672
  onClick: onClick ? noop$4 : preventDefaultStopPropagation,
133582
133673
  selectionMessage,
133583
133674
  caretPosition: end2 + 1,
133675
+ isProtein: isProtein2,
133584
133676
  sequenceLength,
133585
133677
  innerRadius,
133586
133678
  outerRadius: radius
@@ -152940,6 +153032,7 @@ const _Editor = class _Editor extends React__default.Component {
152940
153032
  hideStatusBar,
152941
153033
  hoveredId,
152942
153034
  isFullscreen,
153035
+ maxInsertSize,
152943
153036
  maxAnnotationsToDisplay,
152944
153037
  minHeight = 400,
152945
153038
  onlyShowLabelsThatDoNotFit = true,
@@ -153127,6 +153220,7 @@ const _Editor = class _Editor extends React__default.Component {
153127
153220
  doubleClickOverrides: this.props.doubleClickOverrides
153128
153221
  }), panelPropsToSpread), {
153129
153222
  editorName,
153223
+ maxInsertSize,
153130
153224
  isProtein: sequenceData2.isProtein,
153131
153225
  onlyShowLabelsThatDoNotFit,
153132
153226
  tabHeight,
package/index.umd.js CHANGED
@@ -65806,6 +65806,9 @@ ${latestSubscriptionCallbackError.current.stack}
65806
65806
  }, "dropdownMulti"),
65807
65807
  number: /* @__PURE__ */ __name((newVal2, field) => {
65808
65808
  if (isValueEmpty(newVal2) && !field.isRequired) return;
65809
+ if (field.allowNaN && Number.isNaN(newVal2)) {
65810
+ return;
65811
+ }
65809
65812
  if (isNaN(newVal2) || !isNumber$2(newVal2)) {
65810
65813
  return "Must be a number";
65811
65814
  }
@@ -111885,6 +111888,14 @@ ${latestSubscriptionCallbackError.current.stack}
111885
111888
  color: "hsl(264.7, 100%, 69%)",
111886
111889
  mass: 128.17228
111887
111890
  },
111891
+ O: {
111892
+ value: "O",
111893
+ name: "Pyrrolysine",
111894
+ threeLettersName: "Pyl",
111895
+ colorByFamily: "#FFC0CB",
111896
+ color: "hsl(264.7, 100%, 69%)",
111897
+ mass: 255.313
111898
+ },
111888
111899
  M: {
111889
111900
  value: "M",
111890
111901
  name: "Methionine",
@@ -112031,7 +112042,7 @@ ${latestSubscriptionCallbackError.current.stack}
112031
112042
  mass: 0
112032
112043
  }
112033
112044
  };
112034
- const threeLetterSequenceStringToAminoAcidMap = {
112045
+ const initThreeLetterSequenceStringToAminoAcidMap = {
112035
112046
  gct: proteinAlphabet.A,
112036
112047
  gcc: proteinAlphabet.A,
112037
112048
  gca: proteinAlphabet.A,
@@ -112130,9 +112141,74 @@ ${latestSubscriptionCallbackError.current.stack}
112130
112141
  taa: proteinAlphabet["*"],
112131
112142
  tag: proteinAlphabet["*"],
112132
112143
  tga: proteinAlphabet["*"],
112144
+ uaa: proteinAlphabet["*"],
112145
+ uag: proteinAlphabet["*"],
112146
+ uga: proteinAlphabet["*"],
112133
112147
  "...": proteinAlphabet["."],
112134
112148
  "---": proteinAlphabet["-"]
112135
112149
  };
112150
+ const IUPAC = {
112151
+ A: ["A"],
112152
+ C: ["C"],
112153
+ G: ["G"],
112154
+ T: ["T"],
112155
+ U: ["U"],
112156
+ R: ["A", "G"],
112157
+ Y: ["C", "T", "U"],
112158
+ K: ["G", "T", "U"],
112159
+ M: ["A", "C"],
112160
+ S: ["G", "C"],
112161
+ W: ["A", "T", "U"],
112162
+ B: ["C", "G", "T", "U"],
112163
+ D: ["A", "G", "T", "U"],
112164
+ H: ["A", "C", "T", "U"],
112165
+ V: ["A", "C", "G"],
112166
+ N: ["A", "C", "G", "T", "U"],
112167
+ X: ["A", "C", "G", "T", "U"]
112168
+ };
112169
+ function expandAndResolve(threeLetterCodon) {
112170
+ var _a2, _b2;
112171
+ const chars2 = threeLetterCodon.toUpperCase().split("");
112172
+ const picks = chars2.map((c2) => IUPAC[c2] || [c2]);
112173
+ let allPossibleThreeLetterCodons = [""];
112174
+ for (const set2 of picks) {
112175
+ const next = [];
112176
+ for (const prefix2 of allPossibleThreeLetterCodons) for (const b3 of set2) next.push(prefix2 + b3);
112177
+ allPossibleThreeLetterCodons = next;
112178
+ }
112179
+ let foundAminoAcid = null;
112180
+ for (const codon of allPossibleThreeLetterCodons) {
112181
+ const lowerCodon = codon.toLowerCase();
112182
+ const aminoAcidObj = (_b2 = (_a2 = initThreeLetterSequenceStringToAminoAcidMap[lowerCodon]) != null ? _a2 : initThreeLetterSequenceStringToAminoAcidMap[lowerCodon.replace(/u/g, "t")]) != null ? _b2 : initThreeLetterSequenceStringToAminoAcidMap[lowerCodon.replace(/t/g, "u")];
112183
+ if (aminoAcidObj) {
112184
+ if (!foundAminoAcid) {
112185
+ foundAminoAcid = aminoAcidObj;
112186
+ } else if (foundAminoAcid.value !== aminoAcidObj.value) {
112187
+ return null;
112188
+ }
112189
+ } else {
112190
+ return null;
112191
+ }
112192
+ }
112193
+ return foundAminoAcid;
112194
+ }
112195
+ __name(expandAndResolve, "expandAndResolve");
112196
+ function getCodonToAminoAcidMap() {
112197
+ const map2 = initThreeLetterSequenceStringToAminoAcidMap;
112198
+ const codes = Object.keys(IUPAC);
112199
+ for (const a2 of codes)
112200
+ for (const b3 of codes)
112201
+ for (const c2 of codes) {
112202
+ const codon = a2 + b3 + c2;
112203
+ const lowerCodon = codon.toLowerCase();
112204
+ if (map2[lowerCodon]) continue;
112205
+ const aminoAcidObj = expandAndResolve(codon);
112206
+ if (aminoAcidObj) map2[lowerCodon] = aminoAcidObj;
112207
+ }
112208
+ return map2;
112209
+ }
112210
+ __name(getCodonToAminoAcidMap, "getCodonToAminoAcidMap");
112211
+ const threeLetterSequenceStringToAminoAcidMap = getCodonToAminoAcidMap();
112136
112212
  const degenerateDnaToAminoAcidMap = invert(aminoAcidToDegenerateDnaMap);
112137
112213
  function getAminoAcidFromSequenceTriplet(sequenceString) {
112138
112214
  sequenceString = sequenceString.toLowerCase();
@@ -112245,7 +112321,7 @@ ${latestSubscriptionCallbackError.current.stack}
112245
112321
  const aminoAcidDataForEachBaseOfDNA = [];
112246
112322
  for (let index2 = 0; index2 < sequenceStringLength; index2 += 3) {
112247
112323
  let aminoAcid;
112248
- const aminoAcidIndex = index2 / 3;
112324
+ const aminoAcidIndex = Math.floor(index2 / 3);
112249
112325
  let codonPositionsInCDS;
112250
112326
  let basesRead;
112251
112327
  if (isProteinSequence) {
@@ -112419,7 +112495,7 @@ ${latestSubscriptionCallbackError.current.stack}
112419
112495
  isRna: isRna2,
112420
112496
  isMixedRnaAndDna
112421
112497
  } = {}) {
112422
- return isProtein2 ? `${extended_protein_letters.toLowerCase()}}` : isOligo2 ? ambiguous_rna_letters.toLowerCase() + "t" : isRna2 ? ambiguous_rna_letters.toLowerCase() + "t" : isMixedRnaAndDna ? ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase() : (
112498
+ return isProtein2 ? `${extended_protein_letters.toLowerCase()}` : isOligo2 ? ambiguous_rna_letters.toLowerCase() + "t" : isRna2 ? ambiguous_rna_letters.toLowerCase() + "t" : isMixedRnaAndDna ? ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase() : (
112423
112499
  //just plain old dna
112424
112500
  ambiguous_rna_letters.toLowerCase() + ambiguous_dna_letters.toLowerCase()
112425
112501
  );
@@ -113433,7 +113509,7 @@ ${latestSubscriptionCallbackError.current.stack}
113433
113509
  return __spreadValues(__spreadProps(__spreadValues({}, newRange), {
113434
113510
  start: newLocations[0].start,
113435
113511
  end: newLocations[newLocations.length - 1].end
113436
- }), newLocations.length > 1 && { locations: newLocations });
113512
+ }), newLocations.length > 0 && { locations: newLocations });
113437
113513
  } else {
113438
113514
  return newRange;
113439
113515
  }
@@ -145604,6 +145680,7 @@ ${seq.sequence}
145604
145680
  __spreadValues({
145605
145681
  key: key + "caret1"
145606
145682
  }, {
145683
+ isProtein: isProtein2,
145607
145684
  leftMargin,
145608
145685
  onClick: _onClick || preventDefaultStopPropagation,
145609
145686
  onRightClick: onSelectionContextMenu,
@@ -145623,6 +145700,7 @@ ${seq.sequence}
145623
145700
  __spreadValues({
145624
145701
  key: key + "caret2"
145625
145702
  }, {
145703
+ isProtein: isProtein2,
145626
145704
  leftMargin,
145627
145705
  onClick: _onClick || preventDefaultStopPropagation,
145628
145706
  onRightClick: onSelectionContextMenu,
@@ -150596,7 +150674,8 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
150596
150674
  noQualityScores: !showChromQualScores
150597
150675
  }),
150598
150676
  style: {
150599
- position: "relative"
150677
+ position: "relative",
150678
+ textAlign: "left"
150600
150679
  },
150601
150680
  onContextMenu: /* @__PURE__ */ __name((e2) => {
150602
150681
  showContextMenu([chromatogramMenu], void 0, e2);
@@ -151453,7 +151532,8 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
151453
151532
  ), caretPosition2 > -1 && /* @__PURE__ */ React.createElement(
151454
151533
  Caret$2,
151455
151534
  __spreadProps(__spreadValues({
151456
- caretPosition: caretPosition2
151535
+ caretPosition: caretPosition2,
151536
+ isProtein: isProtein2
151457
151537
  }, __spreadValues(__spreadValues({}, annotationCommonProps), { getGaps: void 0 })), {
151458
151538
  row: alignmentData ? { start: 0, end: alignmentData.sequence.length - 1 } : row
151459
151539
  })
@@ -152978,7 +153058,7 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
152978
153058
  input.click();
152979
153059
  }
152980
153060
  __name(showFileDialog, "showFileDialog");
152981
- const version = "0.7.33";
153061
+ const version = "0.7.35";
152982
153062
  const packageJson = {
152983
153063
  version
152984
153064
  };
@@ -155089,7 +155169,8 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
155089
155169
  return;
155090
155170
  }
155091
155171
  const seqToInsert = isProtein2 ? {
155092
- proteinSequence: charsToInsert
155172
+ proteinSequence: charsToInsert,
155173
+ isProtein: true
155093
155174
  } : {
155094
155175
  sequence: charsToInsert
155095
155176
  };
@@ -155151,10 +155232,9 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
155151
155232
  });
155152
155233
  }, 200);
155153
155234
  }
155154
- if (maxInsertSize && sanitizedVal.lenth > maxInsertSize) {
155235
+ if (maxInsertSize && sanitizedVal.length > maxInsertSize) {
155155
155236
  return window.toastr.error(
155156
- "Sorry, your insert is greater than ",
155157
- maxInsertSize
155237
+ `Sorry, your insert is greater than ${maxInsertSize}`
155158
155238
  );
155159
155239
  }
155160
155240
  e2.target.value = sanitizedVal;
@@ -156014,7 +156094,8 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
156014
156094
  readOnly: readOnly2,
156015
156095
  onPaste,
156016
156096
  disableBpEditing,
156017
- sequenceData: sequenceData2
156097
+ sequenceData: sequenceData2,
156098
+ maxInsertSize
156018
156099
  } = this.props;
156019
156100
  if (disableBpEditing) {
156020
156101
  return this.createDisableBpEditingMsg();
@@ -156041,6 +156122,11 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
156041
156122
  if (sequenceData2.isProtein && !seqDataToInsert.proteinSequence) {
156042
156123
  seqDataToInsert.proteinSequence = seqDataToInsert.sequence;
156043
156124
  }
156125
+ if (maxInsertSize && (seqDataToInsert.proteinSequence || seqDataToInsert.sequence).length > maxInsertSize) {
156126
+ return window.toastr.error(
156127
+ `Sorry, the pasted sequence exceeds the maximum allowed length of ${maxInsertSize}`
156128
+ );
156129
+ }
156044
156130
  seqDataToInsert = tidyUpSequenceData(seqDataToInsert, {
156045
156131
  topLevelSeqData: sequenceData2,
156046
156132
  provideNewIdsForAnnotations: true,
@@ -156155,7 +156241,8 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
156155
156241
  selectionLayer: selectionLayer2 = { start: -1, end: -1 },
156156
156242
  sequenceData: sequenceData2 = { sequence: "" },
156157
156243
  readOnly: readOnly2,
156158
- disableBpEditing
156244
+ disableBpEditing,
156245
+ maxInsertSize
156159
156246
  // updateSequenceData,
156160
156247
  // wrappedInsertSequenceDataAtPositionOrRange
156161
156248
  // handleInsert
@@ -156176,6 +156263,7 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
156176
156263
  selectionLayer: selectionLayer2,
156177
156264
  sequenceLength,
156178
156265
  caretPosition: caretPosition2,
156266
+ maxInsertSize,
156179
156267
  handleInsert: /* @__PURE__ */ __name((seqDataToInsert) => __async(this, null, function* () {
156180
156268
  yield insertAndSelectHelper({
156181
156269
  props: this.props,
@@ -156534,6 +156622,8 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
156534
156622
  [this.commandEnhancer],
156535
156623
  e2,
156536
156624
  () => {
156625
+ document.body.removeEventListener("cut", this.handleCut);
156626
+ document.body.removeEventListener("copy", this.handleCopy);
156537
156627
  if (lastFocusedEl) {
156538
156628
  lastFocusedEl.focus();
156539
156629
  }
@@ -160081,6 +160171,7 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
160081
160171
  onClick: onClick ? noop$4 : preventDefaultStopPropagation,
160082
160172
  selectionMessage,
160083
160173
  caretPosition: start2,
160174
+ isProtein: isProtein2,
160084
160175
  sequenceLength,
160085
160176
  innerRadius,
160086
160177
  outerRadius: radius
@@ -160095,6 +160186,7 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
160095
160186
  onClick: onClick ? noop$4 : preventDefaultStopPropagation,
160096
160187
  selectionMessage,
160097
160188
  caretPosition: end2 + 1,
160189
+ isProtein: isProtein2,
160098
160190
  sequenceLength,
160099
160191
  innerRadius,
160100
160192
  outerRadius: radius
@@ -179454,6 +179546,7 @@ ${seqDataToCopy}\r
179454
179546
  hideStatusBar,
179455
179547
  hoveredId,
179456
179548
  isFullscreen,
179549
+ maxInsertSize,
179457
179550
  maxAnnotationsToDisplay,
179458
179551
  minHeight = 400,
179459
179552
  onlyShowLabelsThatDoNotFit = true,
@@ -179641,6 +179734,7 @@ ${seqDataToCopy}\r
179641
179734
  doubleClickOverrides: this.props.doubleClickOverrides
179642
179735
  }), panelPropsToSpread), {
179643
179736
  editorName,
179737
+ maxInsertSize,
179644
179738
  isProtein: sequenceData2.isProtein,
179645
179739
  onlyShowLabelsThatDoNotFit,
179646
179740
  tabHeight,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ove",
3
- "version": "0.7.34",
3
+ "version": "0.7.36",
4
4
  "main": "./src/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,7 +19,7 @@
19
19
  "@teselagen/range-utils": "0.3.13",
20
20
  "@teselagen/react-list": "0.8.18",
21
21
  "@teselagen/sequence-utils": "0.3.32",
22
- "@teselagen/ui": "0.9.4",
22
+ "@teselagen/ui": "0.9.6",
23
23
  "@use-gesture/react": "10.3.0",
24
24
  "biomsa": "^0.2.4",
25
25
  "classnames": "^2.3.2",
@@ -103,6 +103,7 @@ function SelectionLayer({
103
103
  onClick={onClick ? noop : preventDefaultStopPropagation}
104
104
  selectionMessage={selectionMessage}
105
105
  caretPosition={start}
106
+ isProtein={isProtein}
106
107
  sequenceLength={sequenceLength}
107
108
  innerRadius={innerRadius}
108
109
  outerRadius={radius}
@@ -120,6 +121,7 @@ function SelectionLayer({
120
121
  onClick={onClick ? noop : preventDefaultStopPropagation}
121
122
  selectionMessage={selectionMessage}
122
123
  caretPosition={end + 1}
124
+ isProtein={isProtein}
123
125
  sequenceLength={sequenceLength}
124
126
  innerRadius={innerRadius}
125
127
  outerRadius={radius}
@@ -360,6 +360,7 @@ export class Editor extends React.Component {
360
360
  hideStatusBar,
361
361
  hoveredId,
362
362
  isFullscreen,
363
+ maxInsertSize,
363
364
  maxAnnotationsToDisplay,
364
365
  minHeight = 400,
365
366
  onlyShowLabelsThatDoNotFit = true,
@@ -592,6 +593,7 @@ export class Editor extends React.Component {
592
593
  doubleClickOverrides={this.props.doubleClickOverrides}
593
594
  {...panelPropsToSpread}
594
595
  editorName={editorName}
596
+ maxInsertSize={maxInsertSize}
595
597
  isProtein={sequenceData.isProtein}
596
598
  onlyShowLabelsThatDoNotFit={onlyShowLabelsThatDoNotFit}
597
599
  tabHeight={tabHeight}
@@ -63,7 +63,8 @@ export default function Chromatogram(props) {
63
63
  noQualityScores: !showChromQualScores
64
64
  })}
65
65
  style={{
66
- position: "relative"
66
+ position: "relative",
67
+ textAlign: "left"
67
68
  }}
68
69
  onContextMenu={e => {
69
70
  showContextMenu([chromatogramMenu], undefined, e);
@@ -107,6 +107,7 @@ function SelectionLayer(props) {
107
107
  <Caret
108
108
  key={key + "caret1"}
109
109
  {...{
110
+ isProtein,
110
111
  leftMargin,
111
112
  onClick: _onClick || preventDefaultStopPropagation,
112
113
  onRightClick: onSelectionContextMenu,
@@ -129,6 +130,7 @@ function SelectionLayer(props) {
129
130
  <Caret
130
131
  key={key + "caret2"}
131
132
  {...{
133
+ isProtein,
132
134
  leftMargin,
133
135
  onClick: _onClick || preventDefaultStopPropagation,
134
136
  onRightClick: onSelectionContextMenu,
@@ -618,6 +618,7 @@ export default function RowItem(props) {
618
618
  {caretPosition > -1 && (
619
619
  <Caret
620
620
  caretPosition={caretPosition}
621
+ isProtein={isProtein}
621
622
  {...{ ...annotationCommonProps, ...{ getGaps: undefined } }}
622
623
  row={
623
624
  alignmentData
@@ -65,7 +65,8 @@ class SequenceInputNoHotkeys extends React.Component {
65
65
  }
66
66
  const seqToInsert = isProtein
67
67
  ? {
68
- proteinSequence: charsToInsert
68
+ proteinSequence: charsToInsert,
69
+ isProtein: true
69
70
  }
70
71
  : {
71
72
  sequence: charsToInsert
@@ -153,10 +154,9 @@ class SequenceInputNoHotkeys extends React.Component {
153
154
  });
154
155
  }, 200);
155
156
  }
156
- if (maxInsertSize && sanitizedVal.lenth > maxInsertSize) {
157
+ if (maxInsertSize && sanitizedVal.length > maxInsertSize) {
157
158
  return window.toastr.error(
158
- "Sorry, your insert is greater than ",
159
- maxInsertSize
159
+ `Sorry, your insert is greater than ${maxInsertSize}`,
160
160
  );
161
161
  }
162
162
  e.target.value = sanitizedVal;
@@ -211,7 +211,8 @@ function VectorInteractionHOC(Component /* options */) {
211
211
  readOnly,
212
212
  onPaste,
213
213
  disableBpEditing,
214
- sequenceData
214
+ sequenceData,
215
+ maxInsertSize
215
216
  } = this.props;
216
217
 
217
218
  if (disableBpEditing) {
@@ -241,6 +242,16 @@ function VectorInteractionHOC(Component /* options */) {
241
242
  seqDataToInsert.proteinSequence = seqDataToInsert.sequence;
242
243
  }
243
244
 
245
+ if (
246
+ maxInsertSize &&
247
+ (seqDataToInsert.proteinSequence || seqDataToInsert.sequence).length >
248
+ maxInsertSize
249
+ ) {
250
+ return window.toastr.error(
251
+ `Sorry, the pasted sequence exceeds the maximum allowed length of ${maxInsertSize}`
252
+ );
253
+ }
254
+
244
255
  seqDataToInsert = tidyUpSequenceData(seqDataToInsert, {
245
256
  topLevelSeqData: sequenceData,
246
257
  provideNewIdsForAnnotations: true,
@@ -387,7 +398,8 @@ function VectorInteractionHOC(Component /* options */) {
387
398
  selectionLayer = { start: -1, end: -1 },
388
399
  sequenceData = { sequence: "" },
389
400
  readOnly,
390
- disableBpEditing
401
+ disableBpEditing,
402
+ maxInsertSize
391
403
  // updateSequenceData,
392
404
  // wrappedInsertSequenceDataAtPositionOrRange
393
405
  // handleInsert
@@ -408,6 +420,7 @@ function VectorInteractionHOC(Component /* options */) {
408
420
  selectionLayer,
409
421
  sequenceLength,
410
422
  caretPosition,
423
+ maxInsertSize,
411
424
  handleInsert: async seqDataToInsert => {
412
425
  await insertAndSelectHelper({
413
426
  props: this.props,
@@ -602,6 +615,7 @@ function VectorInteractionHOC(Component /* options */) {
602
615
  const { sequenceData, readOnly, disableBpEditing, selectionLayer } =
603
616
  this.props;
604
617
  const { isProtein } = sequenceData;
618
+
605
619
  // Add the appropriate listener
606
620
  document.body.addEventListener("copy", this.handleCopy, { once: true });
607
621
  document.body.addEventListener("cut", this.handleCut, { once: true });
@@ -827,6 +841,8 @@ function VectorInteractionHOC(Component /* options */) {
827
841
  [this.commandEnhancer],
828
842
  e,
829
843
  () => {
844
+ document.body.removeEventListener("cut", this.handleCut);
845
+ document.body.removeEventListener("copy", this.handleCopy);
830
846
  if (lastFocusedEl) {
831
847
  lastFocusedEl.focus();
832
848
  }