UNPKG

@sahabaplus/mushaf-engine

Version:

TypeScript implementation of a Quran Mushaf navigation engine

130 lines (129 loc) 4.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NavigationBounds = void 0; const versePosition_1 = require("./versePosition"); /** * Defines boundaries and iteration limits for verse navigation. * * `NavigationBounds` controls how the `VersesNavigator` behaves when navigating through * verses. It establishes a bounded range and controls how many times the navigator * can cycle through that range before stopping. * * # Key Concepts * * ## Iteration Limits * The `iterationLimit` controls how many complete cycles through the bounded range * are allowed: * - **0**: No iterations allowed - navigation stops at the end boundary * - **1**: One complete cycle through the range * - **n**: n complete cycles through the range * * ## Bounds and Direction * The bounds can work in two modes: * - **Inclusive mode** (`upperBound < lowerBound`): Navigate from upperBound to lowerBound (inclusive) * - Example: upperBound: (1,1), lowerBound: (114,6) - navigate entire Quran * - **Excluding mode** (`upperBound > lowerBound`): Navigate on the whole range EXCLUDING the range from lowerBound to upperBound (inclusive) * - Example: upperBound: (2,50), lowerBound: (2,1) - navigate everywhere except verses 1-50 of Sura 2 * * ## Iteration Behavior * When the navigator reaches the `lowerBound`: * 1. If `remainingIterations > 0`: increment iteration count and reset to `upperBound` * 2. If `remainingIterations = 0`: return `undefined` (stop navigation) */ class NavigationBounds { /** * Creates a new `NavigationBounds` with specified iteration limit and positions. * * @param iterationLimit - Maximum number of complete cycles through the range * @param upperBound - Upper bound for navigation * @param lowerBound - Lower bound for navigation * * ## Bounds Behavior * - When `upperBound < lowerBound`: Navigate from upperBound to lowerBound (inclusive) * - When `upperBound > lowerBound`: Navigate on the whole range EXCLUDING the range from lowerBound to upperBound (inclusive) * * @example * ```typescript * // Inclusive mode: navigate from (1,1) to (1,7) - entire Al-Fatiha * const bounds = new NavigationBounds( * 0, * new VersePosition(1, 1), // upperBound * new VersePosition(1, 7) // lowerBound * ); * * // Exclude a range: navigate everywhere except from (2, 1) to (2, 50) * const bounds = new NavigationBounds( * 0, * new VersePosition(2, 50), // upperBound > lowerBound * new VersePosition(2, 1) // lowerBound * ); * ``` */ constructor(iterationLimit, upperBound, lowerBound) { this.iterationLimit = iterationLimit; this.upperBound = upperBound; this.lowerBound = lowerBound; } /** * Checks if the bounds are in excluding mode. * * @returns `true` - Excluding mode (upperBound > lowerBound): navigate everywhere except the excluded range * @returns `false` - Inclusive mode (upperBound <= lowerBound): navigate within the range * * @note * Excluding mode currently only works correctly with `Direction.Downwards`. * `Direction.Upwards` uses per-sura forward navigation and doesn't support * verse-by-verse backwards navigation through excluded ranges. * * @example * ```typescript * // Inclusive mode * const inclusive = new NavigationBounds(0, new VersePosition(1, 1), new VersePosition(114, 6)); * console.log(inclusive.isExcludingMode()); // false * * // Excluding mode * const excluding = new NavigationBounds(0, new VersePosition(2, 50), new VersePosition(2, 1)); * console.log(excluding.isExcludingMode()); // true * ``` */ isExcludingMode() { return (this.upperBound.getSura() > this.lowerBound.getSura() || (this.upperBound.getSura() === this.lowerBound.getSura() && this.upperBound.getVerse() > this.lowerBound.getVerse())); } /** * Creates default bounds with no iteration limit and full Quran range. * * - `iterationLimit`: 0 (no cycling) * - `upperBound`: (1, 1) - beginning of Al-Fatiha * - `lowerBound`: (114, 6) - end of An-Nas */ static default() { return new NavigationBounds(0, versePosition_1.VersePosition.start(), versePosition_1.VersePosition.end()); } /** * Get the iteration limit * * @returns The iteration limit */ getIterationLimit() { return this.iterationLimit; } /** * Get the upper bound * * @returns The upper bound position */ getUpperBound() { return this.upperBound; } /** * Get the lower bound * * @returns The lower bound position */ getLowerBound() { return this.lowerBound; } } exports.NavigationBounds = NavigationBounds;