# tools/core/analyzers/blocking.analyzer.ts

> 47 lines of code and 15 definitions.

Tree: Coordination tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-analyzers-blocking-analyzer-ts
Source text: https://banes-lab.com/assets/sources/source.1ae0537dd64258c06cf26720ff44933986af29d113a6cdf472af0eff331df726.generated.txt

## Definitions

- `nextWidth` (lexical_declaration, line 34)
- `ungatedRows` (lexical_declaration, line 41, exported)
- `isSeparator` (lexical_declaration, line 18)
- `UngatedRow` (interface_declaration, line 1, exported)
- `CELL` (lexical_declaration, line 6)
- `cellsOf` (lexical_declaration, line 8)
- `trimmed` (lexical_declaration, line 9)
- `parts` (lexical_declaration, line 14)
- `ungatedRow` (lexical_declaration, line 29)
- `gated` (lexical_declaration, line 30)
- `rows` (lexical_declaration, line 42, exported)
- `width` (lexical_declaration, line 43, exported)
- `cells` (lexical_declaration, line 46, exported)
- `body` (lexical_declaration, line 47, exported)
- `row` (lexical_declaration, line 48, exported)

## Used by

- [tools/rules/blocking.rule.ts](https://banes-lab.com/source/coordination/tools/rules/blocking.rule.ts.md)

## Source

```typescript
export interface UngatedRow {
    readonly id: string;
    readonly line: number;
}

const CELL = "|";

const cellsOf = function cellsOf(line: string): string[] {
    const trimmed = line.trim();
    if (!trimmed.startsWith(CELL)) {
        return [];
    }

    const parts = trimmed.split(CELL);
    return parts.slice(1, -1).map((part) => part.trim());
};

const isSeparator = function isSeparator(cells: readonly string[]): boolean {
    for (const cell of cells) {
        for (const char of cell) {
            if (char !== "-" && char !== ":" && char !== " ") {
                return false;
            }
        }
    }
    return cells.length > 0;
};

const ungatedRow = function ungatedRow(cells: readonly string[], width: number, index: number): UngatedRow | null {
    const gated = (cells.at(-1) ?? "").length > 0;
    return cells.length === width && !gated ? { id: cells[0] ?? "", line: index + 1 } : null;
};

const nextWidth = function nextWidth(cells: readonly string[], width: number): number {
    if (cells.length === 0) {
        return 0;
    }
    return width !== 0 || isSeparator(cells) ? width : cells.length;
};

export const ungatedRows = function ungatedRows(source: string): UngatedRow[] {
    const rows: UngatedRow[] = [];
    let width = 0;

    for (const [index, line] of source.split("\n").entries()) {
        const cells = cellsOf(line);
        const body = cells.length > 0 && width !== 0 && !isSeparator(cells);
        const row = body ? ungatedRow(cells, width, index) : null;
        width = nextWidth(cells, width);
        if (row !== null) {
            rows.push(row);
        }
    }

    return rows;
};
```
