@teselagen/sequence-utils 0.3.37 → 0.3.38-beta.2

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.
Files changed (168) hide show
  1. package/DNAComplementMap.d.ts +1 -1
  2. package/addGapsToSeqReads.d.ts +16 -3
  3. package/adjustAnnotationsToInsert.d.ts +2 -1
  4. package/adjustBpsToReplaceOrInsert.d.ts +2 -1
  5. package/aliasedEnzymesByName.d.ts +37 -1
  6. package/aminoAcidToDegenerateDnaMap.d.ts +1 -31
  7. package/aminoAcidToDegenerateRnaMap.d.ts +1 -1
  8. package/annotateSingleSeq.d.ts +5 -4
  9. package/annotationTypes.d.ts +2 -2
  10. package/autoAnnotate.d.ts +17 -8
  11. package/bioData.d.ts +10 -58
  12. package/calculateEndStability.d.ts +1 -1
  13. package/calculateNebTa.d.ts +6 -1
  14. package/calculateNebTm.d.ts +6 -4
  15. package/calculatePercentGC.d.ts +1 -1
  16. package/calculateSantaLuciaTm.d.ts +28 -114
  17. package/calculateTm.d.ts +13 -1
  18. package/computeDigestFragments.d.ts +30 -24
  19. package/condensePairwiseAlignmentDifferences.d.ts +1 -1
  20. package/convertAACaretPositionOrRangeToDna.d.ts +2 -1
  21. package/convertDnaCaretPositionOrRangeToAA.d.ts +2 -1
  22. package/cutSequenceByRestrictionEnzyme.d.ts +2 -1
  23. package/defaultEnzymesByName.d.ts +2 -1
  24. package/degenerateDnaToAminoAcidMap.d.ts +1 -1
  25. package/degenerateRnaToAminoAcidMap.d.ts +1 -1
  26. package/deleteSequenceDataAtRange.d.ts +2 -1
  27. package/diffUtils.d.ts +9 -7
  28. package/doesEnzymeChopOutsideOfRecognitionSite.d.ts +2 -1
  29. package/featureTypesAndColors.d.ts +19 -6
  30. package/filterSequenceString.d.ts +14 -10
  31. package/findApproxMatches.d.ts +7 -1
  32. package/findNearestRangeOfSequenceOverlapToPosition.d.ts +2 -1
  33. package/findOrfsInPlasmid.d.ts +2 -11
  34. package/findSequenceMatches.d.ts +11 -1
  35. package/generateAnnotations.d.ts +2 -1
  36. package/generateSequenceData.d.ts +8 -13
  37. package/getAllInsertionsInSeqReads.d.ts +11 -1
  38. package/getAminoAcidDataForEachBaseOfDna.d.ts +6 -5
  39. package/getAminoAcidFromSequenceTriplet.d.ts +1 -1
  40. package/getAminoAcidStringFromSequenceString.d.ts +3 -1
  41. package/getCodonRangeForAASliver.d.ts +3 -4
  42. package/getComplementAminoAcidStringFromSequenceString.d.ts +1 -1
  43. package/getComplementSequenceAndAnnotations.d.ts +5 -1
  44. package/getComplementSequenceString.d.ts +1 -1
  45. package/getCutsiteType.d.ts +2 -1
  46. package/getCutsitesFromSequence.d.ts +2 -1
  47. package/getDegenerateDnaStringFromAAString.d.ts +1 -1
  48. package/getDegenerateRnaStringFromAAString.d.ts +1 -1
  49. package/getDigestFragmentsForCutsites.d.ts +4 -1
  50. package/getDigestFragmentsForRestrictionEnzymes.d.ts +8 -1
  51. package/getInsertBetweenVals.d.ts +2 -1
  52. package/getLeftAndRightOfSequenceInRangeGivenPosition.d.ts +2 -1
  53. package/getOrfsFromSequence.d.ts +17 -11
  54. package/getOverlapBetweenTwoSequences.d.ts +2 -1
  55. package/getPossiblePartsFromSequenceAndEnzymes.d.ts +18 -1
  56. package/getReverseAminoAcidStringFromSequenceString.d.ts +1 -1
  57. package/getReverseComplementAminoAcidStringFromSequenceString.d.ts +1 -1
  58. package/getReverseComplementAnnotation.d.ts +11 -1
  59. package/getReverseComplementSequenceAndAnnotations.d.ts +5 -1
  60. package/getReverseComplementSequenceString.d.ts +1 -1
  61. package/getReverseSequenceString.d.ts +1 -1
  62. package/getSequenceDataBetweenRange.d.ts +9 -1
  63. package/getVirtualDigest.d.ts +11 -10
  64. package/guessIfSequenceIsDnaAndNotProtein.d.ts +5 -1
  65. package/index.cjs +732 -483
  66. package/index.d.ts +8 -5
  67. package/index.js +732 -483
  68. package/index.umd.cjs +732 -483
  69. package/insertGapsIntoRefSeq.d.ts +2 -1
  70. package/insertSequenceDataAtPositionOrRange.d.ts +10 -1
  71. package/isEnzymeType2S.d.ts +2 -1
  72. package/mapAnnotationsToRows.d.ts +9 -1
  73. package/package.json +9 -6
  74. package/prepareCircularViewData.d.ts +2 -1
  75. package/prepareRowData.d.ts +7 -3
  76. package/proteinAlphabet.d.ts +1 -1
  77. package/rotateBpsToPosition.d.ts +1 -1
  78. package/rotateSequenceDataToPosition.d.ts +3 -1
  79. package/shiftAnnotationsByLen.d.ts +4 -3
  80. package/src/DNAComplementMap.ts +32 -0
  81. package/src/addGapsToSeqReads.ts +436 -0
  82. package/src/adjustAnnotationsToInsert.ts +20 -0
  83. package/src/adjustBpsToReplaceOrInsert.ts +73 -0
  84. package/src/aliasedEnzymesByName.ts +7366 -0
  85. package/src/aminoAcidToDegenerateDnaMap.ts +32 -0
  86. package/src/aminoAcidToDegenerateRnaMap.ts +32 -0
  87. package/src/annotateSingleSeq.ts +37 -0
  88. package/src/annotationTypes.ts +23 -0
  89. package/src/autoAnnotate.test.js +0 -1
  90. package/src/autoAnnotate.ts +290 -0
  91. package/src/bioData.ts +65 -0
  92. package/src/calculateEndStability.ts +91 -0
  93. package/src/calculateNebTa.ts +46 -0
  94. package/src/calculateNebTm.ts +132 -0
  95. package/src/calculatePercentGC.ts +3 -0
  96. package/src/calculateSantaLuciaTm.ts +184 -0
  97. package/src/calculateTm.ts +242 -0
  98. package/src/computeDigestFragments.ts +238 -0
  99. package/src/condensePairwiseAlignmentDifferences.ts +85 -0
  100. package/src/convertAACaretPositionOrRangeToDna.ts +28 -0
  101. package/src/convertDnaCaretPositionOrRangeToAA.ts +28 -0
  102. package/src/cutSequenceByRestrictionEnzyme.ts +345 -0
  103. package/src/defaultEnzymesByName.ts +280 -0
  104. package/src/degenerateDnaToAminoAcidMap.ts +5 -0
  105. package/src/degenerateRnaToAminoAcidMap.ts +5 -0
  106. package/src/deleteSequenceDataAtRange.ts +13 -0
  107. package/src/diffUtils.ts +80 -0
  108. package/src/doesEnzymeChopOutsideOfRecognitionSite.ts +16 -0
  109. package/src/featureTypesAndColors.ts +167 -0
  110. package/src/filterSequenceString.ts +153 -0
  111. package/src/findApproxMatches.ts +58 -0
  112. package/src/findNearestRangeOfSequenceOverlapToPosition.ts +43 -0
  113. package/src/findOrfsInPlasmid.js +6 -1
  114. package/src/findOrfsInPlasmid.ts +31 -0
  115. package/src/findSequenceMatches.ts +154 -0
  116. package/src/generateAnnotations.ts +39 -0
  117. package/src/generateSequenceData.ts +212 -0
  118. package/src/getAllInsertionsInSeqReads.ts +100 -0
  119. package/src/getAminoAcidDataForEachBaseOfDna.ts +305 -0
  120. package/src/getAminoAcidFromSequenceTriplet.ts +27 -0
  121. package/src/getAminoAcidStringFromSequenceString.ts +36 -0
  122. package/src/getCodonRangeForAASliver.ts +73 -0
  123. package/src/getComplementAminoAcidStringFromSequenceString.ts +10 -0
  124. package/src/getComplementSequenceAndAnnotations.ts +25 -0
  125. package/src/getComplementSequenceString.ts +23 -0
  126. package/src/getCutsiteType.ts +18 -0
  127. package/src/getCutsitesFromSequence.ts +22 -0
  128. package/src/getDegenerateDnaStringFromAAString.ts +15 -0
  129. package/src/getDegenerateRnaStringFromAAString.ts +15 -0
  130. package/src/getDigestFragmentsForCutsites.ts +126 -0
  131. package/src/getDigestFragmentsForRestrictionEnzymes.ts +50 -0
  132. package/src/getInsertBetweenVals.ts +31 -0
  133. package/src/getLeftAndRightOfSequenceInRangeGivenPosition.ts +40 -0
  134. package/src/getMassOfAaString.ts +29 -0
  135. package/src/getOrfsFromSequence.ts +132 -0
  136. package/src/getOverlapBetweenTwoSequences.ts +30 -0
  137. package/src/getPossiblePartsFromSequenceAndEnzymes.ts +149 -0
  138. package/src/getReverseAminoAcidStringFromSequenceString.ts +22 -0
  139. package/src/getReverseComplementAminoAcidStringFromSequenceString.ts +10 -0
  140. package/src/getReverseComplementAnnotation.ts +33 -0
  141. package/src/getReverseComplementSequenceAndAnnotations.ts +46 -0
  142. package/src/getReverseComplementSequenceString.ts +18 -0
  143. package/src/getReverseSequenceString.ts +12 -0
  144. package/src/getSequenceDataBetweenRange.ts +154 -0
  145. package/src/getVirtualDigest.ts +139 -0
  146. package/src/guessIfSequenceIsDnaAndNotProtein.ts +39 -0
  147. package/src/index.test.ts +43 -0
  148. package/src/index.ts +111 -0
  149. package/src/insertGapsIntoRefSeq.ts +43 -0
  150. package/src/insertSequenceDataAtPosition.ts +2 -0
  151. package/src/insertSequenceDataAtPositionOrRange.ts +328 -0
  152. package/src/isEnzymeType2S.ts +5 -0
  153. package/src/mapAnnotationsToRows.ts +256 -0
  154. package/src/prepareCircularViewData.ts +24 -0
  155. package/src/prepareRowData.ts +61 -0
  156. package/src/prepareRowData_output1.json +1 -0
  157. package/src/proteinAlphabet.ts +271 -0
  158. package/src/rotateBpsToPosition.ts +12 -0
  159. package/src/rotateSequenceDataToPosition.ts +54 -0
  160. package/src/shiftAnnotationsByLen.ts +24 -0
  161. package/src/threeLetterSequenceStringToAminoAcidMap.ts +198 -0
  162. package/src/tidyUpAnnotation.ts +205 -0
  163. package/src/tidyUpSequenceData.ts +213 -0
  164. package/src/types.ts +109 -0
  165. package/threeLetterSequenceStringToAminoAcidMap.d.ts +11 -921
  166. package/tidyUpAnnotation.d.ts +13 -11
  167. package/tidyUpSequenceData.d.ts +15 -1
  168. package/types.d.ts +105 -0
package/index.js CHANGED
@@ -2586,9 +2586,10 @@ function getOverlapOfNonCircularRanges(rangeA, rangeB) {
2586
2586
  }
2587
2587
  }
2588
2588
  }
2589
+ return null;
2589
2590
  }
2590
2591
  __name(getOverlapOfNonCircularRanges, "getOverlapOfNonCircularRanges");
2591
- function getOverlapsOfPotentiallyCircularRanges(rangeA, rangeB, maxRangeLength, joinIfPossible) {
2592
+ function getOverlapsOfPotentiallyCircularRanges(rangeA, rangeB, maxRangeLength, joinIfPossible = false) {
2592
2593
  const normalizedRangeA = splitRangeIntoTwoPartsIfItIsCircular(
2593
2594
  rangeA,
2594
2595
  maxRangeLength
@@ -2609,6 +2610,22 @@ function getOverlapsOfPotentiallyCircularRanges(rangeA, rangeB, maxRangeLength,
2609
2610
  }
2610
2611
  });
2611
2612
  });
2613
+ if (joinIfPossible && normalizedRangeA.length === 2 && normalizedRangeB.length === 2 && maxRangeLength) {
2614
+ const joinedOverlap = {};
2615
+ overlaps = flatMap(overlaps, (o) => {
2616
+ if (o.start === 0) {
2617
+ joinedOverlap.end = o.end;
2618
+ return [];
2619
+ } else if (o.end === maxRangeLength - 1) {
2620
+ joinedOverlap.start = o.start;
2621
+ return [];
2622
+ }
2623
+ return [o];
2624
+ });
2625
+ if (Object.keys(joinedOverlap).length > 0) {
2626
+ overlaps.push(joinedOverlap);
2627
+ }
2628
+ }
2612
2629
  return overlaps;
2613
2630
  }
2614
2631
  __name(getOverlapsOfPotentiallyCircularRanges, "getOverlapsOfPotentiallyCircularRanges");
@@ -2680,10 +2697,7 @@ function trimRangeByAnotherRange(rangeToBeTrimmed, trimmingRange, sequenceLength
2680
2697
  if (!overlaps.length) {
2681
2698
  return rangeToBeTrimmed;
2682
2699
  }
2683
- const splitRangesToBeTrimmed = splitRangeIntoTwoPartsIfItIsCircular(
2684
- rangeToBeTrimmed,
2685
- sequenceLength
2686
- );
2700
+ const splitRangesToBeTrimmed = splitRangeIntoTwoPartsIfItIsCircular(rangeToBeTrimmed, sequenceLength);
2687
2701
  splitRangesToBeTrimmed.forEach(function(nonCircularRangeToBeTrimmed, index) {
2688
2702
  overlaps.forEach(function(overlap) {
2689
2703
  if (nonCircularRangeToBeTrimmed) {
@@ -2726,6 +2740,7 @@ function trimRangeByAnotherRange(rangeToBeTrimmed, trimmingRange, sequenceLength
2726
2740
  end: outputTrimmedRange.end
2727
2741
  });
2728
2742
  }
2743
+ return void 0;
2729
2744
  }
2730
2745
  __name(trimRangeByAnotherRange, "trimRangeByAnotherRange");
2731
2746
  function adjustRangeToDeletionOfAnotherRange(rangeToBeAdjusted, anotherRange, maxLength) {
@@ -2872,28 +2887,36 @@ function collapseOverlapsGeneratedFromRangeComparisonIfPossible(overlaps, sequen
2872
2887
  }
2873
2888
  }
2874
2889
  }
2890
+ return overlaps;
2875
2891
  }
2876
2892
  __name(collapseOverlapsGeneratedFromRangeComparisonIfPossible, "collapseOverlapsGeneratedFromRangeComparisonIfPossible");
2877
2893
  function provideInclusiveOptions(funToWrap) {
2878
- return function() {
2879
- const args = Array.prototype.slice.call(arguments);
2894
+ return function(...args) {
2880
2895
  const options = args[args.length - 1];
2881
2896
  if (options && (options.inclusive1BasedEnd || options.inclusive1BasedStart)) {
2882
2897
  args.forEach(function(arg, index) {
2883
- if (arg && arg.start > -1 && options.inclusive1BasedStart) {
2884
- args[index] = assign(arg, { start: arg.start - 1 });
2898
+ const potentialRange = arg;
2899
+ if (potentialRange && typeof potentialRange.start === "number" && potentialRange.start > -1 && options.inclusive1BasedStart) {
2900
+ args[index] = assign(potentialRange, {
2901
+ start: potentialRange.start - 1
2902
+ });
2885
2903
  }
2886
- if (arg && arg.end > -1 && options.inclusive1BasedEnd) {
2887
- args[index] = assign(arg, { end: arg.end - 1 });
2904
+ if (potentialRange && typeof potentialRange.end === "number" && potentialRange.end > -1 && options.inclusive1BasedEnd) {
2905
+ args[index] = assign(potentialRange, {
2906
+ end: potentialRange.end - 1
2907
+ });
2888
2908
  }
2889
2909
  });
2890
2910
  }
2891
2911
  let returnVal = funToWrap.apply(this, args);
2892
- if (returnVal && returnVal.start > -1 && options && options.inclusive1BasedStart) {
2893
- returnVal = assign(returnVal, { start: returnVal.start + 1 });
2912
+ const potentialReturn = returnVal;
2913
+ if (potentialReturn && typeof potentialReturn.start === "number" && potentialReturn.start > -1 && options && options.inclusive1BasedStart) {
2914
+ returnVal = assign(potentialReturn, {
2915
+ start: potentialReturn.start + 1
2916
+ });
2894
2917
  }
2895
- if (returnVal && returnVal.end > -1 && options && options.inclusive1BasedEnd) {
2896
- returnVal = assign(returnVal, { end: returnVal.end + 1 });
2918
+ if (potentialReturn && typeof potentialReturn.end === "number" && potentialReturn.end > -1 && options && options.inclusive1BasedEnd) {
2919
+ returnVal = assign(potentialReturn, { end: potentialReturn.end + 1 });
2897
2920
  }
2898
2921
  return returnVal;
2899
2922
  };
@@ -2939,7 +2962,7 @@ function isPositionWithinRange(position, range, sequenceLength, includeStartEdge
2939
2962
  return positionFits;
2940
2963
  }
2941
2964
  __name(isPositionWithinRange, "isPositionWithinRange");
2942
- function normalizePositionByRangeLength(pPosition, sequenceLength, isInBetweenPositions) {
2965
+ function normalizePositionByRangeLength(pPosition, sequenceLength, isInBetweenPositions = false) {
2943
2966
  let position = pPosition;
2944
2967
  if (position < 0) {
2945
2968
  position += sequenceLength;
@@ -3119,7 +3142,9 @@ function getSequenceWithinRange(range, sequence) {
3119
3142
  if (typeof subSequence === "string") {
3120
3143
  subSequence += sequence.slice(0, range.end + 1);
3121
3144
  } else {
3122
- subSequence = subSequence.concat(sequence.slice(0, range.end + 1));
3145
+ subSequence = subSequence.concat(
3146
+ sequence.slice(0, range.end + 1)
3147
+ );
3123
3148
  }
3124
3149
  return subSequence;
3125
3150
  } else {
@@ -3139,7 +3164,7 @@ function getShortestDistanceBetweenTwoPositions(position1, position2, sequenceLe
3139
3164
  }
3140
3165
  __name(getShortestDistanceBetweenTwoPositions, "getShortestDistanceBetweenTwoPositions");
3141
3166
  function getYOffsetForPotentiallyCircularRange(range, YOffsetLevelsWithRanges, assignYOffsetToRange) {
3142
- let yOffset = [];
3167
+ let yOffset = 0;
3143
3168
  const openYOffsetFound = YOffsetLevelsWithRanges.some(
3144
3169
  function(rangesAlreadyAddedToYOffset, index) {
3145
3170
  const rangeBlocked = rangesAlreadyAddedToYOffset.some(
@@ -3152,6 +3177,7 @@ function getYOffsetForPotentiallyCircularRange(range, YOffsetLevelsWithRanges, a
3152
3177
  );
3153
3178
  if (!rangeBlocked) {
3154
3179
  yOffset = index;
3180
+ if (assignYOffsetToRange) range.yOffset = index;
3155
3181
  rangesAlreadyAddedToYOffset.push(range);
3156
3182
  return true;
3157
3183
  }
@@ -3160,6 +3186,7 @@ function getYOffsetForPotentiallyCircularRange(range, YOffsetLevelsWithRanges, a
3160
3186
  );
3161
3187
  if (!openYOffsetFound) {
3162
3188
  yOffset = YOffsetLevelsWithRanges.length;
3189
+ if (assignYOffsetToRange) range.yOffset = YOffsetLevelsWithRanges.length;
3163
3190
  }
3164
3191
  return yOffset;
3165
3192
  }
@@ -3171,7 +3198,8 @@ function getYOffsetsForPotentiallyCircularRanges(ranges, assignYOffsetToRange) {
3171
3198
  ranges.forEach(function(range) {
3172
3199
  const yOffset = getYOffsetForPotentiallyCircularRange(
3173
3200
  range,
3174
- yOffsetLevels
3201
+ yOffsetLevels,
3202
+ assignYOffsetToRange
3175
3203
  );
3176
3204
  yOffsets.push(yOffset);
3177
3205
  if (yOffset > maxYOffset) {
@@ -3186,21 +3214,20 @@ function getYOffsetsForPotentiallyCircularRanges(ranges, assignYOffsetToRange) {
3186
3214
  __name(getYOffsetsForPotentiallyCircularRanges, "getYOffsetsForPotentiallyCircularRanges");
3187
3215
  const invertRange = provideInclusiveOptions(invertRange$1);
3188
3216
  function invertRange$1(rangeOrCaret, rangeMax) {
3189
- if (rangeOrCaret.start > -1) {
3217
+ if (typeof rangeOrCaret !== "number" && rangeOrCaret.start > -1) {
3190
3218
  const start = rangeOrCaret.end + 1;
3191
3219
  const end = rangeOrCaret.start - 1;
3192
3220
  return {
3193
3221
  start: normalizePositionByRangeLength(start, rangeMax, false),
3194
3222
  end: normalizePositionByRangeLength(end, rangeMax, false)
3195
3223
  };
3196
- } else {
3197
- if (rangeOrCaret > -1) {
3198
- return {
3199
- start: normalizePositionByRangeLength(rangeOrCaret, rangeMax, false),
3200
- end: normalizePositionByRangeLength(rangeOrCaret - 1, rangeMax, false)
3201
- };
3202
- }
3224
+ } else if (typeof rangeOrCaret === "number" && rangeOrCaret > -1) {
3225
+ return {
3226
+ start: normalizePositionByRangeLength(rangeOrCaret, rangeMax, false),
3227
+ end: normalizePositionByRangeLength(rangeOrCaret - 1, rangeMax, false)
3228
+ };
3203
3229
  }
3230
+ return void 0;
3204
3231
  }
3205
3232
  __name(invertRange$1, "invertRange$1");
3206
3233
  function isPositionCloserToRangeStartThanRangeEnd(position, range, maxLength) {
@@ -3254,9 +3281,10 @@ function zeroSubrangeByContainerRange(subRange, containerRange, sequenceLength)
3254
3281
  "subRange must be fully contained by containerRange! Otherwise this function does not make sense"
3255
3282
  );
3256
3283
  }
3257
- const newSubrange = {};
3258
- newSubrange.start = subRange.start - containerRange.start;
3259
- newSubrange.end = subRange.end - containerRange.start;
3284
+ const newSubrange = {
3285
+ start: subRange.start - containerRange.start,
3286
+ end: subRange.end - containerRange.start
3287
+ };
3260
3288
  if (newSubrange.start < 0) {
3261
3289
  newSubrange.start += sequenceLength;
3262
3290
  }
@@ -3267,10 +3295,10 @@ function zeroSubrangeByContainerRange(subRange, containerRange, sequenceLength)
3267
3295
  }
3268
3296
  __name(zeroSubrangeByContainerRange, "zeroSubrangeByContainerRange");
3269
3297
  function adjustRangeToRotation(rangeToBeAdjusted, rotateTo = 0, rangeLength) {
3270
- const mod = rangeLength ? modulo : identity;
3298
+ const mod = /* @__PURE__ */ __name((n) => rangeLength ? modulo(n, rangeLength) : n, "mod");
3271
3299
  const newRange = assign({}, rangeToBeAdjusted, {
3272
- start: mod(rangeToBeAdjusted.start - (rotateTo || 0), rangeLength),
3273
- end: mod(rangeToBeAdjusted.end - (rotateTo || 0), rangeLength)
3300
+ start: mod(rangeToBeAdjusted.start - (rotateTo || 0)),
3301
+ end: mod(rangeToBeAdjusted.end - (rotateTo || 0))
3274
3302
  });
3275
3303
  return newRange;
3276
3304
  }
@@ -3356,7 +3384,11 @@ function autoAnnotate({
3356
3384
  forEach(
3357
3385
  omitBy(seqsToAnnotateById, (s) => !s.sequence.length),
3358
3386
  ({ circular, sequence }, id) => {
3359
- function getMatches({ seqToMatchAgainst, isReverse, seqLen: seqLen2 }) {
3387
+ function getMatches({
3388
+ seqToMatchAgainst,
3389
+ isReverse,
3390
+ seqLen: seqLen2
3391
+ }) {
3360
3392
  let match;
3361
3393
  let lastMatch;
3362
3394
  try {
@@ -3376,13 +3408,13 @@ function autoAnnotate({
3376
3408
  };
3377
3409
  const range = {
3378
3410
  start: matchStart,
3379
- end: normalizePositionByRangeLength(matchEnd - 1, seqLen2)
3411
+ end: normalizePositionByRangeLength(matchEnd - 1, seqLen2, false)
3380
3412
  };
3381
3413
  if (!annotationsToAddBySeqId[id])
3382
3414
  annotationsToAddBySeqId[id] = [];
3383
3415
  annotationsToAddBySeqId[id].push(__spreadProps(__spreadValues({}, isReverse ? {
3384
- start: reversePositionInRange(range.end, seqLen2),
3385
- end: reversePositionInRange(range.start, seqLen2)
3416
+ start: reversePositionInRange(range.end, seqLen2, false),
3417
+ end: reversePositionInRange(range.start, seqLen2, false)
3386
3418
  } : range), {
3387
3419
  strand: isReverse ? -1 : 1,
3388
3420
  id: ann.id
@@ -3413,14 +3445,22 @@ function autoAnnotate({
3413
3445
  const origSeq = seqsToAnnotateById[id];
3414
3446
  const alreadyExistingAnnsByStartEnd = {};
3415
3447
  forEach(origSeq.annotations, (ann) => {
3416
- alreadyExistingAnnsByStartEnd[getStartEndStr(ann, { compareName })] = ann;
3448
+ alreadyExistingAnnsByStartEnd[getStartEndStr(
3449
+ __spreadProps(__spreadValues({}, ann), { strand: typeof ann.strand === "string" ? 1 : ann.strand }),
3450
+ { compareName }
3451
+ )] = ann;
3417
3452
  });
3418
3453
  const warningCounter = {};
3419
3454
  const toAdd = anns.filter((ann) => {
3420
- const alreadyExistingAnn = alreadyExistingAnnsByStartEnd[getStartEndStr(ann, { compareName })];
3455
+ const alreadyExistingAnn = alreadyExistingAnnsByStartEnd[getStartEndStr(
3456
+ __spreadProps(__spreadValues({}, ann), {
3457
+ strand: typeof ann.strand === "string" ? 1 : ann.strand
3458
+ }),
3459
+ { compareName }
3460
+ )];
3421
3461
  if (alreadyExistingAnn) return false;
3422
- if (warnIfMoreThan) {
3423
- warningCounter[ann.id] = (warningCounter[ann.id] || 0) + 1;
3462
+ if (warnIfMoreThan && ann.id !== void 0) {
3463
+ warningCounter[String(ann.id)] = (warningCounter[String(ann.id)] || 0) + 1;
3424
3464
  }
3425
3465
  return true;
3426
3466
  }).sort((a, b) => a.start - b.start);
@@ -3429,16 +3469,23 @@ function autoAnnotate({
3429
3469
  }
3430
3470
  warnIfMoreThan && forEach(warningCounter, (num, annId) => {
3431
3471
  if (num > warnIfMoreThan) {
3432
- toReturn.__more_than_warnings = toReturn.__more_than_warnings || {};
3433
- toReturn.__more_than_warnings[id] = toReturn.__more_than_warnings[id] || [];
3434
- toReturn.__more_than_warnings[id].push(annId);
3472
+ const warnings = toReturn["__more_than_warnings"] || {};
3473
+ warnings[id] = warnings[id] || [];
3474
+ warnings[id].push(annId);
3475
+ toReturn["__more_than_warnings"] = warnings;
3435
3476
  }
3436
3477
  });
3437
3478
  });
3438
3479
  return toReturn;
3439
3480
  }
3440
3481
  __name(autoAnnotate, "autoAnnotate");
3441
- function getStartEndStr({ start, end, name, strand, forward }, { compareName }) {
3482
+ function getStartEndStr({
3483
+ start,
3484
+ end,
3485
+ name,
3486
+ strand,
3487
+ forward
3488
+ }, { compareName }) {
3442
3489
  const isReverse = strand === -1 || forward === false;
3443
3490
  return `${start}-${end}-${isReverse ? "rev" : "for"}-${compareName ? name : ""}`;
3444
3491
  }
@@ -3452,13 +3499,12 @@ function convertApELikeRegexToRegex(regString = "") {
3452
3499
  let hitLeftCaret;
3453
3500
  let hitRightCaret;
3454
3501
  for (const bp of regString.replace("(", "").replace(")", "")) {
3455
- let maybeHandleRightCaret = function(justAdded) {
3502
+ let maybeHandleRightCaret = /* @__PURE__ */ __name(function(justAdded) {
3456
3503
  if (hitRightCaret) {
3457
3504
  rightOfCaretHolder += justAdded;
3458
3505
  afterRightCaretHolder = `${rightOfCaretHolder}${afterRightCaretHolder.length ? "|" : ""}${afterRightCaretHolder}`;
3459
3506
  }
3460
- };
3461
- __name(maybeHandleRightCaret, "maybeHandleRightCaret");
3507
+ }, "maybeHandleRightCaret");
3462
3508
  const ambigVal = ambiguous_dna_values[bp.toUpperCase()];
3463
3509
  if (ambigVal && ambigVal.length > 1) {
3464
3510
  let valToUse;
@@ -3643,16 +3689,17 @@ const getMergedFeatureMap = /* @__PURE__ */ __name(() => {
3643
3689
  })),
3644
3690
  "name"
3645
3691
  );
3646
- let featureOverrides = typeof window !== "undefined" && get$1(window, "tg_featureTypeOverrides") || typeof global !== "undefined" && get$1(global, "tg_featureTypeOverrides");
3647
- featureOverrides = featureOverrides || [];
3648
- featureOverrides = featureOverrides.map((fo) => {
3692
+ const featureOverrides = typeof window !== "undefined" && get$1(window, "tg_featureTypeOverrides") || typeof global !== "undefined" && get$1(global, "tg_featureTypeOverrides") || [];
3693
+ const mappedOverrides = featureOverrides.map((fo) => {
3649
3694
  const originalGenbankFeat = keyedGBFeats[fo.name];
3650
3695
  return __spreadValues(__spreadValues(__spreadValues({}, originalGenbankFeat), fo), originalGenbankFeat ? { isOverridden: true } : { isCustomType: true });
3651
3696
  });
3652
- featureOverrides = keyBy(featureOverrides, "name");
3653
- return __spreadValues(__spreadValues({}, keyedGBFeats), featureOverrides);
3697
+ const keyedOverrides = keyBy(mappedOverrides, "name");
3698
+ return __spreadValues(__spreadValues({}, keyedGBFeats), keyedOverrides);
3654
3699
  }, "getMergedFeatureMap");
3655
- const getFeatureToColorMap = /* @__PURE__ */ __name(({ includeHidden } = {}) => {
3700
+ const getFeatureToColorMap = /* @__PURE__ */ __name(({
3701
+ includeHidden
3702
+ } = {}) => {
3656
3703
  const toRet = {};
3657
3704
  filter(
3658
3705
  getMergedFeatureMap(),
@@ -3662,7 +3709,9 @@ const getFeatureToColorMap = /* @__PURE__ */ __name(({ includeHidden } = {}) =>
3662
3709
  });
3663
3710
  return toRet;
3664
3711
  }, "getFeatureToColorMap");
3665
- const getFeatureTypes = /* @__PURE__ */ __name(({ includeHidden } = {}) => filter(getMergedFeatureMap(), (f) => includeHidden ? true : !f.isHidden).map(
3712
+ const getFeatureTypes = /* @__PURE__ */ __name(({
3713
+ includeHidden
3714
+ } = {}) => filter(getMergedFeatureMap(), (f) => includeHidden ? true : !f.isHidden).map(
3666
3715
  (f) => f.name
3667
3716
  ), "getFeatureTypes");
3668
3717
  function getDefaultExportFromCjs(x) {
@@ -3967,10 +4016,15 @@ __name(requireShortid, "requireShortid");
3967
4016
  var shortidExports = requireShortid();
3968
4017
  const shortid = /* @__PURE__ */ getDefaultExportFromCjs(shortidExports);
3969
4018
  function cutSequenceByRestrictionEnzyme(pSequence, circular, restrictionEnzyme) {
3970
- if (restrictionEnzyme.forwardRegex.length === 0 || restrictionEnzyme.reverseRegex.length === 0) {
3971
- const returnArray = [];
3972
- returnArray.error = "Cannot cut sequence. Enzyme restriction site must be at least 1 bp long.";
3973
- return returnArray;
4019
+ if (!restrictionEnzyme.forwardRegex || // Add check for undefined
4020
+ !restrictionEnzyme.reverseRegex || // Add check for undefined
4021
+ restrictionEnzyme.forwardRegex.length === 0 || restrictionEnzyme.reverseRegex.length === 0) {
4022
+ console.warn(
4023
+ "Cannot cut sequence. Enzyme restriction site must be at least 1 bp long."
4024
+ );
4025
+ const returnVal = [];
4026
+ returnVal.error = "Cannot cut sequence. Enzyme restriction site must be at least 1 bp long.";
4027
+ return returnVal;
3974
4028
  }
3975
4029
  const forwardRegExpPattern = new RegExp(restrictionEnzyme.forwardRegex, "ig");
3976
4030
  const sequence = pSequence;
@@ -3995,54 +4049,54 @@ function cutSequenceByRestrictionEnzyme(pSequence, circular, restrictionEnzyme)
3995
4049
  }
3996
4050
  return cutsitesForward.concat(cutsitesReverse);
3997
4051
  function reverseAllPositionsOfCutsite(cutsite, rangeLength) {
4052
+ cutsite = assign({}, cutsite);
3998
4053
  cutsite.start = reversePositionInRange(cutsite.start, rangeLength, false);
3999
4054
  cutsite.end = reversePositionInRange(cutsite.end, rangeLength, false);
4000
- cutsite.topSnipPosition = reversePositionInRange(
4001
- cutsite.topSnipPosition,
4002
- rangeLength,
4003
- true
4004
- );
4005
- cutsite.bottomSnipPosition = reversePositionInRange(
4006
- cutsite.bottomSnipPosition,
4007
- rangeLength,
4008
- true
4009
- );
4010
- if (cutsite.cutsTwice) {
4011
- cutsite.upstreamTopSnip = reversePositionInRange(
4012
- cutsite.upstreamTopSnip,
4055
+ cutsite.topSnipPosition = cutsite.topSnipPosition != null ? reversePositionInRange(cutsite.topSnipPosition, rangeLength, true) : null;
4056
+ cutsite.bottomSnipPosition = cutsite.bottomSnipPosition != null ? reversePositionInRange(cutsite.bottomSnipPosition, rangeLength, true) : null;
4057
+ if (cutsite.cutType === 1 && cutsite.cutsTwice) {
4058
+ if (cutsite.upstreamTopSnip != null && cutsite.upstreamBottomSnip != null) {
4059
+ cutsite.upstreamTopSnip = reversePositionInRange(
4060
+ cutsite.upstreamTopSnip,
4061
+ rangeLength,
4062
+ true
4063
+ );
4064
+ cutsite.upstreamBottomSnip = reversePositionInRange(
4065
+ cutsite.upstreamBottomSnip,
4066
+ rangeLength,
4067
+ true
4068
+ );
4069
+ }
4070
+ }
4071
+ if (cutsite.recognitionSiteRange) {
4072
+ cutsite.recognitionSiteRange = __spreadValues({}, cutsite.recognitionSiteRange);
4073
+ cutsite.recognitionSiteRange.start = reversePositionInRange(
4074
+ cutsite.recognitionSiteRange.start,
4013
4075
  rangeLength,
4014
- true
4076
+ false
4015
4077
  );
4016
- cutsite.upstreamBottomSnip = reversePositionInRange(
4017
- cutsite.upstreamBottomSnip,
4078
+ cutsite.recognitionSiteRange.end = reversePositionInRange(
4079
+ cutsite.recognitionSiteRange.end,
4018
4080
  rangeLength,
4019
- true
4081
+ false
4020
4082
  );
4021
4083
  }
4022
- cutsite.recognitionSiteRange.start = reversePositionInRange(
4023
- cutsite.recognitionSiteRange.start,
4024
- rangeLength,
4025
- false
4026
- );
4027
- cutsite.recognitionSiteRange.end = reversePositionInRange(
4028
- cutsite.recognitionSiteRange.end,
4029
- rangeLength,
4030
- false
4031
- );
4032
- return assign({}, cutsite, {
4084
+ return __spreadProps(__spreadValues({}, cutsite), {
4033
4085
  start: cutsite.end,
4034
4086
  end: cutsite.start,
4035
- overhangBps: getReverseComplementSequenceString(cutsite.overhangBps),
4087
+ overhangBps: getReverseComplementSequenceString(
4088
+ cutsite.overhangBps || ""
4089
+ ),
4036
4090
  topSnipPosition: cutsite.bottomSnipPosition,
4037
4091
  bottomSnipPosition: cutsite.topSnipPosition,
4038
4092
  upstreamTopSnip: cutsite.upstreamBottomSnip,
4039
4093
  upstreamBottomSnip: cutsite.upstreamTopSnip,
4040
4094
  upstreamTopBeforeBottom: !!cutsite.upstreamTopBeforeBottom,
4041
4095
  topSnipBeforeBottom: !!cutsite.topSnipBeforeBottom,
4042
- recognitionSiteRange: {
4096
+ recognitionSiteRange: cutsite.recognitionSiteRange ? {
4043
4097
  start: cutsite.recognitionSiteRange.end,
4044
4098
  end: cutsite.recognitionSiteRange.start
4045
- },
4099
+ } : void 0,
4046
4100
  forward: false
4047
4101
  });
4048
4102
  }
@@ -4054,7 +4108,7 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4054
4108
  let restrictionCutSite;
4055
4109
  const recognitionSiteLength = restrictionEnzyme.site.length;
4056
4110
  const originalSequence = sequence;
4057
- const originalSequenceLength = sequence.length;
4111
+ const originalSequenceLengthVal = sequence.length;
4058
4112
  if (circular) {
4059
4113
  sequence += sequence;
4060
4114
  }
@@ -4063,7 +4117,10 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4063
4117
  let startIndex = 0;
4064
4118
  let subSequence = sequence;
4065
4119
  while (matchIndex !== -1) {
4066
- const recognitionSiteRange = {};
4120
+ const recognitionSiteRange = {
4121
+ start: 0,
4122
+ end: 0
4123
+ };
4067
4124
  let start;
4068
4125
  let end;
4069
4126
  let upstreamTopSnip = null;
@@ -4078,37 +4135,39 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4078
4135
  recognitionSiteRange.end = matchIndex + recognitionSiteLength - 1 + startIndex;
4079
4136
  end = recognitionSiteRange.end;
4080
4137
  if (restrictionEnzyme.cutType === 1) {
4081
- upstreamTopSnip = recognitionSiteRange.end - restrictionEnzyme.usForward;
4082
- upstreamBottomSnip = recognitionSiteRange.end - restrictionEnzyme.usReverse;
4083
- if (upstreamTopSnip >= 0 && upstreamBottomSnip >= 0) {
4084
- fitsWithinSequence = true;
4085
- if (upstreamTopSnip < upstreamBottomSnip) {
4086
- if (start > upstreamTopSnip) {
4087
- start = upstreamTopSnip + 1;
4138
+ if (restrictionEnzyme.usForward != null && restrictionEnzyme.usReverse != null) {
4139
+ upstreamTopSnip = recognitionSiteRange.end - restrictionEnzyme.usForward;
4140
+ upstreamBottomSnip = recognitionSiteRange.end - restrictionEnzyme.usReverse;
4141
+ if (upstreamTopSnip >= 0 && upstreamBottomSnip >= 0) {
4142
+ fitsWithinSequence = true;
4143
+ if (upstreamTopSnip < upstreamBottomSnip) {
4144
+ if (start > upstreamTopSnip) {
4145
+ start = upstreamTopSnip + 1;
4146
+ }
4147
+ upstreamTopBeforeBottom = true;
4148
+ } else {
4149
+ if (start > upstreamBottomSnip) {
4150
+ start = upstreamBottomSnip + 1;
4151
+ }
4088
4152
  }
4089
- upstreamTopBeforeBottom = true;
4153
+ upstreamTopSnip = normalizePositionByRangeLength(
4154
+ upstreamTopSnip,
4155
+ originalSequenceLengthVal,
4156
+ true
4157
+ );
4158
+ upstreamBottomSnip = normalizePositionByRangeLength(
4159
+ upstreamBottomSnip,
4160
+ originalSequenceLengthVal,
4161
+ true
4162
+ );
4090
4163
  } else {
4091
- if (start > upstreamBottomSnip) {
4092
- start = upstreamBottomSnip + 1;
4093
- }
4164
+ upstreamTopSnip = null;
4165
+ upstreamBottomSnip = null;
4094
4166
  }
4095
- upstreamTopSnip = normalizePositionByRangeLength(
4096
- upstreamTopSnip,
4097
- originalSequenceLength,
4098
- true
4099
- );
4100
- upstreamBottomSnip = normalizePositionByRangeLength(
4101
- upstreamBottomSnip,
4102
- originalSequenceLength,
4103
- true
4104
- );
4105
- } else {
4106
- upstreamTopSnip = null;
4107
- upstreamBottomSnip = null;
4108
4167
  }
4109
4168
  }
4110
- topSnipPosition = recognitionSiteRange.start + restrictionEnzyme.topSnipOffset;
4111
- bottomSnipPosition = recognitionSiteRange.start + restrictionEnzyme.bottomSnipOffset;
4169
+ topSnipPosition = recognitionSiteRange.start + (restrictionEnzyme.topSnipOffset || 0);
4170
+ bottomSnipPosition = recognitionSiteRange.start + (restrictionEnzyme.bottomSnipOffset || 0);
4112
4171
  if (bottomSnipPosition <= currentSequenceLength && topSnipPosition <= currentSequenceLength) {
4113
4172
  fitsWithinSequence = true;
4114
4173
  if (topSnipPosition > bottomSnipPosition) {
@@ -4123,61 +4182,70 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4123
4182
  }
4124
4183
  topSnipPosition = normalizePositionByRangeLength(
4125
4184
  topSnipPosition,
4126
- originalSequenceLength,
4185
+ originalSequenceLengthVal,
4127
4186
  true
4128
4187
  );
4129
4188
  bottomSnipPosition = normalizePositionByRangeLength(
4130
4189
  bottomSnipPosition,
4131
- originalSequenceLength,
4190
+ originalSequenceLengthVal,
4132
4191
  true
4133
4192
  );
4134
4193
  } else {
4135
4194
  topSnipPosition = null;
4136
4195
  bottomSnipPosition = null;
4137
4196
  }
4138
- if (fitsWithinSequence && start >= 0 && end >= 0 && start < originalSequenceLength && end < currentSequenceLength) {
4197
+ if (fitsWithinSequence && start >= 0 && end >= 0 && start < originalSequenceLengthVal && end < currentSequenceLength) {
4139
4198
  start = normalizePositionByRangeLength(
4140
4199
  start,
4141
- originalSequenceLength,
4200
+ originalSequenceLengthVal,
4201
+ false
4202
+ );
4203
+ end = normalizePositionByRangeLength(
4204
+ end,
4205
+ originalSequenceLengthVal,
4142
4206
  false
4143
4207
  );
4144
- end = normalizePositionByRangeLength(end, originalSequenceLength, false);
4145
4208
  recognitionSiteRange.start = normalizePositionByRangeLength(
4146
4209
  recognitionSiteRange.start,
4147
- originalSequenceLength,
4210
+ originalSequenceLengthVal,
4148
4211
  false
4149
4212
  );
4150
4213
  recognitionSiteRange.end = normalizePositionByRangeLength(
4151
4214
  recognitionSiteRange.end,
4152
- originalSequenceLength,
4215
+ originalSequenceLengthVal,
4153
4216
  false
4154
4217
  );
4155
4218
  let cutRange = {
4156
4219
  start: -1,
4157
4220
  end: -1
4158
4221
  };
4159
- if (topSnipPosition !== bottomSnipPosition) {
4222
+ if (topSnipPosition !== null && bottomSnipPosition !== null && topSnipPosition !== bottomSnipPosition) {
4160
4223
  cutRange = topSnipBeforeBottom ? {
4161
4224
  start: topSnipPosition,
4162
4225
  end: normalizePositionByRangeLength(
4163
4226
  bottomSnipPosition - 1,
4164
- originalSequenceLength
4227
+ originalSequenceLengthVal
4165
4228
  )
4166
4229
  } : {
4167
4230
  start: bottomSnipPosition,
4168
4231
  end: normalizePositionByRangeLength(
4169
4232
  topSnipPosition - 1,
4170
- originalSequenceLength
4233
+ originalSequenceLengthVal
4171
4234
  )
4172
4235
  };
4173
4236
  }
4174
- const overhangBps = getSequenceWithinRange(cutRange, originalSequence);
4237
+ const overhangBps = getSequenceWithinRange(
4238
+ cutRange,
4239
+ originalSequence
4240
+ );
4175
4241
  restrictionCutSite = {
4176
4242
  id: shortid(),
4177
4243
  start,
4178
4244
  end,
4179
4245
  topSnipPosition,
4246
+ // Allow null
4180
4247
  bottomSnipPosition,
4248
+ // Allow null
4181
4249
  topSnipBeforeBottom,
4182
4250
  overhangBps,
4183
4251
  overhangSize: overhangBps.length,
@@ -4199,16 +4267,19 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4199
4267
  return restrictionCutSites;
4200
4268
  }
4201
4269
  __name(cutSequence, "cutSequence");
4202
- function getCutsitesFromSequence(sequence, circular, restrictionEnzymes) {
4203
- const cutsitesByName = {};
4204
- for (let i = 0; i < restrictionEnzymes.length; i++) {
4205
- const re = restrictionEnzymes[i];
4206
- const cutsites = cutSequenceByRestrictionEnzyme(sequence, circular, re);
4207
- if (cutsites.length) {
4208
- cutsitesByName[re.name] = cutsites;
4270
+ function getCutsitesFromSequence(sequence, circular, contextEnzymes) {
4271
+ const cutsites = flatMap(contextEnzymes, (enzyme) => {
4272
+ return cutSequenceByRestrictionEnzyme(sequence, circular, enzyme);
4273
+ });
4274
+ const cutsitesByNameMap = {};
4275
+ cutsites.forEach((cutsite) => {
4276
+ const name = cutsite.name || "";
4277
+ if (!cutsitesByNameMap[name]) {
4278
+ cutsitesByNameMap[name] = [];
4209
4279
  }
4210
- }
4211
- return cutsitesByName;
4280
+ cutsitesByNameMap[name].push(cutsite);
4281
+ });
4282
+ return cutsitesByNameMap;
4212
4283
  }
4213
4284
  __name(getCutsitesFromSequence, "getCutsitesFromSequence");
4214
4285
  function computeDigestFragments({
@@ -4226,9 +4297,9 @@ function computeDigestFragments({
4226
4297
  const fragments = [];
4227
4298
  const overlappingEnzymes = [];
4228
4299
  const pairs = [];
4229
- const sortedCutsites = cutsites.sort((a, b) => {
4230
- return a.topSnipPosition - b.topSnipPosition;
4231
- });
4300
+ const sortedCutsites = cutsites.filter(
4301
+ (c) => c.topSnipPosition != null && c.bottomSnipPosition != null
4302
+ );
4232
4303
  if (!circular && cutsites.length) {
4233
4304
  sortedCutsites.push({
4234
4305
  id: "seqTerm_" + shortid(),
@@ -4237,6 +4308,8 @@ function computeDigestFragments({
4237
4308
  overhangBps: "",
4238
4309
  topSnipPosition: 0,
4239
4310
  bottomSnipPosition: 0,
4311
+ overhangSize: 0,
4312
+ // Added to satisfy CutSite
4240
4313
  upstreamTopSnip: 0,
4241
4314
  upstreamBottomSnip: 0,
4242
4315
  upstreamTopBeforeBottom: false,
@@ -4247,26 +4320,34 @@ function computeDigestFragments({
4247
4320
  },
4248
4321
  forward: true,
4249
4322
  name: "Sequence_Terminus",
4323
+ type: "START_OR_END_OF_SEQ",
4250
4324
  restrictionEnzyme: {
4251
- name: "Sequence_Terminus"
4325
+ name: "Sequence_Terminus",
4326
+ site: "",
4327
+ forwardRegex: "",
4328
+ reverseRegex: ""
4252
4329
  }
4253
4330
  });
4254
4331
  }
4332
+ sortedCutsites.sort((a, b) => {
4333
+ return a.topSnipPosition - b.topSnipPosition;
4334
+ });
4255
4335
  sortedCutsites.forEach((cutsite1, index) => {
4336
+ if (!computeDigestDisabled) {
4337
+ pairs.push([
4338
+ cutsite1,
4339
+ sortedCutsites[index + 1] ? sortedCutsites[index + 1] : sortedCutsites[0]
4340
+ ]);
4341
+ }
4256
4342
  if (computePartialDigest && !computePartialDigestDisabled) {
4257
4343
  sortedCutsites.forEach((cs, index2) => {
4258
- if (index2 === index + 1 || index2 === 0) {
4344
+ const isAdjacent = index2 === index + 1 || index === sortedCutsites.length - 1 && index2 === 0;
4345
+ if (isAdjacent) {
4259
4346
  return;
4260
4347
  }
4261
4348
  pairs.push([cutsite1, sortedCutsites[index2]]);
4262
4349
  });
4263
4350
  }
4264
- if (!computeDigestDisabled) {
4265
- pairs.push([
4266
- cutsite1,
4267
- sortedCutsites[index + 1] ? sortedCutsites[index + 1] : sortedCutsites[0]
4268
- ]);
4269
- }
4270
4351
  });
4271
4352
  pairs.forEach((r) => {
4272
4353
  let [cut1, cut2] = r;
@@ -4311,12 +4392,17 @@ function computeDigestFragments({
4311
4392
  cut2.name = "Linear_Sequence_End";
4312
4393
  cut2.restrictionEnzyme.name = "Linear_Sequence_End";
4313
4394
  }
4395
+ cut1 = __spreadProps(__spreadValues({}, cut1), {
4396
+ isOverhangIncludedInFragmentSize: cut1.name !== "Linear_Sequence_Start" && cut1.name !== "Sequence_Terminus" && (cut1.overhangSize || 0) > 0 && !!cut1.topSnipBeforeBottom
4397
+ });
4398
+ cut2 = __spreadProps(__spreadValues({}, cut2), {
4399
+ isOverhangIncludedInFragmentSize: cut2.name !== "Linear_Sequence_End" && cut2.name !== "Sequence_Terminus" && (cut2.overhangSize || 0) > 0 && !cut2.topSnipBeforeBottom
4400
+ });
4314
4401
  const id = start + "-" + end + "-" + size + "-";
4315
4402
  const name = `${cut1.restrictionEnzyme.name} -- ${cut2.restrictionEnzyme.name} ${size} bps`;
4316
- getRangeLength({ start, end }, sequenceLength);
4317
4403
  fragments.push({
4318
4404
  isFormedFromLinearEnd,
4319
- madeFromOneCutsite: cut1 === cut2,
4405
+ madeFromOneCutsite: cut1.id === cut2.id,
4320
4406
  start,
4321
4407
  end,
4322
4408
  size,
@@ -4357,12 +4443,14 @@ function getDigestFragsForSeqAndEnzymes({
4357
4443
  includeOverAndUnderHangs
4358
4444
  }) {
4359
4445
  const cutsitesByName = getCutsitesFromSequence(sequence, circular, enzymes);
4360
- return computeDigestFragments({
4446
+ const digest = computeDigestFragments({
4361
4447
  includeOverAndUnderHangs,
4362
4448
  cutsites: flatMap(cutsitesByName),
4363
4449
  sequenceLength: sequence.length,
4364
4450
  circular
4365
4451
  });
4452
+ digest.fragments.sort((a, b) => b.size - a.size);
4453
+ return digest;
4366
4454
  }
4367
4455
  __name(getDigestFragsForSeqAndEnzymes, "getDigestFragsForSeqAndEnzymes");
4368
4456
  function cloneRegExp(re) {
@@ -5931,7 +6019,8 @@ function expandAndResolve(threeLetterCodon) {
5931
6019
  let allPossibleThreeLetterCodons = [""];
5932
6020
  for (const set of picks) {
5933
6021
  const next = [];
5934
- for (const prefix of allPossibleThreeLetterCodons) for (const b of set) next.push(prefix + b);
6022
+ for (const prefix of allPossibleThreeLetterCodons)
6023
+ for (const b of set) next.push(prefix + b);
5935
6024
  allPossibleThreeLetterCodons = next;
5936
6025
  }
5937
6026
  let foundAminoAcid = null;
@@ -5977,10 +6066,13 @@ function getAminoAcidFromSequenceTriplet(sequenceString) {
5977
6066
  if (aa) {
5978
6067
  return aa;
5979
6068
  }
5980
- const letter = degenerateDnaToAminoAcidMap[
5981
- sequenceString.replace("x", "n")
5982
- //replace x's with n's as those are equivalent dna chars
5983
- ] || "x";
6069
+ const letter = (
6070
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6071
+ degenerateDnaToAminoAcidMap[
6072
+ sequenceString.replace("x", "n")
6073
+ //replace x's with n's as those are equivalent dna chars
6074
+ ] || "x"
6075
+ );
5984
6076
  return proteinAlphabet[letter.toUpperCase()];
5985
6077
  }
5986
6078
  __name(getAminoAcidFromSequenceTriplet, "getAminoAcidFromSequenceTriplet");
@@ -6377,25 +6469,25 @@ function coerceLocation({
6377
6469
  circular,
6378
6470
  name
6379
6471
  }) {
6380
- location.start = parseInt(location.start, 10);
6381
- location.end = parseInt(location.end, 10);
6472
+ location.start = parseInt(String(location.start), 10);
6473
+ location.end = parseInt(String(location.end), 10);
6382
6474
  if (convertAnnotationsFromAAIndices) {
6383
6475
  location.start = location.start * 3;
6384
6476
  location.end = location.end * 3 + 2;
6385
6477
  }
6386
- if (location.start < 0 || !(location.start <= size - 1) || location.start > size - 1) {
6478
+ if (size !== void 0 && (location.start < 0 || location.start > size - 1)) {
6387
6479
  messages.push(
6388
6480
  "Invalid annotation start: " + location.start + " detected for " + location.name + " and set to size: " + size
6389
6481
  );
6390
6482
  location.start = Math.max(0, size - (isProtein ? 3 : 1));
6391
6483
  }
6392
- if (location.end < 0 || !(location.end <= size - 1) || location.end > size - 1) {
6484
+ if (size !== void 0 && (location.end < 0 || location.end > size - 1)) {
6393
6485
  messages.push(
6394
6486
  "Invalid annotation end: " + location.end + " detected for " + location.name + " and set to seq size: " + size
6395
6487
  );
6396
6488
  location.end = Math.max(0, size - 1);
6397
6489
  }
6398
- if (location.start > location.end && circular === false) {
6490
+ if (size !== void 0 && location.start > location.end && circular === false) {
6399
6491
  messages.push(
6400
6492
  "Invalid circular annotation detected for " + name + ". end set to 1"
6401
6493
  );
@@ -6404,21 +6496,30 @@ function coerceLocation({
6404
6496
  }
6405
6497
  __name(coerceLocation, "coerceLocation");
6406
6498
  function getDegenerateDnaStringFromAAString(aaString) {
6407
- return aaString.split("").map((char) => aminoAcidToDegenerateDnaMap[char.toLowerCase()] || "nnn").join("");
6499
+ return aaString.split("").map(
6500
+ (char) => aminoAcidToDegenerateDnaMap[char.toLowerCase()] || "nnn"
6501
+ ).join("");
6408
6502
  }
6409
6503
  __name(getDegenerateDnaStringFromAAString, "getDegenerateDnaStringFromAAString");
6410
- function getAminoAcidStringFromSequenceString(sequenceString, { doNotExcludeAsterisk } = {}) {
6504
+ function getAminoAcidStringFromSequenceString(sequenceString, options = {}) {
6505
+ const { doNotExcludeAsterisk } = options;
6411
6506
  const aminoAcidsPerBase = getAminoAcidDataForEachBaseOfDna(
6412
6507
  sequenceString,
6413
- true
6508
+ true,
6509
+ null,
6510
+ false
6414
6511
  );
6415
6512
  const aaArray = [];
6416
6513
  let aaString = "";
6417
6514
  aminoAcidsPerBase.forEach((aa, index) => {
6515
+ var _a;
6418
6516
  if (!aa.fullCodon) {
6419
6517
  return;
6420
6518
  }
6421
- if (!doNotExcludeAsterisk && index >= aminoAcidsPerBase.length - 3 && aa.aminoAcid.value === "*") {
6519
+ if (!doNotExcludeAsterisk && index >= aminoAcidsPerBase.length - 3 && ((_a = aa.aminoAcid) == null ? void 0 : _a.value) === "*") {
6520
+ return;
6521
+ }
6522
+ if (aa.aminoAcidIndex === null || !aa.aminoAcid) {
6422
6523
  return;
6423
6524
  }
6424
6525
  aaArray[aa.aminoAcidIndex] = aa.aminoAcid.value;
@@ -6445,7 +6546,7 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6445
6546
  messages: []
6446
6547
  };
6447
6548
  if (!seqData) {
6448
- seqData = {};
6549
+ seqData = { sequence: "" };
6449
6550
  }
6450
6551
  if (!seqData.sequence) {
6451
6552
  seqData.sequence = "";
@@ -6508,25 +6609,27 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6508
6609
  const featureTypes = getFeatureTypes();
6509
6610
  annotationTypes.forEach((annotationType) => {
6510
6611
  if (!Array.isArray(seqData[annotationType])) {
6511
- if (typeof seqData[annotationType] === "object") {
6512
- seqData[annotationType] = Object.keys(seqData[annotationType]).map(
6513
- (key) => {
6514
- return seqData[annotationType][key];
6515
- }
6516
- );
6612
+ if (seqData[annotationType] && typeof seqData[annotationType] === "object") {
6613
+ seqData[annotationType] = Object.keys(
6614
+ seqData[annotationType]
6615
+ ).map((key) => {
6616
+ return seqData[annotationType][key];
6617
+ });
6517
6618
  } else {
6518
6619
  seqData[annotationType] = [];
6519
6620
  }
6520
6621
  }
6521
- seqData[annotationType] = seqData[annotationType].filter((annotation) => {
6522
- return tidyUpAnnotation(annotation, __spreadProps(__spreadValues({}, options), {
6523
- featureTypes,
6524
- sequenceData: seqData,
6525
- convertAnnotationsFromAAIndices,
6526
- mutative: true,
6527
- annotationType
6528
- }));
6529
- });
6622
+ seqData[annotationType] = seqData[annotationType].filter(
6623
+ (annotation) => {
6624
+ return tidyUpAnnotation(annotation, __spreadProps(__spreadValues({}, options), {
6625
+ featureTypes,
6626
+ sequenceData: seqData,
6627
+ convertAnnotationsFromAAIndices,
6628
+ mutative: true,
6629
+ annotationType
6630
+ }));
6631
+ }
6632
+ );
6530
6633
  });
6531
6634
  if (!noTranslationData) {
6532
6635
  seqData.translations = flatMap(seqData.translations, (translation) => {
@@ -6534,7 +6637,7 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6534
6637
  if (noCdsTranslations && translation.translationType === "CDS Feature") {
6535
6638
  return [];
6536
6639
  }
6537
- const codonStart = ((_b = (_a = translation == null ? void 0 : translation.notes) == null ? void 0 : _a.codon_start) == null ? void 0 : _b[0]) - 1 || 0;
6640
+ const codonStart = ((_b = (_a = translation == null ? void 0 : translation.notes) == null ? void 0 : _a["codon_start"]) == null ? void 0 : _b[0]) - 1 || 0;
6538
6641
  const expandedRange = expandOrContractRangeByLength(
6539
6642
  translation,
6540
6643
  -codonStart,
@@ -6544,8 +6647,9 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6544
6647
  if (!expandedRange.aminoAcids && !seqData.noSequence) {
6545
6648
  expandedRange.aminoAcids = getAminoAcidDataForEachBaseOfDna(
6546
6649
  seqData.sequence,
6547
- expandedRange.forward,
6548
- expandedRange
6650
+ expandedRange.forward || false,
6651
+ expandedRange,
6652
+ false
6549
6653
  );
6550
6654
  }
6551
6655
  return expandedRange;
@@ -6553,19 +6657,22 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6553
6657
  }
6554
6658
  if (annotationsAsObjects) {
6555
6659
  annotationTypes.forEach((name) => {
6556
- seqData[name] = seqData[name].reduce((acc, item) => {
6557
- let itemId;
6558
- if (item.id || item.id === 0) {
6559
- itemId = item.id;
6560
- } else {
6561
- itemId = shortid();
6562
- if (!doNotProvideIdsForAnnotations) {
6563
- item.id = itemId;
6660
+ seqData[name] = seqData[name].reduce(
6661
+ (acc, item) => {
6662
+ let itemId;
6663
+ if (item.id || item.id === 0) {
6664
+ itemId = item.id;
6665
+ } else {
6666
+ itemId = shortid();
6667
+ if (!doNotProvideIdsForAnnotations) {
6668
+ item.id = itemId;
6669
+ }
6564
6670
  }
6565
- }
6566
- acc[itemId] = item;
6567
- return acc;
6568
- }, {});
6671
+ acc[itemId] = item;
6672
+ return acc;
6673
+ },
6674
+ {}
6675
+ );
6569
6676
  });
6570
6677
  }
6571
6678
  if (logMessages && response.messages.length > 0) {
@@ -6575,17 +6682,17 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6575
6682
  }
6576
6683
  __name(tidyUpSequenceData, "tidyUpSequenceData");
6577
6684
  const getDiffFromSeqs = /* @__PURE__ */ __name((oldData, newData, { ignoreKeys = [] } = {}) => {
6578
- oldData = tidyUpSequenceData(oldData, {
6685
+ const cleanedOldData = tidyUpSequenceData(oldData, {
6579
6686
  annotationsAsObjects: true,
6580
6687
  noTranslationData: true,
6581
6688
  doNotRemoveInvalidChars: true
6582
6689
  });
6583
- newData = tidyUpSequenceData(newData, {
6690
+ const cleanedNewData = tidyUpSequenceData(newData, {
6584
6691
  annotationsAsObjects: true,
6585
6692
  noTranslationData: true,
6586
6693
  doNotRemoveInvalidChars: true
6587
6694
  });
6588
- [oldData, newData].forEach((d) => {
6695
+ [cleanedOldData, cleanedNewData].forEach((d) => {
6589
6696
  [
6590
6697
  "cutsites",
6591
6698
  "orfs",
@@ -6608,27 +6715,26 @@ const getDiffFromSeqs = /* @__PURE__ */ __name((oldData, newData, { ignoreKeys =
6608
6715
  });
6609
6716
  }
6610
6717
  });
6611
- return diff(oldData, newData);
6718
+ return diff(cleanedOldData, cleanedNewData);
6612
6719
  }, "getDiffFromSeqs");
6613
- const patchSeqWithDiff = /* @__PURE__ */ __name((oldData, diff2, { ignoreKeys = [] } = {}) => {
6720
+ const patchSeqWithDiff = /* @__PURE__ */ __name((oldData, diffData, { ignoreKeys = [] } = {}) => {
6614
6721
  ignoreKeys.forEach((k) => {
6615
- delete diff2[k];
6722
+ delete diffData[k];
6616
6723
  });
6617
- return patch(
6618
- tidyUpSequenceData(cloneDeep(oldData), {
6619
- annotationsAsObjects: true,
6620
- doNotRemoveInvalidChars: true
6621
- }),
6622
- diff2
6623
- );
6724
+ const tidyOld = tidyUpSequenceData(cloneDeep(oldData), {
6725
+ annotationsAsObjects: true,
6726
+ doNotRemoveInvalidChars: true
6727
+ });
6728
+ return patch(tidyOld, diffData);
6624
6729
  }, "patchSeqWithDiff");
6625
- const reverseSeqDiff = /* @__PURE__ */ __name((diff2) => {
6626
- return reverse(diff2);
6730
+ const reverseSeqDiff = /* @__PURE__ */ __name((diffData) => {
6731
+ return reverse(diffData);
6627
6732
  }, "reverseSeqDiff");
6628
6733
  function getAllInsertionsInSeqReads(seqReads) {
6629
6734
  const allInsertionsInSeqReads = [];
6630
6735
  seqReads.forEach((seqRead) => {
6631
6736
  const splitSeqRead = seqRead.cigar.match(/([0-9]*[MDI])/g);
6737
+ if (!splitSeqRead) return;
6632
6738
  for (let componentI = 0; componentI < splitSeqRead.length; componentI++) {
6633
6739
  if (splitSeqRead[componentI].slice(-1) === "I") {
6634
6740
  let bpPosOfInsertion = seqRead.pos;
@@ -6672,14 +6778,19 @@ function getAllInsertionsInSeqReads(seqReads) {
6672
6778
  return sortedInsertions;
6673
6779
  }
6674
6780
  __name(getAllInsertionsInSeqReads, "getAllInsertionsInSeqReads");
6675
- function annotateSingleSeq({ fullSeq, searchSeq }) {
6781
+ function annotateSingleSeq({
6782
+ fullSeq,
6783
+ searchSeq
6784
+ }) {
6676
6785
  const fullSeqId = fullSeq.id || "fullSeqId";
6677
6786
  const searchSeqId = searchSeq.id || "searchSeqId";
6678
6787
  const results = autoAnnotate({
6679
6788
  seqsToAnnotateById: {
6680
- [fullSeqId]: __spreadProps(__spreadValues({}, fullSeq), {
6681
- id: fullSeqId
6682
- })
6789
+ [fullSeqId]: {
6790
+ sequence: fullSeq.sequence,
6791
+ circular: fullSeq.circular,
6792
+ annotations: fullSeq.features || []
6793
+ }
6683
6794
  },
6684
6795
  annotationsToCheckById: {
6685
6796
  [searchSeqId]: __spreadProps(__spreadValues({}, searchSeq), {
@@ -6729,7 +6840,9 @@ const aminoAcidToDegenerateRnaMap = {
6729
6840
  z: "sar"
6730
6841
  };
6731
6842
  function getDegenerateRnaStringFromAAString(aaString) {
6732
- return aaString.split("").map((char) => aminoAcidToDegenerateRnaMap[char.toLowerCase()] || "nnn").join("");
6843
+ return aaString.split("").map(
6844
+ (char) => aminoAcidToDegenerateRnaMap[char.toLowerCase()] || "nnn"
6845
+ ).join("");
6733
6846
  }
6734
6847
  __name(getDegenerateRnaStringFromAAString, "getDegenerateRnaStringFromAAString");
6735
6848
  function getVirtualDigest({
@@ -6744,7 +6857,7 @@ function getVirtualDigest({
6744
6857
  const overlappingEnzymes = [];
6745
6858
  const pairs = [];
6746
6859
  const sortedCutsites = cutsites.sort((a, b) => {
6747
- return a.topSnipPosition - b.topSnipPosition;
6860
+ return (a.topSnipPosition || 0) - (b.topSnipPosition || 0);
6748
6861
  });
6749
6862
  sortedCutsites.forEach((cutsite1, index) => {
6750
6863
  if (computePartialDigest && !computePartialDigestDisabled) {
@@ -6761,11 +6874,11 @@ function getVirtualDigest({
6761
6874
  });
6762
6875
  pairs.forEach(([cut1, cut2]) => {
6763
6876
  const start = normalizePositionByRangeLength(
6764
- cut1.topSnipPosition,
6877
+ cut1.topSnipPosition || 0,
6765
6878
  sequenceLength
6766
6879
  );
6767
6880
  const end = normalizePositionByRangeLength(
6768
- cut2.topSnipPosition - 1,
6881
+ (cut2.topSnipPosition || 0) - 1,
6769
6882
  sequenceLength
6770
6883
  );
6771
6884
  if (!isCircular && start > end) {
@@ -6779,6 +6892,7 @@ function getVirtualDigest({
6779
6892
  name: "End Of Seq"
6780
6893
  }
6781
6894
  }
6895
+ // Cast to CutSite as it's a mock
6782
6896
  };
6783
6897
  const frag2 = {
6784
6898
  start: 0,
@@ -6789,6 +6903,7 @@ function getVirtualDigest({
6789
6903
  name: "Start Of Seq"
6790
6904
  }
6791
6905
  },
6906
+ // Cast
6792
6907
  cut2
6793
6908
  };
6794
6909
  fragments.push(addSizeIdName(frag1, sequenceLength));
@@ -6891,27 +7006,18 @@ function findApproxMatches(searchSeq, targetSeq, maxMismatches, circular = false
6891
7006
  return matches;
6892
7007
  }
6893
7008
  __name(findApproxMatches, "findApproxMatches");
6894
- var spliceString$1;
6895
- var hasRequiredSpliceString;
6896
- function requireSpliceString() {
6897
- if (hasRequiredSpliceString) return spliceString$1;
6898
- hasRequiredSpliceString = 1;
6899
- spliceString$1 = /* @__PURE__ */ __name(function spliceSlice(str, index, count, add) {
6900
- return str.slice(0, index) + (add || "") + str.slice(index + count);
6901
- }, "spliceSlice");
6902
- return spliceString$1;
6903
- }
6904
- __name(requireSpliceString, "requireSpliceString");
6905
- var spliceStringExports = requireSpliceString();
6906
- const spliceString = /* @__PURE__ */ getDefaultExportFromCjs(spliceStringExports);
6907
7009
  function adjustBpsToReplaceOrInsert(bpString, insertString = "", caretPositionOrRange) {
6908
7010
  let stringToReturn = bpString;
6909
- if (caretPositionOrRange && caretPositionOrRange.start > -1) {
7011
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange && caretPositionOrRange.start > -1) {
6910
7012
  if (getRangeLength(caretPositionOrRange, bpString.length) === bpString.length) {
6911
7013
  return insertString;
6912
7014
  }
6913
7015
  const ranges = splitRangeIntoTwoPartsIfItIsCircular(
6914
- invertRange(caretPositionOrRange, bpString.length)
7016
+ invertRange(
7017
+ caretPositionOrRange,
7018
+ bpString.length
7019
+ ),
7020
+ bpString.length
6915
7021
  );
6916
7022
  stringToReturn = "";
6917
7023
  ranges.forEach((range, index) => {
@@ -6937,6 +7043,16 @@ function adjustBpsToReplaceOrInsert(bpString, insertString = "", caretPositionOr
6937
7043
  return stringToReturn;
6938
7044
  }
6939
7045
  __name(adjustBpsToReplaceOrInsert, "adjustBpsToReplaceOrInsert");
7046
+ const spliceString = /* @__PURE__ */ __name((str, index, count, add) => {
7047
+ let i = index;
7048
+ if (i < 0) {
7049
+ i = str.length + i;
7050
+ if (i < 0) {
7051
+ i = 0;
7052
+ }
7053
+ }
7054
+ return str.slice(0, i) + (add || "") + str.slice(i + count);
7055
+ }, "spliceString");
6940
7056
  function calculatePercentGC(bps) {
6941
7057
  return (bps.match(/[cg]/gi) || []).length / bps.length * 100 || 0;
6942
7058
  }
@@ -6962,11 +7078,17 @@ const calcTmMethods = {
6962
7078
  * monovalentCationConc - THe monovalent salt concentration. Defaults to 50e-3M.
6963
7079
  * return - Temperature for the given sequence, in Celsius.
6964
7080
  */
6965
- calculateTemperature: /* @__PURE__ */ __name(function(_sequence, { type, A, R, primerConc, monovalentCationConc } = {}) {
7081
+ calculateTemperature: /* @__PURE__ */ __name(function(_sequence, {
7082
+ type,
7083
+ A,
7084
+ R,
7085
+ primerConc,
7086
+ monovalentCationConc
7087
+ } = {}) {
6966
7088
  const sequence = (_sequence || "").toLowerCase();
6967
7089
  if (typeof type === "undefined") {
6968
7090
  type = this.TABLE_BRESLAUER;
6969
- } else if (type != this.TABLE_BRESLAUER && type != this.TABLE_UNIFIED && type != this.TABLE_SUGIMOTO) {
7091
+ } else if (type !== this.TABLE_BRESLAUER && type !== this.TABLE_UNIFIED && type !== this.TABLE_SUGIMOTO) {
6970
7092
  throw new Error("Invalid table type!");
6971
7093
  }
6972
7094
  if (!A) {
@@ -6982,11 +7104,14 @@ const calcTmMethods = {
6982
7104
  monovalentCationConc = this.monovalentCationConc;
6983
7105
  }
6984
7106
  const sequenceLength = sequence.length;
6985
- if (sequenceLength == 0) {
7107
+ if (sequenceLength === 0) {
6986
7108
  return 0;
6987
7109
  }
6988
7110
  const deltaHTable = this.getDeltaHTable(type);
6989
7111
  const deltaSTable = this.getDeltaSTable(type);
7112
+ if (!deltaHTable || !deltaSTable) {
7113
+ return 0;
7114
+ }
6990
7115
  const neighbors = [];
6991
7116
  neighbors.push(this.calculateReps(sequence, "aa"));
6992
7117
  neighbors.push(this.calculateNumberOfOccurrences(sequence, "at"));
@@ -7020,7 +7145,7 @@ const calcTmMethods = {
7020
7145
  * @return {Number[]} deltaH table for given algorithm.
7021
7146
  */
7022
7147
  getDeltaHTable: /* @__PURE__ */ __name(function(type) {
7023
- if (type == this.TABLE_BRESLAUER) {
7148
+ if (type === this.TABLE_BRESLAUER) {
7024
7149
  return [
7025
7150
  9.1,
7026
7151
  8.6,
@@ -7039,7 +7164,7 @@ const calcTmMethods = {
7039
7164
  6.5,
7040
7165
  11.1
7041
7166
  ];
7042
- } else if (type == this.TABLE_SUGIMOTO) {
7167
+ } else if (type === this.TABLE_SUGIMOTO) {
7043
7168
  return [
7044
7169
  8,
7045
7170
  5.6,
@@ -7058,7 +7183,7 @@ const calcTmMethods = {
7058
7183
  9.4,
7059
7184
  11.9
7060
7185
  ];
7061
- } else if (type == this.TABLE_UNIFIED) {
7186
+ } else if (type === this.TABLE_UNIFIED) {
7062
7187
  return [
7063
7188
  7.9,
7064
7189
  7.2,
@@ -7081,39 +7206,6 @@ const calcTmMethods = {
7081
7206
  return null;
7082
7207
  }
7083
7208
  }, "getDeltaHTable"),
7084
- // "AA/TT": -7.9, 7.9
7085
- // "AT/TA": -7.2, 7.2
7086
- // "AC/TG": -8.4, 8.4
7087
- // "AG/TC": -7.8, 7.8
7088
- // "TT/AA": -7.9, 7.9
7089
- // "TA/AT": -7.2, 7.2
7090
- // "TG/AC": -8.5, 8.2
7091
- // "TC/AG": -8.2, 8.5
7092
- // "CC/GG": -8.0, 8.0
7093
- // "CA/GT": -8.5, 8.5
7094
- // "CT/GA": -7.8, 7.8
7095
- // "CG/GC": -10.6, 10.6
7096
- // "GG/CC": -8.0, 8.0
7097
- // "GA/CT": -8.2, 8.2,
7098
- // "GT/CA": -8.4, 8.4
7099
- // "GC/CG": -9.8, 9.8
7100
- // aa, at, ac, ag, tt, ta, tc, tg, cc, ca, ct, cg, gg, ga, gt, gc
7101
- // "AA/TT": -22.2,22.2,
7102
- // "AT/TA": -20.4,20.4,
7103
- // "AC/TG": -22.4,22.4,
7104
- // "AG/TC": -21.0,21.0,
7105
- // "TT/AA": -22.2,22.2,
7106
- // "TA/AT": -21.3,21.3,
7107
- // "TC/AG": -22.2,22.2,
7108
- // "TG/AC": -22.7,22.7,
7109
- // "CC/GG": -19.9,19.9,
7110
- // "CA/GT": -22.7,22.7,
7111
- // "CT/GA": -21.0,21.0,
7112
- // "CG/GC": -27.2,27.2,
7113
- // "GG/CC": -19.9,19.9,
7114
- // "GT/CA": -22.4,22.2,
7115
- // "GA/CT": -22.2,22.4,
7116
- // "GC/CG": -24.4,24.4
7117
7209
  /**
7118
7210
  * @private
7119
7211
  * Function to return deltaS table for given algorithm.
@@ -7121,7 +7213,7 @@ const calcTmMethods = {
7121
7213
  * @return {Number[]} deltaS table for given algorithm.
7122
7214
  */
7123
7215
  getDeltaSTable: /* @__PURE__ */ __name(function(type) {
7124
- if (type == this.TABLE_BRESLAUER) {
7216
+ if (type === this.TABLE_BRESLAUER) {
7125
7217
  return [
7126
7218
  24,
7127
7219
  23.9,
@@ -7140,7 +7232,7 @@ const calcTmMethods = {
7140
7232
  17.3,
7141
7233
  26.7
7142
7234
  ];
7143
- } else if (type == this.TABLE_SUGIMOTO) {
7235
+ } else if (type === this.TABLE_SUGIMOTO) {
7144
7236
  return [
7145
7237
  21.9,
7146
7238
  15.2,
@@ -7159,7 +7251,7 @@ const calcTmMethods = {
7159
7251
  25.5,
7160
7252
  29
7161
7253
  ];
7162
- } else if (type == this.TABLE_UNIFIED) {
7254
+ } else if (type === this.TABLE_UNIFIED) {
7163
7255
  return [
7164
7256
  22.2,
7165
7257
  20.4,
@@ -7193,14 +7285,14 @@ const calcTmMethods = {
7193
7285
  */
7194
7286
  calculateReps: /* @__PURE__ */ __name(function(sequence, target) {
7195
7287
  const sequenceLength = sequence.length;
7196
- if (sequenceLength == 0) {
7288
+ if (sequenceLength === 0) {
7197
7289
  return 0;
7198
7290
  }
7199
7291
  let numFound = 0;
7200
7292
  let seqOffset = 0;
7201
7293
  while (true) {
7202
7294
  const foundSeq = sequence.indexOf(target, seqOffset);
7203
- if (foundSeq == -1) {
7295
+ if (foundSeq === -1) {
7204
7296
  break;
7205
7297
  }
7206
7298
  seqOffset = foundSeq + 1;
@@ -7220,7 +7312,7 @@ const calcTmMethods = {
7220
7312
  */
7221
7313
  calculateNumberOfOccurrences: /* @__PURE__ */ __name(function(sequence, target) {
7222
7314
  const sequenceLength = sequence.length;
7223
- if (sequenceLength == 0) {
7315
+ if (sequenceLength === 0) {
7224
7316
  return 0;
7225
7317
  }
7226
7318
  const numberFound = sequence.split(target).length - 1;
@@ -7255,11 +7347,11 @@ function rotateBpsToPosition(bps, caretPosition) {
7255
7347
  __name(rotateBpsToPosition, "rotateBpsToPosition");
7256
7348
  function arrayRotate(arr, count) {
7257
7349
  count -= arr.length * Math.floor(count / arr.length);
7258
- arr.push.apply(arr, arr.splice(0, count));
7350
+ arr.push(...arr.splice(0, count));
7259
7351
  return arr;
7260
7352
  }
7261
7353
  __name(arrayRotate, "arrayRotate");
7262
- function rotateSequenceDataToPosition(sequenceData, caretPosition, options) {
7354
+ function rotateSequenceDataToPosition(sequenceData, caretPosition, options = {}) {
7263
7355
  const newSequenceData = tidyUpSequenceData(sequenceData, __spreadValues({
7264
7356
  doNotRemoveInvalidChars: true
7265
7357
  }, options));
@@ -7307,16 +7399,24 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7307
7399
  }, options));
7308
7400
  const newSequenceData = cloneDeep(existingSequenceData);
7309
7401
  const insertLength = sequenceDataToInsert.isProtein && sequenceDataToInsert.proteinSequence ? sequenceDataToInsert.proteinSequence.length * 3 : sequenceDataToInsert.sequence.length;
7310
- let caretPosition = caretPositionOrRange;
7311
- const isInsertSameLengthAsSelection = sequenceDataToInsert.sequence.length === getRangeLength(caretPositionOrRange, existingSequenceData.sequence.length);
7312
- if (caretPositionOrRange.start > -1 && getRangeLength(
7402
+ let caretPosition = typeof caretPositionOrRange === "number" ? caretPositionOrRange : caretPositionOrRange.start;
7403
+ const isInsertSameLengthAsSelection = typeof caretPositionOrRange !== "number" && sequenceDataToInsert.sequence.length === getRangeLength(
7404
+ caretPositionOrRange,
7405
+ existingSequenceData.sequence.length
7406
+ );
7407
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1 && getRangeLength(
7313
7408
  caretPositionOrRange,
7314
7409
  existingSequenceData.sequence.length
7315
7410
  ) === existingSequenceData.sequence.length) {
7411
+ const emptyAnnotations = modifiableTypes.reduce(
7412
+ (acc, type) => {
7413
+ acc[type] = [];
7414
+ return acc;
7415
+ },
7416
+ {}
7417
+ );
7316
7418
  existingSequenceData = tidyUpSequenceData(
7317
- __spreadProps(__spreadValues(__spreadValues({}, existingSequenceData), modifiableTypes.reduce((acc, type) => {
7318
- return acc[type] = [];
7319
- }, {})), {
7419
+ __spreadProps(__spreadValues(__spreadValues({}, existingSequenceData), emptyAnnotations), {
7320
7420
  sequence: "",
7321
7421
  doNotRemoveInvalidChars: true,
7322
7422
  proteinSequence: "",
@@ -7326,7 +7426,7 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7326
7426
  );
7327
7427
  newSequenceData.chromatogramData = void 0;
7328
7428
  } else if (newSequenceData.chromatogramData && newSequenceData.chromatogramData.baseTraces) {
7329
- if (caretPositionOrRange && caretPositionOrRange.start > -1) {
7429
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1) {
7330
7430
  if (caretPositionOrRange.start > caretPositionOrRange.end) {
7331
7431
  newSequenceData.chromatogramData = trimChromatogram({
7332
7432
  chromatogramData: newSequenceData.chromatogramData,
@@ -7336,14 +7436,16 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7336
7436
  },
7337
7437
  justBaseCalls: isInsertSameLengthAsSelection
7338
7438
  });
7339
- newSequenceData.chromatogramData = trimChromatogram({
7340
- chromatogramData: newSequenceData.chromatogramData,
7341
- range: {
7342
- start: 0,
7343
- end: caretPositionOrRange.end
7344
- },
7345
- justBaseCalls: isInsertSameLengthAsSelection
7346
- });
7439
+ if (newSequenceData.chromatogramData) {
7440
+ newSequenceData.chromatogramData = trimChromatogram({
7441
+ chromatogramData: newSequenceData.chromatogramData,
7442
+ range: {
7443
+ start: 0,
7444
+ end: caretPositionOrRange.end
7445
+ },
7446
+ justBaseCalls: isInsertSameLengthAsSelection
7447
+ });
7448
+ }
7347
7449
  } else {
7348
7450
  newSequenceData.chromatogramData = trimChromatogram({
7349
7451
  chromatogramData: newSequenceData.chromatogramData,
@@ -7355,10 +7457,10 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7355
7457
  });
7356
7458
  }
7357
7459
  }
7358
- if (sequenceDataToInsert.sequence) {
7460
+ if (sequenceDataToInsert.sequence && newSequenceData.chromatogramData) {
7359
7461
  insertIntoChromatogram({
7360
7462
  chromatogramData: newSequenceData.chromatogramData,
7361
- caretPosition: caretPositionOrRange.start > -1 ? caretPositionOrRange.start : caretPositionOrRange,
7463
+ caretPosition: typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1 ? caretPositionOrRange.start : caretPositionOrRange,
7362
7464
  seqToInsert: sequenceDataToInsert.sequence,
7363
7465
  justBaseCalls: isInsertSameLengthAsSelection
7364
7466
  });
@@ -7371,14 +7473,15 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7371
7473
  );
7372
7474
  newSequenceData.size = newSequenceData.sequence.length;
7373
7475
  newSequenceData.proteinSequence = adjustBpsToReplaceOrInsert(
7374
- existingSequenceData.proteinSequence,
7375
- sequenceDataToInsert.proteinSequence,
7476
+ existingSequenceData.proteinSequence || "",
7477
+ sequenceDataToInsert.proteinSequence || "",
7376
7478
  convertDnaCaretPositionOrRangeToAA(caretPositionOrRange)
7377
7479
  );
7378
- newSequenceData.proteinSize = newSequenceData.proteinSequence.length;
7480
+ newSequenceData.proteinSize = (newSequenceData.proteinSequence || "").length;
7379
7481
  modifiableTypes.forEach((annotationType) => {
7380
7482
  let existingAnnotations = existingSequenceData[annotationType];
7381
- if (caretPositionOrRange && caretPositionOrRange.start > -1) {
7483
+ if (!existingAnnotations) return;
7484
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1) {
7382
7485
  const range = caretPositionOrRange;
7383
7486
  caretPosition = range.start > range.end ? 0 : range.start;
7384
7487
  existingAnnotations = adjustAnnotationsToDelete(
@@ -7388,22 +7491,23 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7388
7491
  );
7389
7492
  }
7390
7493
  newSequenceData[annotationType] = [];
7391
- newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7392
- adjustAnnotationsToInsert(
7393
- existingAnnotations,
7394
- caretPosition,
7395
- insertLength
7396
- )
7397
- );
7398
- newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7399
- adjustAnnotationsToInsert(
7400
- sequenceDataToInsert[annotationType],
7401
- 0,
7402
- caretPosition
7403
- )
7404
- );
7494
+ const annotationsToInsert = sequenceDataToInsert[annotationType];
7495
+ if (newSequenceData[annotationType]) {
7496
+ newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7497
+ adjustAnnotationsToInsert(
7498
+ existingAnnotations,
7499
+ caretPosition,
7500
+ insertLength
7501
+ )
7502
+ );
7503
+ if (annotationsToInsert) {
7504
+ newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7505
+ adjustAnnotationsToInsert(annotationsToInsert, 0, caretPosition)
7506
+ );
7507
+ }
7508
+ }
7405
7509
  });
7406
- if (maintainOriginSplit && caretPositionOrRange && caretPositionOrRange.start > caretPositionOrRange.end) {
7510
+ if (maintainOriginSplit && typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > caretPositionOrRange.end) {
7407
7511
  const caretPosToRotateTo = existingSequenceData.sequence.length - caretPositionOrRange.start;
7408
7512
  return rotateSequenceDataToPosition(
7409
7513
  newSequenceData,
@@ -7421,6 +7525,7 @@ function adjustAnnotationsToDelete(annotationsToBeAdjusted, range, maxLength) {
7421
7525
  maxLength
7422
7526
  );
7423
7527
  const newLocations = annotation.locations && annotation.locations.map((loc) => adjustRangeToDeletionOfAnotherRange(loc, range, maxLength)).filter((range2) => !!range2);
7528
+ if (!newRange) return null;
7424
7529
  if (newLocations && newLocations.length) {
7425
7530
  return __spreadValues(__spreadProps(__spreadValues({}, newRange), {
7426
7531
  start: newLocations[0].start,
@@ -7439,11 +7544,13 @@ function insertIntoChromatogram({
7439
7544
  justBaseCalls
7440
7545
  }) {
7441
7546
  if (!seqToInsert.length) return;
7442
- chromatogramData.baseCalls && chromatogramData.baseCalls.splice(
7443
- caretPosition,
7444
- 0,
7445
- ...seqToInsert.split("")
7446
- );
7547
+ if (chromatogramData.baseCalls) {
7548
+ chromatogramData.baseCalls.splice(
7549
+ caretPosition,
7550
+ 0,
7551
+ ...seqToInsert.split("")
7552
+ );
7553
+ }
7447
7554
  if (justBaseCalls) {
7448
7555
  return chromatogramData;
7449
7556
  }
@@ -7459,8 +7566,20 @@ function insertIntoChromatogram({
7459
7566
  tTrace: toPush
7460
7567
  });
7461
7568
  }
7462
- chromatogramData.baseTraces && chromatogramData.baseTraces.splice(caretPosition, 0, ...baseTracesToInsert);
7463
- chromatogramData.qualNums && chromatogramData.qualNums.splice(caretPosition, 0, ...qualNumsToInsert);
7569
+ if (chromatogramData.baseTraces) {
7570
+ chromatogramData.baseTraces.splice(
7571
+ caretPosition,
7572
+ 0,
7573
+ ...baseTracesToInsert
7574
+ );
7575
+ }
7576
+ if (chromatogramData.qualNums) {
7577
+ chromatogramData.qualNums.splice(
7578
+ caretPosition,
7579
+ 0,
7580
+ ...qualNumsToInsert
7581
+ );
7582
+ }
7464
7583
  return chromatogramData;
7465
7584
  }
7466
7585
  __name(insertIntoChromatogram, "insertIntoChromatogram");
@@ -7473,17 +7592,23 @@ function trimChromatogram({
7473
7592
  "baseCalls",
7474
7593
  ...justBaseCalls ? [] : ["qualNums", "baseTraces", "basePos"]
7475
7594
  ].forEach((type) => {
7476
- chromatogramData[type] && chromatogramData[type].splice(start, end - start + 1);
7595
+ if (chromatogramData[type]) {
7596
+ chromatogramData[type].splice(start, end - start + 1);
7597
+ }
7477
7598
  });
7478
7599
  return chromatogramData;
7479
7600
  }
7480
7601
  __name(trimChromatogram, "trimChromatogram");
7481
7602
  function deleteSequenceDataAtRange(sequenceData, range) {
7482
- return insertSequenceDataAtPositionOrRange({}, sequenceData, range);
7603
+ return insertSequenceDataAtPositionOrRange(
7604
+ { sequence: "" },
7605
+ sequenceData,
7606
+ range
7607
+ );
7483
7608
  }
7484
7609
  __name(deleteSequenceDataAtRange, "deleteSequenceDataAtRange");
7485
7610
  function doesEnzymeChopOutsideOfRecognitionSite(enzyme) {
7486
- if (enzyme.topSnipOffset > enzyme.site.length || enzyme.bottomSnipOffset > enzyme.site.length) {
7611
+ if (enzyme.topSnipOffset && enzyme.bottomSnipOffset && (enzyme.topSnipOffset > enzyme.site.length || enzyme.bottomSnipOffset > enzyme.site.length)) {
7487
7612
  return true;
7488
7613
  } else {
7489
7614
  return false;
@@ -15115,10 +15240,10 @@ defaultEnzymes.forEach((name) => {
15115
15240
  defaultEnzymesByName[name] = aliasedEnzymesByName[name];
15116
15241
  });
15117
15242
  function generateAnnotations(numberOfAnnotationsToGenerate, start, end, maxLength) {
15118
- const result = {};
15243
+ const result = [];
15119
15244
  for (let i = 0; i < numberOfAnnotationsToGenerate; i++) {
15120
15245
  const annotation = generateAnnotation(start, end, maxLength);
15121
- result[annotation.id] = annotation;
15246
+ result.push(annotation);
15122
15247
  }
15123
15248
  return result;
15124
15249
  }
@@ -15146,16 +15271,16 @@ function generateSequenceData({
15146
15271
  numPrimers,
15147
15272
  numTranslations
15148
15273
  } = {}) {
15149
- const proteinSequence = isProtein && generateSequence(sequenceLength, true);
15150
- const sequence = !isProtein && generateSequence(sequenceLength);
15274
+ const proteinSequence = isProtein ? generateSequence(sequenceLength, true) : "";
15275
+ const sequence = !isProtein ? generateSequence(sequenceLength) : "";
15151
15276
  return {
15152
15277
  circular: isProtein ? false : Math.random() > 0.5,
15153
- name: "p-" + Math.floor(Math.random * 100),
15278
+ name: "p-" + Math.floor(Math.random() * 100),
15154
15279
  description: "",
15155
- isProtein,
15280
+ isProtein: !!isProtein,
15156
15281
  sequence,
15157
15282
  proteinSequence,
15158
- translations: isProtein ? void 0 : generateAnnotations(
15283
+ translations: isProtein ? [] : generateAnnotations(
15159
15284
  numTranslations || 5,
15160
15285
  0,
15161
15286
  sequenceLength - 1,
@@ -15167,7 +15292,7 @@ function generateSequenceData({
15167
15292
  sequenceLength - 1,
15168
15293
  sequenceLength / 3
15169
15294
  ),
15170
- primers: isProtein ? void 0 : generateAnnotations(numPrimers || 10, 0, sequenceLength - 1, 50),
15295
+ primers: isProtein ? [] : generateAnnotations(numPrimers || 10, 0, sequenceLength - 1, 50),
15171
15296
  parts: generateAnnotations(
15172
15297
  numParts || 10,
15173
15298
  0,
@@ -15179,15 +15304,14 @@ function generateSequenceData({
15179
15304
  __name(generateSequenceData, "generateSequenceData");
15180
15305
  function generateSequence(m = 9, isProtein) {
15181
15306
  let s = "";
15182
- const r = isProtein ? "" : "gatc";
15307
+ const r = isProtein ? "ACDEFGHIKLMNPQRSTVWY" : "gatc";
15183
15308
  for (let i = 0; i < m; i++) {
15184
15309
  s += r.charAt(Math.floor(Math.random() * r.length));
15185
15310
  }
15186
15311
  return s;
15187
15312
  }
15188
15313
  __name(generateSequence, "generateSequence");
15189
- function findNearestRangeOfSequenceOverlapToPosition(sequenceToSearch, overlapSequence, positionStart, isLinear) {
15190
- if (!positionStart) positionStart = 0;
15314
+ function findNearestRangeOfSequenceOverlapToPosition(sequenceToSearch, overlapSequence, positionStart = 0, isLinear) {
15191
15315
  if (sequenceToSearch.length < overlapSequence.length) {
15192
15316
  return null;
15193
15317
  }
@@ -15205,6 +15329,9 @@ function findNearestRangeOfSequenceOverlapToPosition(sequenceToSearch, overlapSe
15205
15329
  index = result.index;
15206
15330
  distance = newDistance;
15207
15331
  }
15332
+ if (index === void 0) {
15333
+ return null;
15334
+ }
15208
15335
  return normalizeRange(
15209
15336
  {
15210
15337
  start: index,
@@ -15249,9 +15376,11 @@ function getOrfsFromSequence(options) {
15249
15376
  internalStartCodonIndices: [],
15250
15377
  frame: start % 3,
15251
15378
  forward,
15252
- annotationTypePlural: "orfs",
15379
+ // annotationTypePlural: "orfs",
15253
15380
  isOrf: true,
15254
- id: shortid()
15381
+ id: shortid(),
15382
+ type: "orf",
15383
+ name: "ORF"
15255
15384
  });
15256
15385
  }
15257
15386
  }
@@ -15292,7 +15421,10 @@ function getOrfsFromSequence(options) {
15292
15421
  return nonDuplicatedOrfRanges;
15293
15422
  }
15294
15423
  __name(getOrfsFromSequence, "getOrfsFromSequence");
15295
- function findOrfsInPlasmid(sequence, circular, minimumOrfSize, useAdditionalOrfStartCodons) {
15424
+ function findOrfsInPlasmid(sequence, circular, minimumOrfSize, useAdditionalOrfStartCodons, isProteinOrOligo) {
15425
+ if (isProteinOrOligo) {
15426
+ return [];
15427
+ }
15296
15428
  const forwardOrfs = getOrfsFromSequence({
15297
15429
  sequence,
15298
15430
  minimumOrfSize,
@@ -15352,7 +15484,10 @@ function findSequenceMatchesTopStrand(sequence, searchString, options = {}) {
15352
15484
  true
15353
15485
  );
15354
15486
  } else {
15355
- searchStringToUse = convertAmbiguousStringToRegex(searchStringToUse);
15487
+ searchStringToUse = convertAmbiguousStringToRegex(
15488
+ searchStringToUse,
15489
+ false
15490
+ );
15356
15491
  }
15357
15492
  }
15358
15493
  if (!searchStringToUse) return [];
@@ -15472,7 +15607,9 @@ function getCodonRangeForAASliver(aminoAcidPositionInSequence, aminoAcidSliver,
15472
15607
  }
15473
15608
  __name(getCodonRangeForAASliver, "getCodonRangeForAASliver");
15474
15609
  function getComplementAminoAcidStringFromSequenceString(sequenceString) {
15475
- const aaString = getAminoAcidStringFromSequenceString(sequenceString, true);
15610
+ const aaString = getAminoAcidStringFromSequenceString(sequenceString, {
15611
+ doNotExcludeAsterisk: true
15612
+ });
15476
15613
  return aaString.split("").reverse().join("");
15477
15614
  }
15478
15615
  __name(getComplementAminoAcidStringFromSequenceString, "getComplementAminoAcidStringFromSequenceString");
@@ -15510,26 +15647,30 @@ function getSequenceDataBetweenRange(seqData, range, options = {}) {
15510
15647
  sequence: getSequenceWithinRange(range, seqDataToUse.sequence),
15511
15648
  proteinSequence: getSequenceWithinRange(
15512
15649
  convertDnaCaretPositionOrRangeToAA(range),
15513
- seqDataToUse.proteinSequence
15650
+ seqDataToUse.proteinSequence || ""
15514
15651
  )
15515
15652
  },
15516
- annotationTypes.reduce((acc, type) => {
15517
- if (exclude[type]) {
15518
- acc[type] = [];
15653
+ annotationTypes.reduce(
15654
+ (acc, type) => {
15655
+ if (exclude[type]) {
15656
+ acc[type] = [];
15657
+ return acc;
15658
+ }
15659
+ acc[type] = getAnnotationsBetweenRange(
15660
+ seqDataToUse[type],
15661
+ range,
15662
+ seqDataToUse.sequence.length,
15663
+ excludePartial[type]
15664
+ );
15519
15665
  return acc;
15520
- }
15521
- acc[type] = getAnnotationsBetweenRange(
15522
- seqDataToUse[type],
15523
- range,
15524
- seqDataToUse.sequence.length,
15525
- excludePartial[type]
15526
- );
15527
- return acc;
15528
- }, {})
15666
+ },
15667
+ {}
15668
+ )
15529
15669
  );
15530
15670
  if (range.overlapsSelf) {
15531
15671
  const extendedSeqData = insertSequenceDataAtPositionOrRange(
15532
15672
  { sequence: seqDataToReturn.sequence },
15673
+ // Wrapping in object as per assumed signature
15533
15674
  seqDataToUse,
15534
15675
  range.start
15535
15676
  );
@@ -15594,7 +15735,8 @@ function getAnnotationsBetweenRange(annotationsToBeAdjusted, range, maxLength, s
15594
15735
  __name(getAnnotationsBetweenRange, "getAnnotationsBetweenRange");
15595
15736
  function getComplementSequenceAndAnnotations(pSeqObj, options = {}) {
15596
15737
  const seqObj = tidyUpSequenceData(
15597
- getSequenceDataBetweenRange(pSeqObj, options.range),
15738
+ getSequenceDataBetweenRange(pSeqObj, options.range || null),
15739
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15598
15740
  options
15599
15741
  );
15600
15742
  const newSeqObj = Object.assign({}, seqObj, {
@@ -15609,7 +15751,7 @@ function getCutsiteType(restrictionEnzyme) {
15609
15751
  const { topSnipOffset, bottomSnipOffset } = restrictionEnzyme;
15610
15752
  if (topSnipOffset === bottomSnipOffset) {
15611
15753
  return "blunt";
15612
- } else if (topSnipOffset < bottomSnipOffset) {
15754
+ } else if (topSnipOffset !== void 0 && bottomSnipOffset !== void 0 && topSnipOffset < bottomSnipOffset) {
15613
15755
  return "5' overhang";
15614
15756
  } else {
15615
15757
  return "3' overhang";
@@ -15643,7 +15785,7 @@ function getLeftAndRightOfSequenceInRangeGivenPosition(range, position, sequence
15643
15785
  leftHandSide: "",
15644
15786
  rightHandSide: ""
15645
15787
  };
15646
- if (isPositionWithinRange(position, range)) {
15788
+ if (isPositionWithinRange(position, range, sequence.length)) {
15647
15789
  result.leftHandSide = getSequenceWithinRange(
15648
15790
  {
15649
15791
  start: range.start,
@@ -15683,13 +15825,13 @@ function getOverlapBetweenTwoSequences(sequenceToFind, sequenceToSearchIn) {
15683
15825
  }
15684
15826
  }
15685
15827
  __name(getOverlapBetweenTwoSequences, "getOverlapBetweenTwoSequences");
15686
- function getPossiblePartsFromSequenceAndEnzyme(seqData, restrictionEnzymes) {
15687
- restrictionEnzymes = restrictionEnzymes.length ? restrictionEnzymes : [restrictionEnzymes];
15828
+ function getPossiblePartsFromSequenceAndEnzymes(seqData, restrictionEnzymes) {
15829
+ const enzymes = Array.isArray(restrictionEnzymes) ? restrictionEnzymes : [restrictionEnzymes];
15688
15830
  const bps = seqData.sequence;
15689
15831
  const seqLen = bps.length;
15690
- const circular = seqData.circular;
15832
+ const circular = seqData.circular || false;
15691
15833
  let cutsites = [];
15692
- restrictionEnzymes.forEach((enzyme) => {
15834
+ enzymes.forEach((enzyme) => {
15693
15835
  const newCutsites = cutSequenceByRestrictionEnzyme(bps, circular, enzyme);
15694
15836
  cutsites = cutsites.concat(newCutsites);
15695
15837
  });
@@ -15730,13 +15872,13 @@ function getPossiblePartsFromSequenceAndEnzyme(seqData, restrictionEnzymes) {
15730
15872
  return parts;
15731
15873
  }
15732
15874
  }
15733
- __name(getPossiblePartsFromSequenceAndEnzyme, "getPossiblePartsFromSequenceAndEnzyme");
15875
+ __name(getPossiblePartsFromSequenceAndEnzymes, "getPossiblePartsFromSequenceAndEnzymes");
15734
15876
  function getPartBetweenEnzymesWithInclusiveOverhangs(cut1, cut2, seqLen) {
15735
15877
  const firstCutOffset = getEnzymeRelativeOffset(cut1.restrictionEnzyme);
15736
15878
  const secondCutOffset = getEnzymeRelativeOffset(cut2.restrictionEnzyme);
15737
- const start = cut1.topSnipBeforeBottom ? cut1.topSnipPosition : cut1.bottomSnipPosition;
15879
+ const start = (cut1.topSnipBeforeBottom ? cut1.topSnipPosition : cut1.bottomSnipPosition) || 0;
15738
15880
  const end = normalizePositionByRangeLength(
15739
- (cut2.topSnipBeforeBottom ? cut2.bottomSnipPosition : cut2.topSnipPosition) - 1,
15881
+ (cut2.topSnipBeforeBottom ? cut2.bottomSnipPosition || 0 : cut2.topSnipPosition || 0) - 1,
15740
15882
  seqLen
15741
15883
  );
15742
15884
  return {
@@ -15747,20 +15889,20 @@ function getPartBetweenEnzymesWithInclusiveOverhangs(cut1, cut2, seqLen) {
15747
15889
  firstCut: cut1,
15748
15890
  //the offset is always counting with 0 being at the top snip position
15749
15891
  firstCutOffset,
15750
- firstCutOverhang: cut1.overhangBps,
15751
- firstCutOverhangTop: firstCutOffset > 0 ? cut1.overhangBps : "",
15752
- firstCutOverhangBottom: firstCutOffset < 0 ? getComplementSequenceString(cut1.overhangBps) : "",
15892
+ firstCutOverhang: cut1.overhangBps || "",
15893
+ firstCutOverhangTop: firstCutOffset > 0 ? cut1.overhangBps || "" : "",
15894
+ firstCutOverhangBottom: firstCutOffset < 0 ? getComplementSequenceString(cut1.overhangBps || "") : "",
15753
15895
  secondCut: cut2,
15754
15896
  //the offset is always counting with 0 being at the top snip position
15755
15897
  secondCutOffset,
15756
- secondCutOverhang: cut2.overhangBps,
15757
- secondCutOverhangTop: secondCutOffset < 0 ? cut2.overhangBps : "",
15758
- secondCutOverhangBottom: secondCutOffset > 0 ? getComplementSequenceString(cut2.overhangBps) : ""
15898
+ secondCutOverhang: cut2.overhangBps || "",
15899
+ secondCutOverhangTop: secondCutOffset < 0 ? cut2.overhangBps || "" : "",
15900
+ secondCutOverhangBottom: secondCutOffset > 0 ? getComplementSequenceString(cut2.overhangBps || "") : ""
15759
15901
  };
15760
15902
  }
15761
15903
  __name(getPartBetweenEnzymesWithInclusiveOverhangs, "getPartBetweenEnzymesWithInclusiveOverhangs");
15762
15904
  function getEnzymeRelativeOffset(enzyme) {
15763
- return enzyme.bottomSnipOffset - enzyme.topSnipOffset;
15905
+ return (enzyme.bottomSnipOffset || 0) - (enzyme.topSnipOffset || 0);
15764
15906
  }
15765
15907
  __name(getEnzymeRelativeOffset, "getEnzymeRelativeOffset");
15766
15908
  function pairwise(list) {
@@ -15776,6 +15918,8 @@ __name(pairwise, "pairwise");
15776
15918
  function getReverseAminoAcidStringFromSequenceString(sequenceString) {
15777
15919
  const aminoAcidsPerBase = getAminoAcidDataForEachBaseOfDna(
15778
15920
  sequenceString,
15921
+ false,
15922
+ null,
15779
15923
  false
15780
15924
  );
15781
15925
  const aaArray = [];
@@ -15814,7 +15958,8 @@ function getReverseComplementAnnotation(annotation, sequenceLength) {
15814
15958
  __name(getReverseComplementAnnotation, "getReverseComplementAnnotation");
15815
15959
  function getReverseComplementSequenceAndAnnoations(pSeqObj, options = {}) {
15816
15960
  const seqObj = tidyUpSequenceData(
15817
- getSequenceDataBetweenRange(pSeqObj, options.range),
15961
+ getSequenceDataBetweenRange(pSeqObj, options.range || null),
15962
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15818
15963
  __spreadValues({ doNotRemoveInvalidChars: true }, options)
15819
15964
  );
15820
15965
  const newSeqObj = Object.assign(
@@ -15823,17 +15968,20 @@ function getReverseComplementSequenceAndAnnoations(pSeqObj, options = {}) {
15823
15968
  {
15824
15969
  sequence: getReverseComplementSequenceString(seqObj.sequence)
15825
15970
  },
15826
- annotationTypes.reduce((acc, type) => {
15827
- if (seqObj[type]) {
15828
- acc[type] = map(seqObj[type], (annotation) => {
15829
- return getReverseComplementAnnotation(
15830
- annotation,
15831
- seqObj.sequence.length
15832
- );
15833
- });
15834
- }
15835
- return acc;
15836
- }, {})
15971
+ annotationTypes.reduce(
15972
+ (acc, type) => {
15973
+ if (seqObj[type]) {
15974
+ acc[type] = map(seqObj[type], (annotation) => {
15975
+ return getReverseComplementAnnotation(
15976
+ annotation,
15977
+ seqObj.sequence.length
15978
+ );
15979
+ });
15980
+ }
15981
+ return acc;
15982
+ },
15983
+ {}
15984
+ )
15837
15985
  );
15838
15986
  return tidyUpSequenceData(newSeqObj, __spreadValues({
15839
15987
  doNotRemoveInvalidChars: true
@@ -15855,10 +16003,13 @@ __name(getReverseSequenceString, "getReverseSequenceString");
15855
16003
  function guessIfSequenceIsDnaAndNotProtein(seq, options = {}) {
15856
16004
  const { threshold = 0.9, loose } = options;
15857
16005
  const dnaLetters = options.dnaLetters || loose ? [...ambiguous_dna_letters.split(""), "U"] : ["G", "A", "T", "C", "U"];
15858
- const dnaLetterMap = dnaLetters.reduce((acc, letter) => {
15859
- acc[letter.toUpperCase()] = true;
15860
- return acc;
15861
- }, {});
16006
+ const dnaLetterMap = dnaLetters.reduce(
16007
+ (acc, letter) => {
16008
+ acc[letter.toUpperCase()] = true;
16009
+ return acc;
16010
+ },
16011
+ {}
16012
+ );
15862
16013
  let count = 0;
15863
16014
  if (!seq || !seq.length) return true;
15864
16015
  for (let index = 0; index < seq.length; index++) {
@@ -15878,15 +16029,17 @@ function mapAnnotationsToRows(annotations, sequenceLength, bpsPerRow, { splitFor
15878
16029
  const yOffsetLevelMap = {};
15879
16030
  const wrappedAnnotations = {};
15880
16031
  forEach(annotations, (annotation) => {
16032
+ var _a;
15881
16033
  const containsLocations = !!(annotation.locations && annotation.locations.length);
15882
16034
  if (annotation.overlapsSelf) {
15883
16035
  if (!wrappedAnnotations[annotation.id]) {
15884
16036
  mapAnnotationToRows({
15885
- annotation: {
16037
+ annotation: __spreadProps(__spreadValues({}, annotation), {
15886
16038
  start: 0,
15887
16039
  end: sequenceLength - 1,
15888
- id: `__tempAnnRemoveMe__${annotation.id}`
15889
- },
16040
+ id: `__tempAnnRemoveMe__${annotation.id}`,
16041
+ overlapsSelf: false
16042
+ }),
15890
16043
  sequenceLength,
15891
16044
  bpsPerRow,
15892
16045
  annotationsToRowsMap,
@@ -15907,7 +16060,7 @@ function mapAnnotationsToRows(annotations, sequenceLength, bpsPerRow, { splitFor
15907
16060
  splitForwardReverse
15908
16061
  });
15909
16062
  if (containsLocations) {
15910
- annotation.locations.forEach((location) => {
16063
+ (_a = annotation.locations) == null ? void 0 : _a.forEach((location) => {
15911
16064
  mapAnnotationToRows({
15912
16065
  annotation,
15913
16066
  sequenceLength,
@@ -15923,7 +16076,7 @@ function mapAnnotationsToRows(annotations, sequenceLength, bpsPerRow, { splitFor
15923
16076
  forEach(annotationsToRowsMap, (annotationsForRow, i) => {
15924
16077
  annotationsToRowsMap[i] = filter(
15925
16078
  annotationsForRow,
15926
- (ann) => !startsWith(ann.id, "__tempAnnRemoveMe__")
16079
+ (ann) => !startsWith(String(ann.id), "__tempAnnRemoveMe__")
15927
16080
  );
15928
16081
  });
15929
16082
  return annotationsToRowsMap;
@@ -15965,6 +16118,13 @@ function mapAnnotationToRows({
15965
16118
  yOffset = ann.yOffset;
15966
16119
  }
15967
16120
  });
16121
+ if (yOffset === void 0) {
16122
+ annotationsForRow.forEach((ann) => {
16123
+ if (ann.id === annotation.id) {
16124
+ yOffset = ann.yOffset;
16125
+ }
16126
+ });
16127
+ }
15968
16128
  } else {
15969
16129
  if (location) {
15970
16130
  annotationsForRow.forEach((ann) => {
@@ -15973,32 +16133,74 @@ function mapAnnotationToRows({
15973
16133
  }
15974
16134
  });
15975
16135
  } else {
15976
- if (index > 0 && //second half of an annotation range
15977
- annotationsForRow.length && //there are already annotations within the row
15978
- annotationsForRow[annotationsForRow.length - 1].annotation === annotation) {
16136
+ if (index > 0 && annotationsForRow.length && annotationsForRow[annotationsForRow.length - 1].annotation === annotation) {
15979
16137
  yOffset = annotationsForRow[annotationsForRow.length - 1].yOffset;
15980
16138
  } else {
15981
- yOffset = getYOffsetForPotentiallyCircularRange(
15982
- annotation,
15983
- yOffsetsForRow
15984
- );
16139
+ const siblingRangesOnThisRow = ranges.slice(index + 1).filter((r) => {
16140
+ const rStartRow = Math.floor(r.start / bpsPerRow);
16141
+ const rEndRow = Math.floor(r.end / bpsPerRow);
16142
+ return rowNumber >= rStartRow && rowNumber <= rEndRow;
16143
+ });
16144
+ if (siblingRangesOnThisRow.length > 0) {
16145
+ let foundYOffset = -1;
16146
+ yOffsetsForRow.some((rangesAlreadyAddedToYOffset, levelIndex) => {
16147
+ const rangeBlocked = rangesAlreadyAddedToYOffset.some(
16148
+ (comparisonRange) => {
16149
+ return checkIfPotentiallyCircularRangesOverlap(
16150
+ range,
16151
+ comparisonRange
16152
+ );
16153
+ }
16154
+ );
16155
+ if (rangeBlocked) return false;
16156
+ const siblingBlocked = siblingRangesOnThisRow.some(
16157
+ (siblingRange) => {
16158
+ return rangesAlreadyAddedToYOffset.some((comparisonRange) => {
16159
+ return checkIfPotentiallyCircularRangesOverlap(
16160
+ siblingRange,
16161
+ comparisonRange
16162
+ );
16163
+ });
16164
+ }
16165
+ );
16166
+ if (!siblingBlocked) {
16167
+ foundYOffset = levelIndex;
16168
+ return true;
16169
+ }
16170
+ return false;
16171
+ });
16172
+ if (foundYOffset > -1) {
16173
+ yOffset = foundYOffset;
16174
+ yOffsetsForRow[foundYOffset].push(range);
16175
+ } else {
16176
+ yOffset = yOffsetsForRow.length;
16177
+ yOffsetsForRow.push([range]);
16178
+ }
16179
+ } else {
16180
+ yOffset = getYOffsetForPotentiallyCircularRange(
16181
+ range,
16182
+ yOffsetsForRow,
16183
+ false
16184
+ );
16185
+ }
16186
+ }
16187
+ if (yOffset !== void 0) {
16188
+ if (!yOffsetsForRow[yOffset]) yOffsetsForRow[yOffset] = [];
16189
+ yOffsetsForRow[yOffset].push({
16190
+ start,
16191
+ end
16192
+ });
15985
16193
  }
15986
- if (!yOffsetsForRow[yOffset]) yOffsetsForRow[yOffset] = [];
15987
- yOffsetsForRow[yOffset].push({
15988
- start,
15989
- end
15990
- });
15991
16194
  }
15992
16195
  }
15993
- annotationsForRow.push(__spreadProps(__spreadValues(__spreadValues({
16196
+ annotationsForRow.push(__spreadProps(__spreadValues(__spreadValues(__spreadProps(__spreadValues({}, annotation), {
15994
16197
  id: annotation.id,
15995
16198
  annotation,
15996
16199
  start,
15997
16200
  end
15998
- }, containsLocations && { containsLocations }), location && { isJoinedLocation: !!location }), {
16201
+ }), containsLocations && { containsLocations }), location && { isJoinedLocation: !!location }), {
15999
16202
  yOffset,
16000
16203
  enclosingRangeType: range.type
16001
- //either "beginning", "end" or "beginningAndEnd"
16002
16204
  }));
16003
16205
  }
16004
16206
  });
@@ -16008,10 +16210,14 @@ function prepareCircularViewData(sequenceData) {
16008
16210
  const clonedSeqData = cloneDeep(sequenceData);
16009
16211
  annotationTypes.forEach((annotationType) => {
16010
16212
  if (annotationType !== "cutsites") {
16011
- const maxYOffset = getYOffsetsForPotentiallyCircularRanges(
16012
- clonedSeqData[annotationType]
16013
- ).maxYOffset;
16014
- clonedSeqData[annotationType].maxYOffset = maxYOffset;
16213
+ const annotations = clonedSeqData[annotationType];
16214
+ if (annotations) {
16215
+ const maxYOffset = getYOffsetsForPotentiallyCircularRanges(
16216
+ annotations,
16217
+ true
16218
+ ).maxYOffset;
16219
+ clonedSeqData[annotationType].maxYOffset = maxYOffset;
16220
+ }
16015
16221
  }
16016
16222
  });
16017
16223
  return clonedSeqData;
@@ -16024,14 +16230,19 @@ function prepareRowData(sequenceData, bpsPerRow) {
16024
16230
  const rowMap = {};
16025
16231
  annotationTypes.forEach((type) => {
16026
16232
  rowMap[type] = mapAnnotationsToRows(
16027
- sequenceData[type],
16233
+ sequenceData[type] || [],
16028
16234
  sequenceLength,
16029
16235
  bpsPerRow,
16030
16236
  { splitForwardReverse: type === "primers" }
16031
16237
  );
16032
16238
  });
16033
16239
  for (let rowNumber = 0; rowNumber < totalRows; rowNumber++) {
16034
- const row = {};
16240
+ const row = {
16241
+ rowNumber,
16242
+ start: 0,
16243
+ end: 0,
16244
+ sequence: ""
16245
+ };
16035
16246
  row.rowNumber = rowNumber;
16036
16247
  row.start = rowNumber * bpsPerRow;
16037
16248
  row.end = (rowNumber + 1) * bpsPerRow - 1 < sequenceLength ? (rowNumber + 1) * bpsPerRow - 1 : sequenceLength - 1;
@@ -16092,17 +16303,16 @@ function addGapsToSeqReads(refSeq, seqReads) {
16092
16303
  }
16093
16304
  }
16094
16305
  const refSeqWithGaps = insertGapsIntoRefSeq(refSeq.sequence, seqReads);
16095
- const seqReadsWithGaps = [
16096
- { name: refSeq.name, sequence: refSeqWithGaps.toUpperCase() }
16097
- ];
16306
+ const seqReadsWithGaps = [{ name: refSeq.name, sequence: refSeqWithGaps.toUpperCase() }];
16098
16307
  seqReads.forEach((seqRead) => {
16099
16308
  const allInsertionsInSeqReads = [];
16100
16309
  seqReads.forEach((seqRead2) => {
16101
16310
  const splitSeqRead = seqRead2.cigar.match(/([0-9]*[SMDI])/g);
16311
+ if (!splitSeqRead) return;
16102
16312
  let adjustedSeqReadPos2 = cloneDeep(seqRead2.pos);
16103
16313
  if (splitSeqRead[0].slice(-1) === "S") {
16104
16314
  const numOfBeginningSoftClipped = splitSeqRead[0].slice(0, -1);
16105
- adjustedSeqReadPos2 = seqRead2.pos - numOfBeginningSoftClipped;
16315
+ adjustedSeqReadPos2 = seqRead2.pos - Number(numOfBeginningSoftClipped);
16106
16316
  }
16107
16317
  for (let componentI = 0; componentI < splitSeqRead.length; componentI++) {
16108
16318
  if (splitSeqRead[componentI].slice(-1) === "I") {
@@ -16128,10 +16338,11 @@ function addGapsToSeqReads(refSeq, seqReads) {
16128
16338
  }
16129
16339
  });
16130
16340
  const splitSeqReadChunk = seqRead.cigar.match(/([0-9]*[SMDI])/g);
16341
+ if (!splitSeqReadChunk) return;
16131
16342
  let adjustedSeqReadPos = cloneDeep(seqRead.pos);
16132
16343
  if (splitSeqReadChunk[0].slice(-1) === "S") {
16133
16344
  const numOfBeginningSoftClipped = splitSeqReadChunk[0].slice(0, -1);
16134
- adjustedSeqReadPos = seqRead.pos - numOfBeginningSoftClipped;
16345
+ adjustedSeqReadPos = seqRead.pos - Number(numOfBeginningSoftClipped);
16135
16346
  }
16136
16347
  let eachSeqReadWithGaps = seqRead.seq.split("");
16137
16348
  if (adjustedSeqReadPos > 0) {
@@ -16319,10 +16530,11 @@ function addGapsToSeqReads(refSeq, seqReads) {
16319
16530
  const seqReadLengthsBeforeRefSeqStart = [];
16320
16531
  seqReads.forEach((seq) => {
16321
16532
  const splitSeqReadChunk = seq.cigar.match(/([0-9]*[SMDI])/g);
16533
+ if (!splitSeqReadChunk) return;
16322
16534
  let adjustedSeqReadPos = cloneDeep(seq.pos);
16323
16535
  if (splitSeqReadChunk[0].slice(-1) === "S") {
16324
16536
  const numOfBeginningSoftClipped = splitSeqReadChunk[0].slice(0, -1);
16325
- adjustedSeqReadPos = seq.pos - numOfBeginningSoftClipped;
16537
+ adjustedSeqReadPos = seq.pos - Number(numOfBeginningSoftClipped);
16326
16538
  if (adjustedSeqReadPos < 0) {
16327
16539
  seqReadLengthsBeforeRefSeqStart.push(Math.abs(adjustedSeqReadPos));
16328
16540
  }
@@ -16332,13 +16544,14 @@ function addGapsToSeqReads(refSeq, seqReads) {
16332
16544
  for (let i = 1; i < seqReadsWithGaps.length; i++) {
16333
16545
  const eachSeqReadWithGaps = seqReadsWithGaps[i].sequence.split("");
16334
16546
  const splitSeqReadChunk = seqReads[i - 1].cigar.match(/([0-9]*[SMDI])/g);
16547
+ if (!splitSeqReadChunk) continue;
16335
16548
  let adjustedSeqReadPos = cloneDeep(seqReads[i - 1].pos);
16336
16549
  if (seqReadLengthsBeforeRefSeqStart.length > 0) {
16337
16550
  longestSeqReadLength = Math.max(...seqReadLengthsBeforeRefSeqStart);
16338
16551
  }
16339
16552
  if (splitSeqReadChunk[0].slice(-1) === "S") {
16340
16553
  const numOfBeginningSoftClipped = splitSeqReadChunk[0].slice(0, -1);
16341
- adjustedSeqReadPos = seqReads[i - 1].pos - numOfBeginningSoftClipped;
16554
+ adjustedSeqReadPos = seqReads[i - 1].pos - Number(numOfBeginningSoftClipped);
16342
16555
  if (adjustedSeqReadPos > 0) {
16343
16556
  if (longestSeqReadLength > 0) {
16344
16557
  eachSeqReadWithGaps.unshift("-".repeat(longestSeqReadLength + 1));
@@ -16452,11 +16665,11 @@ function calculateNebTm(sequence, { monovalentCationConc = 0.05, primerConc = 5e
16452
16665
  for (let i = 0; i < seq.length; i++) {
16453
16666
  if (i === 0 || i === seq.length - 1) {
16454
16667
  if (seq[i] === "G" || seq[i] === "C") {
16455
- hi += sequenceToEnthalpyMap.initiationWithTerminalGC;
16456
- si += sequenceToEntropyMap.initiationWithTerminalGC;
16668
+ hi += sequenceToEnthalpyMap["initiationWithTerminalGC"];
16669
+ si += sequenceToEntropyMap["initiationWithTerminalGC"];
16457
16670
  } else if (seq[i] === "A" || seq[i] === "T") {
16458
- hi += sequenceToEnthalpyMap.initiationWithTerminalAT;
16459
- si += sequenceToEntropyMap.initiationWithTerminalAT;
16671
+ hi += sequenceToEnthalpyMap["initiationWithTerminalAT"];
16672
+ si += sequenceToEntropyMap["initiationWithTerminalAT"];
16460
16673
  }
16461
16674
  }
16462
16675
  if (i < seq.length - 1) {
@@ -16499,9 +16712,13 @@ function calculateNebTa(sequences, primerConc, { monovalentCationConc, polymeras
16499
16712
  `${sequences.length} sequences received when 2 primers were expected`
16500
16713
  );
16501
16714
  }
16502
- const meltingTemperatures = sequences.map(
16503
- (seq) => calculateNebTm(seq, primerConc, { monovalentCationConc })
16504
- );
16715
+ const meltingTemperatures = sequences.map((seq) => {
16716
+ const tm = calculateNebTm(seq, { monovalentCationConc, primerConc });
16717
+ if (typeof tm !== "number") {
16718
+ throw new Error(`Invalid Tm calculated for ${seq}: ${tm}`);
16719
+ }
16720
+ return tm;
16721
+ });
16505
16722
  meltingTemperatures.sort((a, b) => a - b);
16506
16723
  const lowerMeltingTemp = meltingTemperatures[0];
16507
16724
  let annealingTemp;
@@ -16578,17 +16795,17 @@ function isValidSequence(sequence) {
16578
16795
  __name(isValidSequence, "isValidSequence");
16579
16796
  function calculateSantaLuciaTm(sequence) {
16580
16797
  try {
16581
- sequence = sequence == null ? void 0 : sequence.toUpperCase().trim();
16582
- if (!isValidSequence(sequence)) {
16798
+ const seq = sequence == null ? void 0 : sequence.toUpperCase().trim();
16799
+ if (!isValidSequence(seq)) {
16583
16800
  throw new Error("Invalid sequence: contains non-DNA characters");
16584
16801
  }
16585
- if (sequence.length < 2) {
16802
+ if (seq.length < 2) {
16586
16803
  throw new Error("Sequence too short: minimum length is 2 bases");
16587
16804
  }
16588
16805
  let deltaH = 0;
16589
16806
  let deltaS = 0;
16590
- for (let i = 0; i < sequence.length - 1; i++) {
16591
- const dinucleotide = sequence.substring(i, i + 2);
16807
+ for (let i = 0; i < seq.length - 1; i++) {
16808
+ const dinucleotide = seq.substring(i, i + 2);
16592
16809
  if (dinucleotide.includes("N")) {
16593
16810
  continue;
16594
16811
  }
@@ -16598,23 +16815,23 @@ function calculateSantaLuciaTm(sequence) {
16598
16815
  deltaS += params.dS;
16599
16816
  }
16600
16817
  }
16601
- const firstBase = sequence[0];
16602
- const lastBase = sequence[sequence.length - 1];
16818
+ const firstBase = seq[0];
16819
+ const lastBase = seq[seq.length - 1];
16603
16820
  if (firstBase === "G" || firstBase === "C") {
16604
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16605
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16821
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16822
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16606
16823
  } else {
16607
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16608
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16824
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16825
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16609
16826
  }
16610
16827
  if (lastBase === "G" || lastBase === "C") {
16611
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16612
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16828
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16829
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16613
16830
  } else {
16614
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16615
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16831
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16832
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16616
16833
  }
16617
- const nnPairs = sequence.length - 1;
16834
+ const nnPairs = seq.length - 1;
16618
16835
  deltaS = applySaltCorrection(deltaS, nnPairs);
16619
16836
  const C = PRIMER3_PARAMS.dnaConc * 1e-9;
16620
16837
  const Tm = deltaH * 1e3 / (deltaS + PRIMER3_PARAMS.R * Math.log(C / 4));
@@ -16626,16 +16843,16 @@ function calculateSantaLuciaTm(sequence) {
16626
16843
  __name(calculateSantaLuciaTm, "calculateSantaLuciaTm");
16627
16844
  function calculateEndStability(sequence) {
16628
16845
  try {
16629
- sequence = sequence == null ? void 0 : sequence.toUpperCase().trim();
16630
- if (!isValidSequence(sequence)) {
16846
+ const seq = sequence == null ? void 0 : sequence.toUpperCase().trim();
16847
+ if (!isValidSequence(seq)) {
16631
16848
  throw new Error("Invalid sequence: contains non-DNA characters");
16632
16849
  }
16633
- if (sequence.length < 5) {
16850
+ if (seq.length < 5) {
16634
16851
  throw new Error(
16635
16852
  "Sequence too short: minimum length is 5 bases for end stability calculation"
16636
16853
  );
16637
16854
  }
16638
- const last5Bases = sequence.substring(sequence.length - 5);
16855
+ const last5Bases = seq.substring(seq.length - 5);
16639
16856
  let deltaH = 0;
16640
16857
  let deltaS = 0;
16641
16858
  for (let i = 0; i < 4; i++) {
@@ -16652,18 +16869,18 @@ function calculateEndStability(sequence) {
16652
16869
  const firstBase = last5Bases[0];
16653
16870
  const lastBase = last5Bases[last5Bases.length - 1];
16654
16871
  if (firstBase === "G" || firstBase === "C") {
16655
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16656
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16872
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16873
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16657
16874
  } else {
16658
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16659
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16875
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16876
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16660
16877
  }
16661
16878
  if (lastBase === "G" || lastBase === "C") {
16662
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16663
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16879
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16880
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16664
16881
  } else {
16665
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16666
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16882
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16883
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16667
16884
  }
16668
16885
  const T = 310.15;
16669
16886
  const deltaG = deltaH - T * deltaS / 1e3;
@@ -16678,24 +16895,40 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16678
16895
  const pairs = [];
16679
16896
  if (!cutsites.length) return [];
16680
16897
  let sortedCutsites = cutsites.sort((a, b) => {
16681
- return a.topSnipPosition - b.topSnipPosition;
16898
+ return (a.topSnipPosition || 0) - (b.topSnipPosition || 0);
16682
16899
  });
16683
16900
  if (!circular) {
16684
16901
  sortedCutsites = [
16685
16902
  {
16903
+ start: 0,
16904
+ end: 0,
16686
16905
  topSnipPosition: 0,
16687
16906
  bottomSnipPosition: 0,
16688
16907
  overhangSize: 0,
16689
16908
  type: "START_OR_END_OF_SEQ",
16690
- name: "START_OF_SEQ"
16909
+ name: "START_OF_SEQ",
16910
+ restrictionEnzyme: {
16911
+ name: "START_OF_SEQ",
16912
+ site: "",
16913
+ forwardRegex: "",
16914
+ reverseRegex: ""
16915
+ }
16691
16916
  },
16692
16917
  ...sortedCutsites,
16693
16918
  {
16919
+ start: sequenceLength,
16920
+ end: sequenceLength,
16694
16921
  topSnipPosition: sequenceLength,
16695
16922
  bottomSnipPosition: sequenceLength,
16696
16923
  overhangSize: 0,
16697
16924
  type: "START_OR_END_OF_SEQ",
16698
- name: "END_OF_SEQ"
16925
+ name: "END_OF_SEQ",
16926
+ restrictionEnzyme: {
16927
+ name: "END_OF_SEQ",
16928
+ site: "",
16929
+ forwardRegex: "",
16930
+ reverseRegex: ""
16931
+ }
16699
16932
  }
16700
16933
  ];
16701
16934
  }
@@ -16718,11 +16951,11 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16718
16951
  });
16719
16952
  pairs.forEach(([cut1, cut2]) => {
16720
16953
  const start = normalizePositionByRangeLength(
16721
- cut1.topSnipPosition,
16954
+ cut1.topSnipPosition || 0,
16722
16955
  sequenceLength
16723
16956
  );
16724
16957
  const end = normalizePositionByRangeLength(
16725
- cut2.topSnipPosition - 1,
16958
+ (cut2.topSnipPosition || 0) - 1,
16726
16959
  sequenceLength
16727
16960
  );
16728
16961
  const fragmentRange = { start, end };
@@ -16740,7 +16973,9 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16740
16973
  })
16741
16974
  }, fragmentRange), {
16742
16975
  size,
16743
- id
16976
+ id,
16977
+ name: `${cut1.restrictionEnzyme.name} -- ${cut2.restrictionEnzyme.name} ${size} bps`
16978
+ // Add missing name property
16744
16979
  }));
16745
16980
  });
16746
16981
  fragments.filter((fragment) => {
@@ -16752,21 +16987,33 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16752
16987
  return fragments;
16753
16988
  }
16754
16989
  __name(getDigestFragmentsForCutsites, "getDigestFragmentsForCutsites");
16755
- function getDigestFragmentsForRestrictionEnzymes(sequence, circular, restrictionEnzymeOrEnzymes, opts) {
16756
- const restrictionEnzymes = Array.isArray(restrictionEnzymeOrEnzymes) ? restrictionEnzymeOrEnzymes : [restrictionEnzymeOrEnzymes];
16757
- const cutsites = flatMap(restrictionEnzymes, (restrictionEnzyme) => {
16758
- return cutSequenceByRestrictionEnzyme(
16759
- sequence,
16760
- circular,
16761
- restrictionEnzyme
16762
- );
16763
- });
16764
- return getDigestFragmentsForCutsites(
16765
- sequence.length,
16990
+ function getDigestFragmentsForRestrictionEnzymes(sequence, circular, contextEnzymes, options) {
16991
+ const cutsitesByName = getCutsitesFromSequence(
16992
+ sequence,
16766
16993
  circular,
16767
- cutsites,
16768
- opts
16994
+ Array.isArray(contextEnzymes) ? contextEnzymes : [contextEnzymes]
16769
16995
  );
16996
+ const digest = computeDigestFragments(__spreadProps(__spreadValues({
16997
+ cutsites: flatMap(cutsitesByName),
16998
+ sequenceLength: sequence.length,
16999
+ circular
17000
+ }, options), {
17001
+ computePartialDigest: (options == null ? void 0 : options.computePartialDigest) || (options == null ? void 0 : options.computePartialDigests)
17002
+ }));
17003
+ const fragments = uniqBy(digest.fragments, (fragment) => {
17004
+ return `${fragment.start}-${fragment.end}-${fragment.size}`;
17005
+ });
17006
+ if (circular && ((options == null ? void 0 : options.computePartialDigest) || (options == null ? void 0 : options.computePartialDigests))) {
17007
+ const fullLengthFragmentIndex = fragments.findIndex(
17008
+ (f) => f.size === sequence.length
17009
+ );
17010
+ if (fullLengthFragmentIndex > -1) {
17011
+ fragments.splice(fullLengthFragmentIndex, 1);
17012
+ }
17013
+ }
17014
+ return fragments.sort((a, b) => {
17015
+ return a.start - b.start || b.size - a.size;
17016
+ });
16770
17017
  }
16771
17018
  __name(getDigestFragmentsForRestrictionEnzymes, "getDigestFragmentsForRestrictionEnzymes");
16772
17019
  function convertAACaretPositionOrRangeToDna(rangeOrCaret) {
@@ -16812,11 +17059,13 @@ function shiftAnnotationsByLen({
16812
17059
  }) {
16813
17060
  modifiableTypes.forEach((annotationType) => {
16814
17061
  const existingAnnotations = seqData[annotationType];
16815
- seqData[annotationType] = adjustAnnotationsToInsert(
16816
- existingAnnotations,
16817
- caretPosition,
16818
- insertLength
16819
- );
17062
+ if (existingAnnotations) {
17063
+ seqData[annotationType] = adjustAnnotationsToInsert(
17064
+ existingAnnotations,
17065
+ caretPosition,
17066
+ insertLength
17067
+ );
17068
+ }
16820
17069
  });
16821
17070
  }
16822
17071
  __name(shiftAnnotationsByLen, "shiftAnnotationsByLen");
@@ -16887,7 +17136,7 @@ export {
16887
17136
  getMergedFeatureMap,
16888
17137
  getOrfsFromSequence,
16889
17138
  getOverlapBetweenTwoSequences,
16890
- getPossiblePartsFromSequenceAndEnzyme as getPossiblePartsFromSequenceAndEnzymes,
17139
+ getPossiblePartsFromSequenceAndEnzymes,
16891
17140
  getReverseAminoAcidStringFromSequenceString,
16892
17141
  getReverseComplementAminoAcidStringFromSequenceString,
16893
17142
  getReverseComplementAnnotation,