# domain/converters/evidence.converter.ts

> 41 lines of code and 12 definitions.

Tree: Site tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/tree#file-domain-converters-evidence-converter-ts
Source text: https://banes-lab.com/assets/sources/source.0dbb89c8589fa6555f0298f08ef84cfcdbde648c1a7dbe7a1d310ff2de49b85f.generated.txt

## Definitions

- `isChapterOf` (lexical_declaration, line 18)
- `subjectMatches` (lexical_declaration, line 24, exported)
- `chapterEdge` (lexical_declaration, line 39, exported)
- `evidenceFor` (lexical_declaration, line 32, exported)
- `CHAPTER_PREFIX` (lexical_declaration, line 10)
- `chapterHref` (lexical_declaration, line 12)
- `cut` (lexical_declaration, line 19)
- `section` (lexical_declaration, line 20)
- `href` (lexical_declaration, line 28, exported)
- `head` (lexical_declaration, line 40, exported)
- `tail` (lexical_declaration, line 41, exported)
- `entry` (lexical_declaration, line 42, exported)

## Uses

- [core/assets/link.assets.ts](https://banes-lab.com/source/tree/core/assets/link.assets.ts.md)

## Used by

- [domain/loaders/evidence.loader.ts](https://banes-lab.com/source/tree/domain/loaders/evidence.loader.ts.md)

## Source

```typescript
import { CHAPTER_FACE, CHAPTER_KIND } from "#configuration/constants/vocabulary.constants";
import type { ChapterSubject, Evidence, EvidenceSubject } from "#types/evidence.types";
import { pageFromPath, pagePath } from "#assets/link.assets";
import { ANCHOR_PREFIX } from "#configuration/constants/document.constants";
import type { EdgeRef } from "#types/link.types";
import { FACE_SEPARATOR } from "@govlab/constants";
import type { ReferenceTarget } from "#types/reference.types";
import { SITE_VOCABULARY } from "#configuration/strings/site.strings";

const CHAPTER_PREFIX = CHAPTER_FACE + FACE_SEPARATOR;

const chapterHref = function chapterHref(target: ReferenceTarget): string | null {
    return target.face === CHAPTER_FACE && target.ref.startsWith(CHAPTER_PREFIX)
        ? target.ref.slice(CHAPTER_PREFIX.length)
        : null;
};

const isChapterOf = function isChapterOf(subject: ChapterSubject, href: string): boolean {
    const cut = href.indexOf(ANCHOR_PREFIX);
    const section = cut === -1 ? "" : href.slice(cut + ANCHOR_PREFIX.length);
    return section === subject.section && pageFromPath(href, "") === subject.page;
};

export const subjectMatches = function subjectMatches(subject: EvidenceSubject, target: ReferenceTarget): boolean {
    if (subject.kind === "record") {
        return subject.ref === target.ref;
    }
    const href = chapterHref(target);
    return href !== null && isChapterOf(subject, href);
};

export const evidenceFor = function evidenceFor(
    target: ReferenceTarget,
    registry: readonly Evidence[],
): readonly Evidence[] {
    return registry.filter((entry) => subjectMatches(entry.subject, target));
};

export const chapterEdge = function chapterEdge(subject: ChapterSubject): EdgeRef | null {
    const head = CHAPTER_PREFIX + pagePath(subject.page);
    const tail = ANCHOR_PREFIX + subject.section;
    const entry = SITE_VOCABULARY.find(
        (candidate) =>
            candidate.kind === CHAPTER_KIND && candidate.ref.startsWith(head) && candidate.ref.endsWith(tail),
    );
    return entry === undefined ? null : { label: entry.phrase, ref: entry.ref };
};
```
