lens-content-processor 0.50.0 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/bundler/article.d.ts +5 -0
  2. package/dist/bundler/article.js +23 -1
  3. package/dist/bundler/article.js.map +1 -1
  4. package/dist/cli.js +19 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/content-schema.js +21 -6
  7. package/dist/content-schema.js.map +1 -1
  8. package/dist/course-graph.d.ts +2 -0
  9. package/dist/course-graph.js +190 -0
  10. package/dist/course-graph.js.map +1 -0
  11. package/dist/flattener/index.js +18 -4
  12. package/dist/flattener/index.js.map +1 -1
  13. package/dist/glossary.d.ts +38 -0
  14. package/dist/glossary.js +365 -0
  15. package/dist/glossary.js.map +1 -0
  16. package/dist/index.d.ts +21 -2
  17. package/dist/index.js +64 -94
  18. package/dist/index.js.map +1 -1
  19. package/dist/markdown-parse.d.ts +5 -0
  20. package/dist/markdown-parse.js +33 -0
  21. package/dist/markdown-parse.js.map +1 -0
  22. package/dist/parser/course.js +54 -3
  23. package/dist/parser/course.js.map +1 -1
  24. package/dist/parser/lens.d.ts +3 -1
  25. package/dist/parser/lens.js +4 -1
  26. package/dist/parser/lens.js.map +1 -1
  27. package/dist/parser/meeting-doc.d.ts +14 -0
  28. package/dist/parser/meeting-doc.js +230 -0
  29. package/dist/parser/meeting-doc.js.map +1 -0
  30. package/dist/parser/response-segments.d.ts +2 -2
  31. package/dist/parser/response-segments.js +39 -4
  32. package/dist/parser/response-segments.js.map +1 -1
  33. package/dist/parser/survey.js +9 -0
  34. package/dist/parser/survey.js.map +1 -1
  35. package/dist/reference-graph.d.ts +3 -0
  36. package/dist/reference-graph.js +11 -7
  37. package/dist/reference-graph.js.map +1 -1
  38. package/dist/same-page-links.js +3 -18
  39. package/dist/same-page-links.js.map +1 -1
  40. package/dist/validator/article-structure.js +1 -1
  41. package/dist/validator/article-structure.js.map +1 -1
  42. package/dist/validator/emphasis.js +1 -1
  43. package/dist/validator/emphasis.js.map +1 -1
  44. package/dist/validator/same-lens-links.js +3 -15
  45. package/dist/validator/same-lens-links.js.map +1 -1
  46. package/dist/validator/test-segments.js +1 -1
  47. package/package.json +1 -1
  48. package/dist/validator/markdown-parse.d.ts +0 -3
  49. package/dist/validator/markdown-parse.js +0 -22
  50. package/dist/validator/markdown-parse.js.map +0 -1
@@ -0,0 +1,365 @@
1
+ import { parseMarkdown } from "./markdown-parse.js";
2
+ import { stripAuthoringMarkup } from "./authoring-markup.js";
3
+ import { parseFrontmatter } from "./parser/frontmatter.js";
4
+ import { findFileWithExtension, parseWikilink, resolveWikilinkPath, } from "./parser/wikilink.js";
5
+ import { validateFrontmatter } from "./validator/validate-frontmatter.js";
6
+ import { checkTierViolation } from "./validator/tier.js";
7
+ export function isGlossaryPath(path) {
8
+ return path.startsWith("glossary/") || path.includes("/glossary/");
9
+ }
10
+ function termFromPath(path) {
11
+ return (path.split("/").pop() ?? path).replace(/\.md$/, "");
12
+ }
13
+ export function parseGlossaryEntry(content, file) {
14
+ const errors = [];
15
+ const stripped = stripAuthoringMarkup(content);
16
+ // An entry with no aliases needs no frontmatter: the whole file is the definition.
17
+ const parsed = /^---\r?\n/.test(stripped)
18
+ ? parseFrontmatter(stripped, file)
19
+ : { frontmatter: {}, body: stripped, bodyStartLine: 1 };
20
+ if ("error" in parsed && parsed.error) {
21
+ return { entry: null, errors: [parsed.error] };
22
+ }
23
+ const { frontmatter, body, bodyStartLine } = parsed;
24
+ errors.push(...validateFrontmatter(frontmatter, "glossary", file));
25
+ const fail = (message, suggestion, line = bodyStartLine) => {
26
+ errors.push({ file, line, message, suggestion, severity: "error" });
27
+ return { entry: null, errors };
28
+ };
29
+ const aliases = frontmatter.aliases ?? [];
30
+ if (!Array.isArray(aliases) ||
31
+ !aliases.every((a) => typeof a === "string" && a.trim())) {
32
+ return fail("Field 'aliases' must be a list of phrases", 'Write one phrase per line, e.g.\naliases:\n - "artificial general intelligence"', 2);
33
+ }
34
+ const definition = body.trim();
35
+ if (!definition) {
36
+ return fail("Glossary entry has no definition", "Write the definition below the frontmatter, in one or two sentences");
37
+ }
38
+ if (/^#{1,6}\s/m.test(definition)) {
39
+ return fail("A glossary definition cannot contain a heading", "Definitions show in a small popup; keep them to plain sentences");
40
+ }
41
+ return {
42
+ entry: {
43
+ term: termFromPath(file),
44
+ aliases: aliases.map((a) => a.trim()),
45
+ definition,
46
+ },
47
+ errors,
48
+ };
49
+ }
50
+ /** A phrase may belong to one entry only, or a highlight could not say which. */
51
+ export function validateGlossaryAliases(entries) {
52
+ const owner = new Map();
53
+ const errors = [];
54
+ for (const [path, entry] of entries) {
55
+ for (const phrase of phrasesOf(entry)) {
56
+ const key = normalizeApostrophes(phrase.toLowerCase());
57
+ const first = owner.get(key);
58
+ if (first === undefined) {
59
+ owner.set(key, path);
60
+ }
61
+ else if (first !== path) {
62
+ errors.push({
63
+ file: path,
64
+ message: `Glossary phrase "${phrase}" is already used by ${first}`,
65
+ suggestion: "Remove the phrase from one of the two entries (phrases differing only in case also clash)",
66
+ severity: "error",
67
+ });
68
+ }
69
+ }
70
+ }
71
+ return errors;
72
+ }
73
+ function phrasesOf(entry) {
74
+ return [entry.term, ...entry.aliases];
75
+ }
76
+ function normalizeApostrophes(text) {
77
+ return text.replace(/[’‘]/g, "'");
78
+ }
79
+ // ─── Applying a lens's glossary_terms ───
80
+ const WORD = String.raw `[\p{L}\p{N}_-]`;
81
+ function compilePhrase(term, phrase) {
82
+ const escaped = normalizeApostrophes(phrase)
83
+ .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
84
+ .replace(/'/g, "['’‘]");
85
+ const capitals = /\p{L}/u.test(phrase) && phrase === phrase.toUpperCase();
86
+ return {
87
+ term,
88
+ pattern: new RegExp(`(?<!${WORD})${escaped}(?!${WORD})`, capitals ? "gu" : "giu"),
89
+ length: phrase.length,
90
+ };
91
+ }
92
+ /** Nodes whose text the learner does not read as running prose. */
93
+ const SKIPPED_NODES = new Set([
94
+ "heading",
95
+ "link",
96
+ "linkReference",
97
+ "inlineCode",
98
+ "code",
99
+ "html",
100
+ "inlineMath",
101
+ "math",
102
+ "footnoteDefinition",
103
+ ]);
104
+ const SKIPPED_DIRECTIVES = new Set(["hide", "collapse", "footnote"]);
105
+ /** Inline markup a term may sit in; the mark then wraps it (see findHits). */
106
+ const EMPHASIS = new Set(["emphasis", "strong", "delete"]);
107
+ function isSkipped(node) {
108
+ if (SKIPPED_NODES.has(node.type))
109
+ return true;
110
+ if (node.type !== "textDirective" &&
111
+ node.type !== "leafDirective" &&
112
+ node.type !== "containerDirective")
113
+ return false;
114
+ return (SKIPPED_DIRECTIVES.has(node.name) ||
115
+ (node.name === "callout" && node.attributes?.collapse === "closed"));
116
+ }
117
+ // Inline raw HTML arrives as separate open and close tag nodes; the text
118
+ // between them (<a>, <code>, <abbr>...) is not running prose either.
119
+ const OPEN_TAG = /^<([a-z][\w-]*)\b[^>]*(?<!\/)>$/i;
120
+ const CLOSE_TAG = /^<\/[a-z][\w-]*\s*>$/i;
121
+ const VOID_TAGS = new Set(["br", "hr", "img", "input", "wbr"]);
122
+ /** Text nodes a learner reads, in document order, with their ancestors. */
123
+ function readableText(tree) {
124
+ const out = [];
125
+ const walk = (node, ancestors) => {
126
+ if (isSkipped(node))
127
+ return;
128
+ if (node.type === "text")
129
+ out.push({ text: node, ancestors });
130
+ if (!("children" in node))
131
+ return;
132
+ let insideTag = 0;
133
+ for (const c of node.children) {
134
+ if (c.type === "html") {
135
+ const open = OPEN_TAG.exec(c.value);
136
+ if (open && !VOID_TAGS.has(open[1].toLowerCase()))
137
+ insideTag++;
138
+ else if (CLOSE_TAG.test(c.value))
139
+ insideTag = Math.max(0, insideTag - 1);
140
+ }
141
+ else if (!insideTag)
142
+ walk(c, [...ancestors, node]);
143
+ }
144
+ };
145
+ walk(tree, []);
146
+ return out;
147
+ }
148
+ // The renderer's inline math rule (web_frontend/src/lib/markdownMath.ts),
149
+ // which the parser here does not apply. A test fails if the two differ.
150
+ export const INLINE_MATH_RE = /(?<!\$)\$(?!\$)([^\s$](?:[^$\n]*?[^\s$])?)\$(?![\d$])/g;
151
+ const ENTITY = /^&(?:#\d+|#x[\da-f]+|[a-z][a-z\d]*);/i;
152
+ /** Source the parser drops from a text node's value, at the cursor. */
153
+ const DROPPED = /^(?:[ \t]+(?=\r?\n)|\\(?=[!-/:-@[-`{-~]))/;
154
+ const LINE_PREFIX = /^[ \t>]+/;
155
+ /**
156
+ * The source offset of each character of a text node's value. The value is
157
+ * not a plain slice of the source: its container drops what starts each line
158
+ * (`> `, list indentation), and escapes and entities are decoded. A character
159
+ * written as an entity has no offset; the walk stops at anything else it
160
+ * cannot place, and later characters have no offset either.
161
+ */
162
+ function sourceOffsets(source, text) {
163
+ const end = text.position?.end.offset ?? 0;
164
+ let cursor = text.position?.start.offset ?? end;
165
+ const offsets = [];
166
+ // By UTF-16 unit, as the offsets are: an emoji is two.
167
+ walk: for (let i = 0; i < text.value.length; i++) {
168
+ while (cursor < end) {
169
+ const rest = source.slice(cursor, cursor + 40);
170
+ // Before the plain comparison: "&amp;" is one "&" of the value. Text
171
+ // that only looks like an entity ("AT&T;") is still in the value.
172
+ const entity = ENTITY.exec(rest);
173
+ if (entity && !text.value.startsWith(entity[0], i)) {
174
+ cursor += entity[0].length;
175
+ continue walk;
176
+ }
177
+ if (source[cursor] === text.value[i]) {
178
+ offsets[i] = cursor++;
179
+ continue walk;
180
+ }
181
+ const dropped = DROPPED.exec(rest) ??
182
+ (source[cursor - 1] === "\n" ? LINE_PREFIX.exec(rest) : null);
183
+ if (!dropped)
184
+ break walk;
185
+ cursor += dropped[0].length;
186
+ }
187
+ break;
188
+ }
189
+ return offsets;
190
+ }
191
+ /**
192
+ * Every non-overlapping occurrence of a phrase in `source`, as source
193
+ * offsets, longest phrase first at each place.
194
+ *
195
+ * The renderer wraps each mark in a `:glossary[...]` directive, so a mark is
196
+ * placed where that directive parses as the same text:
197
+ * - Not inside `$...$` math, and not right after `:` (it would read as
198
+ * `::glossary`) or `\` (an escaped colon). Such a place is still taken,
199
+ * so a shorter phrase inside it is not marked instead.
200
+ * - A term that is all of an emphasis (`**LLM**s`) is marked around the
201
+ * emphasis: a directive inside it would stop the closing `**` from
202
+ * closing. A term that only touches the edge of an emphasis is skipped.
203
+ */
204
+ function findHits(source, phrases, footnotesRunToEnd) {
205
+ const hits = [];
206
+ const tree = parseMarkdown(source, "gfm-directive-math");
207
+ // An article's footnotes render leniently (web_frontend/src/lib/footnotes.ts):
208
+ // everything after the first definition belongs to the notes.
209
+ const end = footnotesRunToEnd
210
+ ? Math.min(...tree.children
211
+ .filter((n) => n.type === "footnoteDefinition")
212
+ .map((n) => n.position?.start.offset ?? Infinity))
213
+ : Infinity;
214
+ for (const { text, ancestors } of readableText(tree)) {
215
+ if ((text.position?.start.offset ?? 0) >= end)
216
+ break;
217
+ const math = [...text.value.matchAll(INLINE_MATH_RE)].map((m) => ({
218
+ start: m.index,
219
+ end: m.index + m[0].length,
220
+ }));
221
+ const offsets = sourceOffsets(source, text);
222
+ const taken = [];
223
+ for (const phrase of phrases) {
224
+ for (const match of text.value.matchAll(phrase.pattern)) {
225
+ const at = { start: match.index, end: match.index + match[0].length };
226
+ if (taken.some((t) => at.start < t.end && t.start < at.end))
227
+ continue;
228
+ const from = offsets[at.start];
229
+ const to = offsets[at.end - 1];
230
+ const inMath = math.some((m) => at.start < m.end && m.start < at.end);
231
+ let mark = null;
232
+ if (from !== undefined &&
233
+ to !== undefined &&
234
+ source.slice(from, to + 1) === match[0] &&
235
+ !inMath) {
236
+ mark = placeMark({ start: from, end: to + 1, term: phrase.term }, text, ancestors);
237
+ if (mark && /[:\\]/.test(source[mark.start - 1] ?? ""))
238
+ mark = null;
239
+ }
240
+ taken.push({ ...at, mark });
241
+ }
242
+ }
243
+ for (const t of taken)
244
+ if (t.mark)
245
+ hits.push(t.mark);
246
+ }
247
+ return hits.sort((a, b) => a.start - b.start);
248
+ }
249
+ /** Widen a mark around the emphasis it fills, or drop one that touches an emphasis edge. */
250
+ function placeMark(mark, text, ancestors) {
251
+ let node = text;
252
+ let covers = mark.start === text.position?.start.offset &&
253
+ mark.end === text.position?.end.offset;
254
+ let widened = mark;
255
+ for (let i = ancestors.length - 1; i >= 0; i--) {
256
+ const parent = ancestors[i];
257
+ if (!EMPHASIS.has(parent.type))
258
+ break;
259
+ const touches = widened.start === node.position?.start.offset ||
260
+ widened.end === node.position?.end.offset;
261
+ if (!touches)
262
+ break;
263
+ if (!covers || parent.children.length !== 1)
264
+ return null;
265
+ const start = parent.position?.start.offset;
266
+ const end = parent.position?.end.offset;
267
+ if (start === undefined || end === undefined)
268
+ return null;
269
+ widened = { ...mark, start, end };
270
+ node = parent;
271
+ covers = true;
272
+ }
273
+ return widened;
274
+ }
275
+ /** Text and article segments, unless they sit in a box that starts closed. */
276
+ function isMarkable(segment) {
277
+ return ((segment.type === "text" || segment.type === "article") &&
278
+ !segment.frames?.some((frame) => frame.collapse === "closed"));
279
+ }
280
+ /**
281
+ * Mark the first occurrence of each term a lens lists in `glossary_terms`.
282
+ * `links` is the raw frontmatter value.
283
+ */
284
+ export function applyGlossary(links, segments, lensPath, files, entriesByPath, tierMap) {
285
+ const errors = [];
286
+ const unchanged = { segments, glossary: [], errors };
287
+ // `glossary_terms:` with nothing under it is an empty list.
288
+ if (links === null)
289
+ return unchanged;
290
+ if (!Array.isArray(links) || !links.every((l) => typeof l === "string")) {
291
+ errors.push({
292
+ file: lensPath,
293
+ message: "Field 'glossary_terms' must be a list of wikilinks",
294
+ suggestion: 'Write one link per line, e.g.\nglossary_terms:\n - "[[../glossary/AGI]]"',
295
+ severity: "error",
296
+ });
297
+ return unchanged;
298
+ }
299
+ const entries = [];
300
+ for (const link of links) {
301
+ const entry = resolveEntry(link, lensPath, files, entriesByPath, tierMap, errors);
302
+ if (entry && !entries.some((e) => e.term === entry.term))
303
+ entries.push(entry);
304
+ }
305
+ const phrases = entries
306
+ .flatMap((entry) => phrasesOf(entry).map((p) => compilePhrase(entry.term, p)))
307
+ .sort((a, b) => b.length - a.length);
308
+ if (phrases.length === 0)
309
+ return unchanged;
310
+ const marked = new Set();
311
+ const out = segments.map((segment) => {
312
+ if (!isMarkable(segment))
313
+ return segment;
314
+ const glossaryMarks = findHits(segment.content, phrases, segment.type === "article").filter((hit) => {
315
+ if (marked.has(hit.term))
316
+ return false;
317
+ marked.add(hit.term);
318
+ return true;
319
+ });
320
+ return glossaryMarks.length ? { ...segment, glossaryMarks } : segment;
321
+ });
322
+ for (const entry of entries) {
323
+ if (!marked.has(entry.term)) {
324
+ errors.push({
325
+ file: lensPath,
326
+ message: `Glossary term "${entry.term}" does not appear in this lens`,
327
+ suggestion: "Remove it from glossary_terms, or add the phrase it is written as to the entry's aliases",
328
+ severity: "warning",
329
+ });
330
+ }
331
+ }
332
+ return {
333
+ segments: out,
334
+ glossary: entries
335
+ .filter((e) => marked.has(e.term))
336
+ .map(({ term, definition }) => ({ term, definition })),
337
+ errors,
338
+ };
339
+ }
340
+ function resolveEntry(link, lensPath, files, entriesByPath, tierMap, errors) {
341
+ const parsed = parseWikilink(link.trim());
342
+ const target = parsed && !parsed.error
343
+ ? findFileWithExtension(resolveWikilinkPath(parsed.path, lensPath), files)
344
+ : null;
345
+ if (!target || !isGlossaryPath(target)) {
346
+ errors.push({
347
+ file: lensPath,
348
+ message: target
349
+ ? `glossary_terms: ${link} is not a glossary entry`
350
+ : `glossary_terms: ${link} could not be resolved`,
351
+ suggestion: "Link to a file in the glossary/ folder, e.g. [[../glossary/AGI]]",
352
+ severity: "error",
353
+ });
354
+ return null;
355
+ }
356
+ const violation = checkTierViolation(lensPath, tierMap?.get(lensPath) ?? "production", target, tierMap?.get(target) ?? "production", "glossary entry");
357
+ if (violation) {
358
+ errors.push(violation);
359
+ return null;
360
+ }
361
+ // An entry that failed to parse is missing here; its own errors are
362
+ // reported once, against the entry.
363
+ return entriesByPath.get(target) ?? null;
364
+ }
365
+ //# sourceMappingURL=glossary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../src/glossary.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,6 +9,12 @@ export interface ProcessResult {
9
9
  modules: FlattenedModule[];
10
10
  courses: Course[];
11
11
  surveys: FlattenedSurvey[];
12
+ /**
13
+ * Meeting-doc Markdown by repo path (meetings/ folder), published text:
14
+ * what the platform renders into a meeting's session-doc template. A
15
+ * meeting's `docPath` is a key of this map.
16
+ */
17
+ meetingDocs?: Record<string, string>;
12
18
  errors: ContentError[];
13
19
  urlsToValidate: UrlToValidate[];
14
20
  skillTree: SkillTree;
@@ -33,6 +39,7 @@ export interface SurveyQuestionSegment {
33
39
  type: "question";
34
40
  key: string;
35
41
  content: string;
42
+ description?: string;
36
43
  required: boolean;
37
44
  maxChars?: number;
38
45
  placeholder?: string;
@@ -42,6 +49,7 @@ export interface SurveyRatingSegment {
42
49
  type: "rating";
43
50
  key: string;
44
51
  content: string;
52
+ description?: string;
45
53
  scale: number;
46
54
  required: boolean;
47
55
  lowLabel?: string;
@@ -52,6 +60,7 @@ export interface SurveyChoiceSegment {
52
60
  type: "choice";
53
61
  key: string;
54
62
  content: string;
63
+ description?: string;
55
64
  options: string[];
56
65
  multi: boolean;
57
66
  required: boolean;
@@ -97,6 +106,9 @@ export interface Course {
97
106
  outcomes?: string;
98
107
  timeCommitment?: string;
99
108
  applicationNotes?: string;
109
+ /** The language the course is written in, a name like `Spanish`; absent =
110
+ * English. The read-aloud reader speaks it (core/tts/config.py). */
111
+ language?: string;
100
112
  error?: string;
101
113
  }
102
114
  /**
@@ -128,7 +140,7 @@ export interface Section {
128
140
  optional?: boolean;
129
141
  hide?: boolean;
130
142
  feedback?: boolean;
131
- forceFeedback?: boolean;
143
+ forceFeedback?: true | "first";
132
144
  contentId: string | null;
133
145
  learningOutcomes: LearningOutcomeRef[];
134
146
  wordCount?: number;
@@ -140,6 +152,8 @@ export interface Section {
140
152
  readingMinutes?: number;
141
153
  tutorMinutes?: number;
142
154
  addToAiContext?: string[] | null;
155
+ glossary?: GlossaryDefinition[];
156
+ glossaryTerms?: unknown;
143
157
  }
144
158
  export interface SectionMeta {
145
159
  title?: string;
@@ -156,6 +170,7 @@ export interface ProgressionItem {
156
170
  facilitatorSurveyPath?: string;
157
171
  facilitatorSurveyId?: string;
158
172
  docTemplateUrl?: string;
173
+ docPath?: string;
159
174
  }
160
175
  export interface ContentError {
161
176
  file: string;
@@ -171,6 +186,7 @@ export interface TextSegment {
171
186
  type: "text";
172
187
  content: string;
173
188
  optional?: boolean;
189
+ glossaryMarks?: GlossaryMark[];
174
190
  }
175
191
  export interface ChatSegment {
176
192
  type: "chat";
@@ -181,6 +197,7 @@ export interface ChatSegment {
181
197
  export interface ArticleSegment {
182
198
  type: "article";
183
199
  content: string;
200
+ glossaryMarks?: GlossaryMark[];
184
201
  collapsed_before?: string;
185
202
  collapsed_after?: string;
186
203
  skipEndMarker?: boolean;
@@ -225,6 +242,7 @@ export interface QuestionSegment {
225
242
  graded: boolean;
226
243
  feedbackInstructions?: string;
227
244
  content: string;
245
+ description?: string;
228
246
  assessmentInstructions?: string;
229
247
  maxTime?: string;
230
248
  maxChars?: number;
@@ -232,7 +250,7 @@ export interface QuestionSegment {
232
250
  placeholder?: string;
233
251
  optional?: boolean;
234
252
  feedback?: boolean;
235
- forceFeedback?: boolean;
253
+ forceFeedback?: true | "first";
236
254
  scale?: number;
237
255
  lowLabel?: string;
238
256
  highLabel?: string;
@@ -318,6 +336,7 @@ export type Segment = (TextSegment | ChatSegment | ArticleSegment | VideoSegment
318
336
  import { type TranscriptSentence } from "./bundler/video.js";
319
337
  export type { TranscriptSentence } from "./bundler/video.js";
320
338
  export { parseWidget, isWidgetPath } from "./parser/widget.js";
339
+ import { type GlossaryDefinition, type GlossaryMark } from "./glossary.js";
321
340
  export type { ContentTier } from "./validator/tier.js";
322
341
  export { checkTierViolation } from "./validator/tier.js";
323
342
  import { type SkillTree } from "./skill-tree.js";