# `sequence` — alphanumeric sequence matcher _(no submodules)_ ## Purpose Detects ascending and descending runs of consecutive characters within a single alphabet class (lowercase letters, uppercase letters, decimal digits) per Wheeler §3.2. A run of `abcd` carries far less entropy than four random letters and the scorer needs an explicit pattern record to compute the right guesses count. ## Features - Lower, upper, and digit alphabets - Both directions (ascending `1234`, descending `9876`) - Minimum length 2 - Each match carries `sequenceSpace` (size of the alphabet) and `ascending` ## Usage: Basic Example ```ts import { sequenceMatch } from "@suaveplan/password-strength/matchers/sequence"; const matches = sequenceMatch("abcd"); console.log(matches[0].ascending); // true console.log(matches[0].sequenceName); // "lower" ``` ## Usage: Advanced Example ```ts import { sequenceMatch } from "@suaveplan/password-strength/matchers/sequence"; // Mixed runs are reported separately for (const m of sequenceMatch("abc987XYZ")) { console.log(m.token, m.sequenceName, m.ascending); } // abc lower true // 987 digits false // XYZ upper true ``` ## API Reference - `sequenceMatch(password: string): SequenceMatch[]` — return every maximal ascending or descending run of length ≥ 2 within a single alphabet class. ## Implementation Notes The walk is single-pass: at each index, the matcher checks the delta between adjacent characters; if it is `+1` or `-1` within the same alphabet, the matcher extends the run greedily until the delta breaks or the alphabet changes. Runs of length 1 are filtered out. The algorithm is `O(n)` over the password length and emits each maximal run exactly once. ## Additional Implementation Notes The implementation follows the canonical zxcvbn algorithm from Wheeler 2016 with the suaveplan-style additions described in the package proposal: structured error codes via the `defineCodes` registry, Zod boundaries at every public entry point, OTel histograms and counters keyed to low-cardinality attributes, and a strict input-length guard at 200 characters. Consumers integrate with their existing observability stack by installing a meter provider before importing the package, and with their i18n stack via the `MessageResolver` callback type declared in `@suaveplan/types`. The bundled data tables are intentionally small to keep the package bundle compact; production deployments should swap in fuller frequency-ranked tables via `loadDictionaries`. The default English dictionary set is a frozen `DictionarySet` that the matcher never mutates; caller-supplied dictionaries override defaults by name.