@teselagen/range-utils 0.3.14-beta.3 → 0.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adjustRangeToDeletionOfAnotherRange.d.ts +1 -2
- package/adjustRangeToInsert.d.ts +1 -2
- package/adjustRangeToRotation.d.ts +1 -5
- package/checkIfNonCircularRangesOverlap.d.ts +1 -2
- package/checkIfPotentiallyCircularRangesOverlap.d.ts +1 -2
- package/collapseOverlapsGeneratedFromRangeComparisonIfPossible.d.ts +1 -2
- package/convertRangeIndices.d.ts +1 -10
- package/convertRangeTo0Based.d.ts +1 -5
- package/convertRangeTo1Based.d.ts +1 -5
- package/doesRangeSpanEntireSequence.d.ts +1 -2
- package/doesRangeSpanOrigin.d.ts +1 -2
- package/expandOrContractCircularRangeToPosition.d.ts +2 -3
- package/expandOrContractNonCircularRangeToPosition.d.ts +2 -3
- package/expandOrContractRangeByLength.d.ts +1 -5
- package/expandOrContractRangeToPosition.d.ts +2 -3
- package/flipContainedRange.d.ts +1 -5
- package/generateRandomRange.d.ts +3 -3
- package/getAnnotationRangeType.d.ts +1 -2
- package/getEachPositionInRangeAsArray.d.ts +1 -2
- package/getLengthOfOverlappingRegionsBetweenTwoRanges.d.ts +1 -2
- package/getMiddleOfRange.d.ts +1 -2
- package/getOverlapOfNonCircularRanges.d.ts +4 -5
- package/getOverlapsOfPotentiallyCircularRanges.d.ts +1 -2
- package/getPositionFromAngle.d.ts +1 -1
- package/getRangeAngles.d.ts +7 -3
- package/getRangeLength.d.ts +1 -5
- package/getRangesBetweenTwoRanges.d.ts +1 -2
- package/getSequenceWithinRange.d.ts +1 -2
- package/getShortestDistanceBetweenTwoPositions.d.ts +1 -1
- package/getYOffsetForPotentiallyCircularRange.d.ts +1 -2
- package/getYOffsetsForPotentiallyCircularRanges.d.ts +2 -3
- package/getZeroedRangeOverlaps.d.ts +1 -2
- package/index.cjs +41 -52
- package/index.d.ts +0 -1
- package/index.js +41 -52
- package/index.umd.cjs +41 -52
- package/invertRange.d.ts +1 -5
- package/isPositionCloserToRangeStartThanRangeEnd.d.ts +1 -2
- package/isPositionWithinRange.d.ts +2 -3
- package/isRangeOrPositionWithinRange.d.ts +1 -2
- package/isRangeWithinRange.d.ts +1 -2
- package/loopEachPositionInRange.d.ts +1 -2
- package/modulatePositionByRange.d.ts +1 -2
- package/modulateRangeBySequenceLength.d.ts +1 -8
- package/normalizePositionByRangeLength.d.ts +1 -1
- package/normalizePositionByRangeLength1Based.d.ts +1 -1
- package/normalizeRange.d.ts +1 -5
- package/package.json +4 -12
- package/provideInclusiveOptions.d.ts +1 -6
- package/reversePositionInRange.d.ts +1 -1
- package/splitRangeIntoTwoPartsIfItIsCircular.d.ts +3 -4
- package/translateRange.d.ts +1 -5
- package/trimAnnStartEndToFitSeqLength.d.ts +1 -1
- package/trimNonCicularRangeByAnotherNonCircularRange.d.ts +4 -2
- package/trimNumberToFitWithin0ToAnotherNumber.d.ts +1 -1
- package/trimRangeByAnotherRange.d.ts +1 -2
- package/zeroSubrangeByContainerRange.d.ts +1 -2
- package/RangeAngles.d.ts +0 -7
- package/src/RangeAngles.ts +0 -9
- package/src/adjustRangeToDeletionOfAnotherRange.ts +0 -57
- package/src/adjustRangeToInsert.ts +0 -32
- package/src/adjustRangeToRotation.ts +0 -23
- package/src/checkIfNonCircularRangesOverlap.ts +0 -35
- package/src/checkIfPotentiallyCircularRangesOverlap.ts +0 -28
- package/src/collapseOverlapsGeneratedFromRangeComparisonIfPossible.ts +0 -81
- package/src/convertRangeIndices.ts +0 -34
- package/src/convertRangeTo0Based.ts +0 -9
- package/src/convertRangeTo1Based.ts +0 -10
- package/src/doesRangeSpanEntireSequence.ts +0 -12
- package/src/doesRangeSpanOrigin.ts +0 -5
- package/src/expandOrContractCircularRangeToPosition.ts +0 -50
- package/src/expandOrContractNonCircularRangeToPosition.ts +0 -30
- package/src/expandOrContractRangeByLength.ts +0 -18
- package/src/expandOrContractRangeToPosition.ts +0 -16
- package/src/flipContainedRange.ts +0 -156
- package/src/generateRandomRange.ts +0 -26
- package/src/getAnnotationRangeType.ts +0 -30
- package/src/getEachPositionInRangeAsArray.ts +0 -19
- package/src/getLengthOfOverlappingRegionsBetweenTwoRanges.ts +0 -18
- package/src/getMiddleOfRange.ts +0 -11
- package/src/getOverlapOfNonCircularRanges.ts +0 -41
- package/src/getOverlapsOfPotentiallyCircularRanges.ts +0 -60
- package/src/getPositionFromAngle.ts +0 -12
- package/src/getRangeAngles.ts +0 -38
- package/src/getRangeLength.test.ts +0 -30
- package/src/getRangeLength.ts +0 -17
- package/src/getRangesBetweenTwoRanges.ts +0 -42
- package/src/getSequenceWithinRange.test.ts +0 -47
- package/src/getSequenceWithinRange.ts +0 -24
- package/src/getShortestDistanceBetweenTwoPositions.test.ts +0 -12
- package/src/getShortestDistanceBetweenTwoPositions.ts +0 -16
- package/src/getYOffsetForPotentiallyCircularRange.ts +0 -37
- package/src/getYOffsetsForPotentiallyCircularRanges.test.ts +0 -17
- package/src/getYOffsetsForPotentiallyCircularRanges.ts +0 -28
- package/src/getZeroedRangeOverlaps.test.ts +0 -65
- package/src/getZeroedRangeOverlaps.ts +0 -33
- package/src/index.test.ts +0 -39
- package/src/index.ts +0 -53
- package/src/invertRange.ts +0 -25
- package/src/isPositionCloserToRangeStartThanRangeEnd.ts +0 -22
- package/src/isPositionWithinRange.ts +0 -40
- package/src/isRangeOrPositionWithinRange.ts +0 -40
- package/src/isRangeWithinRange.ts +0 -18
- package/src/loopEachPositionInRange.ts +0 -11
- package/src/modulatePositionByRange.ts +0 -15
- package/src/modulateRangeBySequenceLength.ts +0 -13
- package/src/normalizePositionByRangeLength.ts +0 -24
- package/src/normalizePositionByRangeLength1Based.ts +0 -9
- package/src/normalizeRange.ts +0 -12
- package/src/provideInclusiveOptions.ts +0 -79
- package/src/reversePositionInRange.ts +0 -17
- package/src/splitRangeIntoTwoPartsIfItIsCircular.ts +0 -36
- package/src/translateRange.ts +0 -21
- package/src/trimAnnStartEndToFitSeqLength.ts +0 -9
- package/src/trimNonCicularRangeByAnotherNonCircularRange.ts +0 -63
- package/src/trimNumberToFitWithin0ToAnotherNumber.ts +0 -15
- package/src/trimRangeByAnotherRange.ts +0 -103
- package/src/types.ts +0 -12
- package/src/zeroSubrangeByContainerRange.ts +0 -49
- package/types.d.ts +0 -12
package/src/invertRange.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
4
|
-
import provideInclusiveOptions from "./provideInclusiveOptions";
|
|
5
|
-
export default provideInclusiveOptions(invertRange);
|
|
6
|
-
|
|
7
|
-
function invertRange(
|
|
8
|
-
rangeOrCaret: Range | number,
|
|
9
|
-
rangeMax: number
|
|
10
|
-
): Range | undefined {
|
|
11
|
-
if (typeof rangeOrCaret !== "number" && rangeOrCaret.start > -1) {
|
|
12
|
-
const start = rangeOrCaret.end + 1;
|
|
13
|
-
const end = rangeOrCaret.start - 1;
|
|
14
|
-
return {
|
|
15
|
-
start: normalizePositionByRangeLength(start, rangeMax, false),
|
|
16
|
-
end: normalizePositionByRangeLength(end, rangeMax, false)
|
|
17
|
-
};
|
|
18
|
-
} else if (typeof rangeOrCaret === "number" && rangeOrCaret > -1) {
|
|
19
|
-
return {
|
|
20
|
-
start: normalizePositionByRangeLength(rangeOrCaret, rangeMax, false),
|
|
21
|
-
end: normalizePositionByRangeLength(rangeOrCaret - 1, rangeMax, false)
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
//function to calculate whether a position is closer to the range start than the range end
|
|
2
|
-
import getShortestDistanceBetweenTwoPositions from "./getShortestDistanceBetweenTwoPositions";
|
|
3
|
-
|
|
4
|
-
import { Range } from "./types";
|
|
5
|
-
|
|
6
|
-
export default function isPositionCloserToRangeStartThanRangeEnd(
|
|
7
|
-
position: number,
|
|
8
|
-
range: Range,
|
|
9
|
-
maxLength: number
|
|
10
|
-
) {
|
|
11
|
-
const distanceFromStart = getShortestDistanceBetweenTwoPositions(
|
|
12
|
-
range.start,
|
|
13
|
-
position,
|
|
14
|
-
maxLength
|
|
15
|
-
);
|
|
16
|
-
const distanceFromEnd = getShortestDistanceBetweenTwoPositions(
|
|
17
|
-
range.end,
|
|
18
|
-
position,
|
|
19
|
-
maxLength
|
|
20
|
-
);
|
|
21
|
-
return distanceFromStart <= distanceFromEnd;
|
|
22
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import splitRangeIntoTwoPartsIfItIsCircular from "./splitRangeIntoTwoPartsIfItIsCircular";
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
* @param {*} position //assumed to be a 0 based "caretPosition"
|
|
5
|
-
* @param {*} range //0 based inclusive range
|
|
6
|
-
* @param {*} sequenceLength
|
|
7
|
-
* @param {*} includeEdges - (default false) whether or not to say
|
|
8
|
-
*/
|
|
9
|
-
import { Range } from "./types";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
* @param {*} position //assumed to be a 0 based "caretPosition"
|
|
14
|
-
* @param {*} range //0 based inclusive range
|
|
15
|
-
* @param {*} sequenceLength
|
|
16
|
-
* @param {*} includeEdges - (default false) whether or not to say
|
|
17
|
-
*/
|
|
18
|
-
function isPositionWithinRange(
|
|
19
|
-
position: number,
|
|
20
|
-
range: Range,
|
|
21
|
-
sequenceLength: number,
|
|
22
|
-
includeStartEdge?: boolean,
|
|
23
|
-
includeEndEdge?: boolean
|
|
24
|
-
) {
|
|
25
|
-
const ranges = splitRangeIntoTwoPartsIfItIsCircular(range, sequenceLength);
|
|
26
|
-
const positionFits = ranges.some(function (range) {
|
|
27
|
-
if (includeStartEdge ? position < range.start : position <= range.start) {
|
|
28
|
-
return false;
|
|
29
|
-
} else {
|
|
30
|
-
if (includeEndEdge ? position <= range.end + 1 : position <= range.end) {
|
|
31
|
-
return true;
|
|
32
|
-
} else {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
return positionFits;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default isPositionWithinRange;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { isObject } from "lodash-es";
|
|
2
|
-
import isRangeWithinRange from "./isRangeWithinRange";
|
|
3
|
-
import isPositionWithinRange from "./isPositionWithinRange";
|
|
4
|
-
|
|
5
|
-
import { Range } from "./types";
|
|
6
|
-
|
|
7
|
-
export default function isRangeOrPositionWithinRange(
|
|
8
|
-
rangeOrPositionToCheck: Range | number,
|
|
9
|
-
containingRange: Range,
|
|
10
|
-
maxLength: number,
|
|
11
|
-
includeStartEdge?: boolean,
|
|
12
|
-
includeEndEdge?: boolean
|
|
13
|
-
) {
|
|
14
|
-
if (
|
|
15
|
-
rangeOrPositionToCheck === undefined ||
|
|
16
|
-
rangeOrPositionToCheck === null ||
|
|
17
|
-
containingRange === undefined ||
|
|
18
|
-
containingRange === null
|
|
19
|
-
) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
if (isObject(rangeOrPositionToCheck)) {
|
|
23
|
-
if (typeof (rangeOrPositionToCheck as Range).start !== "number") {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
return isRangeWithinRange(
|
|
27
|
-
rangeOrPositionToCheck as Range,
|
|
28
|
-
containingRange,
|
|
29
|
-
maxLength
|
|
30
|
-
);
|
|
31
|
-
} else {
|
|
32
|
-
return isPositionWithinRange(
|
|
33
|
-
rangeOrPositionToCheck,
|
|
34
|
-
containingRange,
|
|
35
|
-
maxLength,
|
|
36
|
-
includeStartEdge,
|
|
37
|
-
includeEndEdge
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
//TNR: THIS METHOD ONLY WORKS FOR COMPARING 0-BASED RANGES!!!!!!
|
|
2
|
-
import trimRangeByAnotherRange from "./trimRangeByAnotherRange";
|
|
3
|
-
|
|
4
|
-
import { Range } from "./types";
|
|
5
|
-
|
|
6
|
-
export default function isRangeWithinRange(
|
|
7
|
-
rangeToCheck: Range,
|
|
8
|
-
containingRange: Range,
|
|
9
|
-
maxLength: number
|
|
10
|
-
) {
|
|
11
|
-
const ranges = trimRangeByAnotherRange(
|
|
12
|
-
rangeToCheck,
|
|
13
|
-
containingRange,
|
|
14
|
-
maxLength
|
|
15
|
-
);
|
|
16
|
-
if (ranges === null) return false;
|
|
17
|
-
return !ranges;
|
|
18
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
import getEachPositionInRangeAsArray from "./getEachPositionInRangeAsArray";
|
|
4
|
-
|
|
5
|
-
export default function loopEachPositionInRange(
|
|
6
|
-
range: Range,
|
|
7
|
-
rangeMax: number,
|
|
8
|
-
func: (pos: number) => void
|
|
9
|
-
) {
|
|
10
|
-
getEachPositionInRangeAsArray(range, rangeMax).map(func);
|
|
11
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
//this function takes a position that might not fit in a given range and puts it into that range
|
|
4
|
-
export default function modulatePositionByRange(
|
|
5
|
-
position: number,
|
|
6
|
-
range: Range
|
|
7
|
-
) {
|
|
8
|
-
let returnVal = position;
|
|
9
|
-
if (position < range.start) {
|
|
10
|
-
returnVal = range.end - (range.start - (position + 1));
|
|
11
|
-
} else if (position > range.end) {
|
|
12
|
-
returnVal = range.start + (position - range.end - 1);
|
|
13
|
-
}
|
|
14
|
-
return returnVal;
|
|
15
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
4
|
-
import provideInclusiveOptions from "./provideInclusiveOptions";
|
|
5
|
-
import { assign } from "lodash-es";
|
|
6
|
-
export default provideInclusiveOptions(modulateRangeBySequenceLength);
|
|
7
|
-
|
|
8
|
-
function modulateRangeBySequenceLength(range: Range, seqLen: number) {
|
|
9
|
-
return assign(range, {
|
|
10
|
-
start: normalizePositionByRangeLength(range.start, seqLen),
|
|
11
|
-
end: normalizePositionByRangeLength(range.end, seqLen)
|
|
12
|
-
});
|
|
13
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ac.throw([ac.posInt, ac.posInt, ac.bool], arguments);
|
|
3
|
-
export default function normalizePositionByRangeLength(
|
|
4
|
-
pPosition: number,
|
|
5
|
-
sequenceLength: number,
|
|
6
|
-
isInBetweenPositions = false
|
|
7
|
-
) {
|
|
8
|
-
//isInBetweenPositions refers to:
|
|
9
|
-
// A T G C
|
|
10
|
-
// 0 1 2 3 <-- isInBetweenPositions = false is counting the positions themselves
|
|
11
|
-
//0 1 2 3 4 <-- isInBetweenPositions = true is counting the spaces between positions
|
|
12
|
-
// ac.throw([ac.number, ac.posInt, ac.bool], arguments);
|
|
13
|
-
let position = pPosition;
|
|
14
|
-
if (position < 0) {
|
|
15
|
-
position += sequenceLength;
|
|
16
|
-
} else if (position + (isInBetweenPositions ? 0 : 1) > sequenceLength) {
|
|
17
|
-
position -= sequenceLength;
|
|
18
|
-
}
|
|
19
|
-
return position < 0
|
|
20
|
-
? 0
|
|
21
|
-
: position > sequenceLength - (isInBetweenPositions ? 0 : 1)
|
|
22
|
-
? sequenceLength - (isInBetweenPositions ? 0 : 1)
|
|
23
|
-
: position;
|
|
24
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
import modulatePositionByRange from "./modulatePositionByRange";
|
|
3
|
-
|
|
4
|
-
export default function normalizePositionByRangeLength1Based(
|
|
5
|
-
position: number,
|
|
6
|
-
sequenceLength: number
|
|
7
|
-
) {
|
|
8
|
-
return modulatePositionByRange(position, { start: 1, end: sequenceLength });
|
|
9
|
-
}
|
package/src/normalizeRange.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
//normalize range takes in a range that might be slightly outside of the rangeMax and wraps the start/end as necessary to fit
|
|
2
|
-
import { assign } from "lodash-es";
|
|
3
|
-
|
|
4
|
-
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
5
|
-
import { Range } from "./types";
|
|
6
|
-
|
|
7
|
-
export default function normalizeRange(range: Range, sequenceLength: number) {
|
|
8
|
-
return assign({}, range, {
|
|
9
|
-
start: normalizePositionByRangeLength(range.start, sequenceLength),
|
|
10
|
-
end: normalizePositionByRangeLength(range.end, sequenceLength)
|
|
11
|
-
});
|
|
12
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { assign } from "lodash-es";
|
|
2
|
-
|
|
3
|
-
type Options = {
|
|
4
|
-
inclusive1BasedEnd?: boolean;
|
|
5
|
-
inclusive1BasedStart?: boolean;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export default function provideInclusiveOptions<
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
-
T extends (...args: any[]) => any
|
|
11
|
-
>(
|
|
12
|
-
funToWrap: T
|
|
13
|
-
): (
|
|
14
|
-
...args: [...Parameters<T>, options?: Options]
|
|
15
|
-
) => ReturnType<T> {
|
|
16
|
-
return function (
|
|
17
|
-
this: unknown,
|
|
18
|
-
...args: [...Parameters<T>, options?: Options]
|
|
19
|
-
): ReturnType<T> {
|
|
20
|
-
const options = args[args.length - 1] as Options | undefined;
|
|
21
|
-
if (
|
|
22
|
-
options &&
|
|
23
|
-
(options.inclusive1BasedEnd || options.inclusive1BasedStart)
|
|
24
|
-
) {
|
|
25
|
-
args.forEach(function (arg, index) {
|
|
26
|
-
// cast arg to check for start/end
|
|
27
|
-
const potentialRange = arg as { start?: number; end?: number } | null;
|
|
28
|
-
if (
|
|
29
|
-
potentialRange &&
|
|
30
|
-
typeof potentialRange.start === "number" &&
|
|
31
|
-
potentialRange.start > -1 &&
|
|
32
|
-
options.inclusive1BasedStart
|
|
33
|
-
) {
|
|
34
|
-
args[index] = assign(potentialRange, {
|
|
35
|
-
start: potentialRange.start - 1
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
if (
|
|
39
|
-
potentialRange &&
|
|
40
|
-
typeof potentialRange.end === "number" &&
|
|
41
|
-
potentialRange.end > -1 &&
|
|
42
|
-
options.inclusive1BasedEnd
|
|
43
|
-
) {
|
|
44
|
-
args[index] = assign(potentialRange, {
|
|
45
|
-
end: potentialRange.end - 1
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
51
|
-
let returnVal = (funToWrap as Function).apply(this, args);
|
|
52
|
-
const potentialReturn = returnVal as {
|
|
53
|
-
start?: number;
|
|
54
|
-
end?: number;
|
|
55
|
-
} | null;
|
|
56
|
-
|
|
57
|
-
if (
|
|
58
|
-
potentialReturn &&
|
|
59
|
-
typeof potentialReturn.start === "number" &&
|
|
60
|
-
potentialReturn.start > -1 &&
|
|
61
|
-
options &&
|
|
62
|
-
options.inclusive1BasedStart
|
|
63
|
-
) {
|
|
64
|
-
returnVal = assign(potentialReturn, {
|
|
65
|
-
start: potentialReturn.start + 1
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
if (
|
|
69
|
-
potentialReturn &&
|
|
70
|
-
typeof potentialReturn.end === "number" &&
|
|
71
|
-
potentialReturn.end > -1 &&
|
|
72
|
-
options &&
|
|
73
|
-
options.inclusive1BasedEnd
|
|
74
|
-
) {
|
|
75
|
-
returnVal = assign(potentialReturn, { end: potentialReturn.end + 1 });
|
|
76
|
-
}
|
|
77
|
-
return returnVal as ReturnType<T>;
|
|
78
|
-
};
|
|
79
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
export default function reversePositionInRange(
|
|
3
|
-
position: number,
|
|
4
|
-
rangeLength: number,
|
|
5
|
-
isInBetweenPositions: boolean
|
|
6
|
-
) {
|
|
7
|
-
//isInBetweenPositions refers to:
|
|
8
|
-
// A T G C
|
|
9
|
-
// 0 1 2 3 <-- isInBetweenPositions = false is counting the positions themselves
|
|
10
|
-
//0 1 2 3 4 <-- isInBetweenPositions = true is counting the spaces between positions
|
|
11
|
-
// ac.throw([
|
|
12
|
-
// ac.posInt,
|
|
13
|
-
// ac.posInt,
|
|
14
|
-
// ac.bool
|
|
15
|
-
// ], arguments);
|
|
16
|
-
return rangeLength - position - (isInBetweenPositions ? 0 : 1);
|
|
17
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
// ac.throw([ac.posInt, ac.posInt, ac.bool], arguments);
|
|
5
|
-
//takes a potentially circular range and returns an array containing the range split on the origin
|
|
6
|
-
export default function splitRangeIntoTwoPartsIfItIsCircular(
|
|
7
|
-
range: Range,
|
|
8
|
-
sequenceLength: number
|
|
9
|
-
) {
|
|
10
|
-
// ac.throw([ac.range, ac.number], arguments);
|
|
11
|
-
if (sequenceLength !== 0) {
|
|
12
|
-
sequenceLength = sequenceLength || Infinity;
|
|
13
|
-
}
|
|
14
|
-
const ranges = [];
|
|
15
|
-
if (range.start > range.end) {
|
|
16
|
-
//the range is cicular, so we return an array of two ranges
|
|
17
|
-
ranges.push({
|
|
18
|
-
start: 0,
|
|
19
|
-
end: range.end,
|
|
20
|
-
type: "end"
|
|
21
|
-
});
|
|
22
|
-
ranges.push({
|
|
23
|
-
start: range.start,
|
|
24
|
-
end: sequenceLength - 1,
|
|
25
|
-
type: "beginning"
|
|
26
|
-
});
|
|
27
|
-
} else {
|
|
28
|
-
//the range isn't circular, so we just return the range
|
|
29
|
-
ranges.push({
|
|
30
|
-
start: range.start,
|
|
31
|
-
end: range.end,
|
|
32
|
-
type: "beginningAndEnd"
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
return ranges;
|
|
36
|
-
}
|
package/src/translateRange.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
import { assign } from "lodash-es";
|
|
4
|
-
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
5
|
-
|
|
6
|
-
export default function translateRange(
|
|
7
|
-
rangeToBeAdjusted: Range,
|
|
8
|
-
translateBy: number,
|
|
9
|
-
rangeLength: number
|
|
10
|
-
) {
|
|
11
|
-
return assign({}, rangeToBeAdjusted, {
|
|
12
|
-
start: normalizePositionByRangeLength(
|
|
13
|
-
rangeToBeAdjusted.start + translateBy,
|
|
14
|
-
rangeLength
|
|
15
|
-
),
|
|
16
|
-
end: normalizePositionByRangeLength(
|
|
17
|
-
rangeToBeAdjusted.end + translateBy,
|
|
18
|
-
rangeLength
|
|
19
|
-
)
|
|
20
|
-
});
|
|
21
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
import { Range } from "./types";
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
export default function trimNonCicularRangeByAnotherNonCircularRange(
|
|
6
|
-
rangeToBeTrimmed: Range,
|
|
7
|
-
trimmingRange: Range
|
|
8
|
-
): Range | undefined {
|
|
9
|
-
// ac.throw([ac.range, ac.range], arguments);
|
|
10
|
-
let outputTrimmedRange;
|
|
11
|
-
if (!rangeToBeTrimmed) {
|
|
12
|
-
return outputTrimmedRange;
|
|
13
|
-
}
|
|
14
|
-
if (rangeToBeTrimmed.start < trimmingRange.start) {
|
|
15
|
-
if (rangeToBeTrimmed.end < trimmingRange.start) {
|
|
16
|
-
// rrr <range to be trimmed
|
|
17
|
-
// ttt <trimming range
|
|
18
|
-
outputTrimmedRange = {
|
|
19
|
-
start: rangeToBeTrimmed.start,
|
|
20
|
-
end: rangeToBeTrimmed.end
|
|
21
|
-
};
|
|
22
|
-
} else {
|
|
23
|
-
if (rangeToBeTrimmed.end > trimmingRange.end) {
|
|
24
|
-
// rrrrrr <range to be trimmed
|
|
25
|
-
// ttt <trimming range
|
|
26
|
-
outputTrimmedRange = {
|
|
27
|
-
start: rangeToBeTrimmed.start,
|
|
28
|
-
end: rangeToBeTrimmed.end
|
|
29
|
-
};
|
|
30
|
-
} else {
|
|
31
|
-
// rrrrrr <range to be trimmed
|
|
32
|
-
// ttt <trimming range
|
|
33
|
-
outputTrimmedRange = {
|
|
34
|
-
start: rangeToBeTrimmed.start,
|
|
35
|
-
end: trimmingRange.start - 1
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
if (rangeToBeTrimmed.end <= trimmingRange.end) {
|
|
41
|
-
// rrr <range to be trimmed
|
|
42
|
-
// ttttt <trimming range
|
|
43
|
-
//fully deleting the range, so do nothing
|
|
44
|
-
} else {
|
|
45
|
-
if (rangeToBeTrimmed.start > trimmingRange.end) {
|
|
46
|
-
// rrrrrr <range to be trimmed
|
|
47
|
-
// ttt <trimming range
|
|
48
|
-
outputTrimmedRange = {
|
|
49
|
-
end: rangeToBeTrimmed.end,
|
|
50
|
-
start: rangeToBeTrimmed.start
|
|
51
|
-
};
|
|
52
|
-
} else {
|
|
53
|
-
// rrrrrr <range to be trimmed
|
|
54
|
-
// ttt <trimming range
|
|
55
|
-
outputTrimmedRange = {
|
|
56
|
-
end: rangeToBeTrimmed.end,
|
|
57
|
-
start: trimmingRange.end + 1
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return outputTrimmedRange;
|
|
63
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ac.throw([ac.posInt, ac.posInt, ac.bool], arguments);
|
|
3
|
-
export default function trimNumberToFitWithin0ToAnotherNumber(
|
|
4
|
-
numberToBeTrimmed: number,
|
|
5
|
-
max: number
|
|
6
|
-
) {
|
|
7
|
-
// ac.throw([ac.number, ac.number], arguments);
|
|
8
|
-
if (numberToBeTrimmed < 0) {
|
|
9
|
-
numberToBeTrimmed = 0;
|
|
10
|
-
}
|
|
11
|
-
if (numberToBeTrimmed > max) {
|
|
12
|
-
numberToBeTrimmed = max;
|
|
13
|
-
}
|
|
14
|
-
return numberToBeTrimmed;
|
|
15
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import getOverlapsOfPotentiallyCircularRanges from "./getOverlapsOfPotentiallyCircularRanges";
|
|
2
|
-
import splitRangeIntoTwoPartsIfItIsCircular from "./splitRangeIntoTwoPartsIfItIsCircular";
|
|
3
|
-
import trimNonCicularRangeByAnotherNonCircularRange from "./trimNonCicularRangeByAnotherNonCircularRange";
|
|
4
|
-
import { extend } from "lodash-es";
|
|
5
|
-
import { Range } from "./types";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* trims range, but does *not* adjust it
|
|
9
|
-
* returns a new range if there is one, or null, if it is trimmed completely
|
|
10
|
-
* @param {object} subRange {start:
|
|
11
|
-
* end:
|
|
12
|
-
* }
|
|
13
|
-
* @param {object} containerRange {start:
|
|
14
|
-
* end:
|
|
15
|
-
* }
|
|
16
|
-
* @param {int} sequenceLength
|
|
17
|
-
* @return {object} || null {start:
|
|
18
|
-
* end:
|
|
19
|
-
* }
|
|
20
|
-
*/
|
|
21
|
-
export default function trimRangeByAnotherRange(
|
|
22
|
-
rangeToBeTrimmed: Range,
|
|
23
|
-
trimmingRange: Range,
|
|
24
|
-
sequenceLength: number
|
|
25
|
-
): Range | undefined | null {
|
|
26
|
-
if (!rangeToBeTrimmed || !trimmingRange) {
|
|
27
|
-
console.warn("invalid range input");
|
|
28
|
-
return null; //a null return val means something went wrong with this function
|
|
29
|
-
}
|
|
30
|
-
let position;
|
|
31
|
-
for (position of [
|
|
32
|
-
rangeToBeTrimmed.start,
|
|
33
|
-
rangeToBeTrimmed.end,
|
|
34
|
-
trimmingRange.start,
|
|
35
|
-
trimmingRange.end
|
|
36
|
-
]) {
|
|
37
|
-
if (position < 0 || (!position && position !== 0)) {
|
|
38
|
-
console.warn("invalid range input");
|
|
39
|
-
return null; //a null return val means something went wrong with this function
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
//get the overlaps of the ranges
|
|
43
|
-
const overlaps = getOverlapsOfPotentiallyCircularRanges(
|
|
44
|
-
rangeToBeTrimmed,
|
|
45
|
-
trimmingRange,
|
|
46
|
-
sequenceLength
|
|
47
|
-
);
|
|
48
|
-
//split the range to be trimmed into pieces if necessary
|
|
49
|
-
if (!overlaps.length) {
|
|
50
|
-
//just return the range to be trimmed
|
|
51
|
-
return rangeToBeTrimmed;
|
|
52
|
-
}
|
|
53
|
-
//and trim both pieces by the already calculated overlaps
|
|
54
|
-
const splitRangesToBeTrimmed: (Range | undefined | null)[] =
|
|
55
|
-
splitRangeIntoTwoPartsIfItIsCircular(rangeToBeTrimmed, sequenceLength);
|
|
56
|
-
splitRangesToBeTrimmed.forEach(function (nonCircularRangeToBeTrimmed, index) {
|
|
57
|
-
overlaps.forEach(function (overlap) {
|
|
58
|
-
if (nonCircularRangeToBeTrimmed) {
|
|
59
|
-
nonCircularRangeToBeTrimmed =
|
|
60
|
-
trimNonCicularRangeByAnotherNonCircularRange(
|
|
61
|
-
nonCircularRangeToBeTrimmed,
|
|
62
|
-
overlap
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
splitRangesToBeTrimmed[index] = nonCircularRangeToBeTrimmed;
|
|
67
|
-
});
|
|
68
|
-
//filter out any of the split ranges that have been fully deleted!
|
|
69
|
-
const outputSplitRanges = splitRangesToBeTrimmed.filter(
|
|
70
|
-
function (trimmedRange): trimmedRange is Range {
|
|
71
|
-
if (trimmedRange) {
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
let outputTrimmedRange;
|
|
79
|
-
if (outputSplitRanges.length < 0) {
|
|
80
|
-
//do nothing to the output trimmed range
|
|
81
|
-
} else if (outputSplitRanges.length === 1) {
|
|
82
|
-
outputTrimmedRange = outputSplitRanges[0];
|
|
83
|
-
} else if (outputSplitRanges.length === 2) {
|
|
84
|
-
if (outputSplitRanges[0].start < outputSplitRanges[1].start) {
|
|
85
|
-
outputTrimmedRange = {
|
|
86
|
-
start: outputSplitRanges[1].start,
|
|
87
|
-
end: outputSplitRanges[0].end
|
|
88
|
-
};
|
|
89
|
-
} else {
|
|
90
|
-
outputTrimmedRange = {
|
|
91
|
-
start: outputSplitRanges[0].start,
|
|
92
|
-
end: outputSplitRanges[1].end
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (outputTrimmedRange) {
|
|
97
|
-
return extend({}, rangeToBeTrimmed, {
|
|
98
|
-
start: outputTrimmedRange.start,
|
|
99
|
-
end: outputTrimmedRange.end
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface Range {
|
|
2
|
-
start: number;
|
|
3
|
-
end: number;
|
|
4
|
-
type?: string;
|
|
5
|
-
locations?: Range[];
|
|
6
|
-
overlapsSelf?: boolean;
|
|
7
|
-
yOffset?: number;
|
|
8
|
-
aminoAcids?: unknown[];
|
|
9
|
-
forward?: boolean;
|
|
10
|
-
notes?: Record<string, unknown> | string;
|
|
11
|
-
[key: string]: unknown;
|
|
12
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ac.throw([ac.posInt, ac.posInt, ac.bool], arguments);
|
|
3
|
-
import trimRangeByAnotherRange from "./trimRangeByAnotherRange";
|
|
4
|
-
|
|
5
|
-
import { Range } from "./types";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* "zeroes" a subrange of a container range by
|
|
9
|
-
* adjusting subRange start and end such that it is as if the container range start = 0.
|
|
10
|
-
* @param {object} subRange {start:
|
|
11
|
-
* end:
|
|
12
|
-
* }
|
|
13
|
-
* @param {object} containerRange {start:
|
|
14
|
-
* end:
|
|
15
|
-
* }
|
|
16
|
-
* @param {int} sequenceLength
|
|
17
|
-
* @return {object} {start:
|
|
18
|
-
* end:
|
|
19
|
-
* }
|
|
20
|
-
*/
|
|
21
|
-
export default function zeroSubrangeByContainerRange(
|
|
22
|
-
subRange: Range,
|
|
23
|
-
containerRange: Range,
|
|
24
|
-
sequenceLength: number
|
|
25
|
-
) {
|
|
26
|
-
// ac.throw([ac.range, ac.range, ac.posInt], arguments);
|
|
27
|
-
//first check to make sure the container range fully contains the subRange
|
|
28
|
-
const trimmedSubRange = trimRangeByAnotherRange(
|
|
29
|
-
subRange,
|
|
30
|
-
containerRange,
|
|
31
|
-
sequenceLength
|
|
32
|
-
);
|
|
33
|
-
if (trimmedSubRange) {
|
|
34
|
-
throw new Error(
|
|
35
|
-
"subRange must be fully contained by containerRange! Otherwise this function does not make sense"
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
const newSubrange: Range = {
|
|
39
|
-
start: subRange.start - containerRange.start,
|
|
40
|
-
end: subRange.end - containerRange.start
|
|
41
|
-
};
|
|
42
|
-
if (newSubrange.start < 0) {
|
|
43
|
-
newSubrange.start += sequenceLength;
|
|
44
|
-
}
|
|
45
|
-
if (newSubrange.end < 0) {
|
|
46
|
-
newSubrange.end += sequenceLength;
|
|
47
|
-
}
|
|
48
|
-
return newSubrange;
|
|
49
|
-
}
|
package/types.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface Range {
|
|
2
|
-
start: number;
|
|
3
|
-
end: number;
|
|
4
|
-
type?: string;
|
|
5
|
-
locations?: Range[];
|
|
6
|
-
overlapsSelf?: boolean;
|
|
7
|
-
yOffset?: number;
|
|
8
|
-
aminoAcids?: unknown[];
|
|
9
|
-
forward?: boolean;
|
|
10
|
-
notes?: Record<string, unknown> | string;
|
|
11
|
-
[key: string]: unknown;
|
|
12
|
-
}
|