(data: ReadonlyArray<DataPoint>, isTuple: boolean)
| 670 | const monotonicXCache = new WeakMap<ReadonlyArray<DataPoint>, boolean>(); |
| 671 | |
| 672 | const isMonotonicNonDecreasingFiniteX = (data: ReadonlyArray<DataPoint>, isTuple: boolean): boolean => { |
| 673 | const cached = monotonicXCache.get(data); |
| 674 | if (cached !== undefined) return cached; |
| 675 | |
| 676 | let prevX = Number.NEGATIVE_INFINITY; |
| 677 | |
| 678 | if (isTuple) { |
| 679 | const tupleData = data as ReadonlyArray<TuplePoint>; |
| 680 | for (let i = 0; i < tupleData.length; i++) { |
| 681 | const x = tupleData[i][0]; |
| 682 | if (!Number.isFinite(x)) { |
| 683 | monotonicXCache.set(data, false); |
| 684 | return false; |
| 685 | } |
| 686 | if (x < prevX) { |
| 687 | monotonicXCache.set(data, false); |
| 688 | return false; |
| 689 | } |
| 690 | prevX = x; |
| 691 | } |
| 692 | monotonicXCache.set(data, true); |
| 693 | return true; |
| 694 | } |
| 695 | |
| 696 | const objectData = data as ReadonlyArray<ObjectPoint>; |
| 697 | for (let i = 0; i < objectData.length; i++) { |
| 698 | const x = objectData[i].x; |
| 699 | if (!Number.isFinite(x)) { |
| 700 | monotonicXCache.set(data, false); |
| 701 | return false; |
| 702 | } |
| 703 | if (x < prevX) { |
| 704 | monotonicXCache.set(data, false); |
| 705 | return false; |
| 706 | } |
| 707 | prevX = x; |
| 708 | } |
| 709 | monotonicXCache.set(data, true); |
| 710 | return true; |
| 711 | }; |
| 712 | |
| 713 | const lowerBoundXTuple = (data: ReadonlyArray<TuplePoint>, xTarget: number): number => { |
| 714 | let lo = 0; |
no outgoing calls
no test coverage detected