lens-content-processor 0.33.0 → 0.35.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 (61) hide show
  1. package/dist/authoring-markup.d.ts +26 -1
  2. package/dist/authoring-markup.js +67 -16
  3. package/dist/authoring-markup.js.map +1 -1
  4. package/dist/bundler/article.d.ts +69 -9
  5. package/dist/bundler/article.js +159 -58
  6. package/dist/bundler/article.js.map +1 -1
  7. package/dist/content-schema.d.ts +3 -1
  8. package/dist/content-schema.js +51 -12
  9. package/dist/content-schema.js.map +1 -1
  10. package/dist/dedupe-errors.js +1 -7
  11. package/dist/dedupe-errors.js.map +1 -1
  12. package/dist/flattener/index.d.ts +23 -0
  13. package/dist/flattener/index.js +379 -262
  14. package/dist/flattener/index.js.map +1 -1
  15. package/dist/index.d.ts +29 -2
  16. package/dist/index.js +84 -15
  17. package/dist/index.js.map +1 -1
  18. package/dist/parser/article.js +13 -5
  19. package/dist/parser/article.js.map +1 -1
  20. package/dist/parser/course.js +19 -6
  21. package/dist/parser/course.js.map +1 -1
  22. package/dist/parser/learning-outcome.d.ts +0 -1
  23. package/dist/parser/learning-outcome.js +55 -18
  24. package/dist/parser/learning-outcome.js.map +1 -1
  25. package/dist/parser/lens.d.ts +6 -1
  26. package/dist/parser/lens.js +47 -41
  27. package/dist/parser/lens.js.map +1 -1
  28. package/dist/parser/module.js +9 -5
  29. package/dist/parser/module.js.map +1 -1
  30. package/dist/parser/response-segments.d.ts +54 -0
  31. package/dist/parser/response-segments.js +499 -0
  32. package/dist/parser/response-segments.js.map +1 -0
  33. package/dist/parser/survey.js +56 -15
  34. package/dist/parser/survey.js.map +1 -1
  35. package/dist/validator/article-structure.js +4 -18
  36. package/dist/validator/article-structure.js.map +1 -1
  37. package/dist/validator/directives.js +20 -42
  38. package/dist/validator/directives.js.map +1 -1
  39. package/dist/validator/emphasis.js +34 -55
  40. package/dist/validator/emphasis.js.map +1 -1
  41. package/dist/validator/html-tags.js +111 -103
  42. package/dist/validator/html-tags.js.map +1 -1
  43. package/dist/validator/markdown-parse.d.ts +3 -0
  44. package/dist/validator/markdown-parse.js +22 -0
  45. package/dist/validator/markdown-parse.js.map +1 -0
  46. package/dist/validator/output-integrity.d.ts +1 -1
  47. package/dist/validator/output-integrity.js +17 -23
  48. package/dist/validator/output-integrity.js.map +1 -1
  49. package/dist/validator/segment-fields.d.ts +4 -2
  50. package/dist/validator/segment-fields.js +27 -5
  51. package/dist/validator/segment-fields.js.map +1 -1
  52. package/dist/validator/test-segments.d.ts +11 -0
  53. package/dist/validator/test-segments.js +45 -0
  54. package/dist/validator/test-segments.js.map +1 -1
  55. package/dist/validator/uuid.d.ts +1 -2
  56. package/dist/validator/uuid.js +4 -6
  57. package/dist/validator/uuid.js.map +1 -1
  58. package/dist/validator/video-imports.d.ts +35 -0
  59. package/dist/validator/video-imports.js +183 -0
  60. package/dist/validator/video-imports.js.map +1 -0
  61. package/package.json +1 -1
@@ -21,10 +21,9 @@ export function validateUuids(entries) {
21
21
  if (!isValidUuid(entry.uuid)) {
22
22
  errors.push({
23
23
  file: entry.file,
24
- line: entry.line,
25
24
  message: `Invalid UUID format for ${entry.field}: '${entry.uuid}'`,
26
- suggestion: 'UUID must be in format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12 hex characters)',
27
- severity: 'error',
25
+ suggestion: "UUID must be in format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12 hex characters)",
26
+ severity: "error",
28
27
  });
29
28
  continue; // Skip duplicate check for invalid UUIDs
30
29
  }
@@ -35,10 +34,9 @@ export function validateUuids(entries) {
35
34
  if (existing.file !== entry.file || existing.field !== entry.field) {
36
35
  errors.push({
37
36
  file: entry.file,
38
- line: entry.line,
39
37
  message: `Duplicate UUID '${entry.uuid}' - also used in ${existing.file} (${existing.field})`,
40
- suggestion: 'Each UUID must be unique across the entire vault',
41
- severity: 'error',
38
+ suggestion: "Each UUID must be unique across the entire vault",
39
+ severity: "error",
42
40
  });
43
41
  }
44
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/validator/uuid.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,UAAU,GAAG,iEAAiE,CAAC;AAErF;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAaD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAoB;IAChD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC,CAAC,2BAA2B;IAE3E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAE3C,oBAAoB;QACpB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,2BAA2B,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,IAAI,GAAG;gBAClE,UAAU,EAAE,0FAA0F;gBACtG,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,SAAS,CAAC,yCAAyC;QACrD,CAAC;QAED,sBAAsB;QACtB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,0FAA0F;YAC1F,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;gBACnE,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,mBAAmB,KAAK,CAAC,IAAI,oBAAoB,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,GAAG;oBAC7F,UAAU,EAAE,kDAAkD;oBAC9D,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/validator/uuid.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,UAAU,GACd,iEAAiE,CAAC;AAEpE;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAYD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAoB;IAChD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC,CAAC,2BAA2B;IAE3E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAE3C,oBAAoB;QACpB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,2BAA2B,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,IAAI,GAAG;gBAClE,UAAU,EACR,0FAA0F;gBAC5F,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,SAAS,CAAC,yCAAyC;QACrD,CAAC;QAED,sBAAsB;QACtB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,0FAA0F;YAC1F,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;gBACnE,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,mBAAmB,KAAK,CAAC,IAAI,oBAAoB,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,GAAG;oBAC7F,UAAU,EAAE,kDAAkD;oBAC9D,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { ContentError } from "../index.js";
2
+ export interface VideoImportSyntax {
3
+ /** Wikilink target, e.g. "../video_transcripts/name" */
4
+ target: string;
5
+ from?: string;
6
+ to?: string;
7
+ }
8
+ export type VideoImportParse = {
9
+ kind: "import";
10
+ import: VideoImportSyntax;
11
+ } | {
12
+ kind: "invalid";
13
+ reason: string;
14
+ suggestion: string;
15
+ } | {
16
+ kind: "none";
17
+ };
18
+ /**
19
+ * Classify a single line of article body text.
20
+ * - "import": a valid own-line ::video import
21
+ * - "invalid": an attempted import with broken syntax
22
+ * - "none": not a video import at all
23
+ */
24
+ export declare function parseVideoImportLine(line: string): VideoImportParse;
25
+ /**
26
+ * Parse-time validation of ::video imports in an article body.
27
+ * Resolution errors (missing transcript file, bad range) are reported later
28
+ * by the flattener, which has the file map.
29
+ */
30
+ export declare function validateVideoImports(body: string, file: string, bodyStartLine: number): ContentError[];
31
+ /**
32
+ * Lens text segments do not resolve ::video imports — catch attempts there
33
+ * with a pointer to the supported mechanisms.
34
+ */
35
+ export declare function validateNoVideoImportsInLensText(content: string, file: string, line: number): ContentError[];
@@ -0,0 +1,183 @@
1
+ import { parseTimestamp } from "../bundler/video.js";
2
+ // ::video{attr}[[path|alias]] or ::video[[path|alias]]{attr}, anchored to a
3
+ // full (trimmed) line. Alias is accepted for wikilink-tooling compatibility
4
+ // but unused — the display title comes from the transcript frontmatter.
5
+ const VIDEO_IMPORT_LINE_RE = /^::video(?:\{([^}]*)\})?\[\[([^\]|]+)(?:\|[^\]]+)?\]\](?:\{([^}]*)\})?$/;
6
+ // Anything that looks like an attempted ::video import (used to flag
7
+ // malformed/misplaced usages without false-positives on prose that merely
8
+ // mentions "::video").
9
+ const VIDEO_IMPORT_CANDIDATE_RE = /::video[[{]/;
10
+ // CommonMark permits up to three leading spaces before a fenced code block.
11
+ const CODE_FENCE = /^ {0,3}(?:```|~~~)/;
12
+ const CONTAINER_OPEN = /^(:{3,})([\w-]+)/;
13
+ const CONTAINER_CLOSE = /^(:{3,})\s*(?:\{[^}]*\})?\s*$/;
14
+ /** Parse `from="..." to="..."` attribute text. */
15
+ function parseAttrs(attr) {
16
+ if (attr === undefined || attr.trim() === "")
17
+ return {};
18
+ const tokens = [...attr.matchAll(/([\w-]+)\s*=\s*"([^"]*)"/g)];
19
+ const consumed = tokens.map((m) => m[0]).join(" ");
20
+ if (consumed.replace(/\s+/g, " ").trim() !== attr.replace(/\s+/g, " ").trim()) {
21
+ return {
22
+ reason: `invalid attributes '{${attr}}'`,
23
+ suggestion: 'Use key="value" attributes: from and/or to',
24
+ };
25
+ }
26
+ const result = {};
27
+ for (const token of tokens) {
28
+ const key = token[1];
29
+ const value = token[2];
30
+ if (key !== "from" && key !== "to") {
31
+ return {
32
+ reason: `unrecognized attribute '${key}'`,
33
+ suggestion: "Only from and to attributes are supported",
34
+ };
35
+ }
36
+ if (result[key] !== undefined) {
37
+ return {
38
+ reason: `duplicate attribute '${key}'`,
39
+ suggestion: `Keep only one ${key} attribute`,
40
+ };
41
+ }
42
+ if (parseTimestamp(value) === null) {
43
+ return {
44
+ reason: `invalid timestamp in '${key}="${value}"'`,
45
+ suggestion: "Use M:SS (e.g. 1:30) or H:MM:SS (e.g. 1:30:00)",
46
+ };
47
+ }
48
+ result[key] = value;
49
+ }
50
+ return result;
51
+ }
52
+ /**
53
+ * Classify a single line of article body text.
54
+ * - "import": a valid own-line ::video import
55
+ * - "invalid": an attempted import with broken syntax
56
+ * - "none": not a video import at all
57
+ */
58
+ export function parseVideoImportLine(line) {
59
+ const trimmed = line.trim();
60
+ if (!VIDEO_IMPORT_CANDIDATE_RE.test(trimmed))
61
+ return { kind: "none" };
62
+ const match = trimmed.match(VIDEO_IMPORT_LINE_RE);
63
+ if (!match) {
64
+ if (trimmed.startsWith("::video")) {
65
+ return {
66
+ kind: "invalid",
67
+ reason: "malformed ::video import",
68
+ suggestion: 'Use ::video[[../video_transcripts/name]] with optional {from="1:30" to="4:10"}, alone on its own line',
69
+ };
70
+ }
71
+ // ::video appears mid-line — an import buried in prose.
72
+ return {
73
+ kind: "invalid",
74
+ reason: "::video import must be alone on its own line",
75
+ suggestion: "Move the ::video[[...]] import to its own line",
76
+ };
77
+ }
78
+ const preAttr = match[1];
79
+ const target = match[2].trim();
80
+ const postAttr = match[3];
81
+ if (preAttr !== undefined && postAttr !== undefined) {
82
+ return {
83
+ kind: "invalid",
84
+ reason: "attributes given both before and after the wikilink",
85
+ suggestion: "Use a single {from=... to=...} block after the ]]",
86
+ };
87
+ }
88
+ const attrs = parseAttrs(preAttr ?? postAttr);
89
+ if ("reason" in attrs) {
90
+ return { kind: "invalid", reason: attrs.reason, suggestion: attrs.suggestion };
91
+ }
92
+ if (target === "") {
93
+ return {
94
+ kind: "invalid",
95
+ reason: "empty wikilink target",
96
+ suggestion: "Reference a transcript: ::video[[../video_transcripts/name]]",
97
+ };
98
+ }
99
+ return { kind: "import", import: { target, ...attrs } };
100
+ }
101
+ /**
102
+ * Parse-time validation of ::video imports in an article body.
103
+ * Resolution errors (missing transcript file, bad range) are reported later
104
+ * by the flattener, which has the file map.
105
+ */
106
+ export function validateVideoImports(body, file, bodyStartLine) {
107
+ const errors = [];
108
+ const lines = body.split("\n");
109
+ let inCodeBlock = false;
110
+ // Names of open container directives, innermost last. Imports inside
111
+ // hide/collapse would silently vanish from rendered output (the collapsed
112
+ // string strips them), so they are rejected outright.
113
+ const containerStack = [];
114
+ for (let i = 0; i < lines.length; i++) {
115
+ const line = lines[i];
116
+ const absLine = bodyStartLine + i;
117
+ if (CODE_FENCE.test(line)) {
118
+ inCodeBlock = !inCodeBlock;
119
+ continue;
120
+ }
121
+ if (inCodeBlock)
122
+ continue;
123
+ const openMatch = line.match(CONTAINER_OPEN);
124
+ if (openMatch) {
125
+ containerStack.push(openMatch[2]);
126
+ continue;
127
+ }
128
+ if (CONTAINER_CLOSE.test(line)) {
129
+ containerStack.pop();
130
+ continue;
131
+ }
132
+ const parsed = parseVideoImportLine(line);
133
+ if (parsed.kind === "none")
134
+ continue;
135
+ if (parsed.kind === "invalid") {
136
+ const notOwnLine = parsed.reason.includes("own line");
137
+ errors.push({
138
+ file,
139
+ line: absLine,
140
+ code: notOwnLine
141
+ ? "article.video-import-not-own-line"
142
+ : "article.video-import-invalid",
143
+ message: `Invalid ::video import: ${parsed.reason}`,
144
+ suggestion: parsed.suggestion,
145
+ severity: "error",
146
+ });
147
+ continue;
148
+ }
149
+ const hiddenIn = containerStack.find((name) => name === "hide" || name === "collapse");
150
+ if (hiddenIn) {
151
+ errors.push({
152
+ file,
153
+ line: absLine,
154
+ code: "article.video-import-in-hide",
155
+ message: `::video import inside a ':::${hiddenIn}' container`,
156
+ suggestion: "Move the import outside the hidden block — hidden text is collapsed and the video would never render",
157
+ severity: "error",
158
+ });
159
+ }
160
+ }
161
+ return errors;
162
+ }
163
+ /**
164
+ * Lens text segments do not resolve ::video imports — catch attempts there
165
+ * with a pointer to the supported mechanisms.
166
+ */
167
+ export function validateNoVideoImportsInLensText(content, file, line) {
168
+ const errors = [];
169
+ const lines = content.split("\n");
170
+ for (let i = 0; i < lines.length; i++) {
171
+ if (VIDEO_IMPORT_CANDIDATE_RE.test(lines[i])) {
172
+ errors.push({
173
+ file,
174
+ line: line + i,
175
+ message: "::video imports are only supported in article bodies",
176
+ suggestion: "Use a '#### Video' segment in the lens, or move the import into the article file",
177
+ severity: "error",
178
+ });
179
+ }
180
+ }
181
+ return errors;
182
+ }
183
+ //# sourceMappingURL=video-imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-imports.js","sourceRoot":"","sources":["../../src/validator/video-imports.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,4EAA4E;AAC5E,4EAA4E;AAC5E,wEAAwE;AACxE,MAAM,oBAAoB,GACxB,yEAAyE,CAAC;AAE5E,qEAAqE;AACrE,0EAA0E;AAC1E,uBAAuB;AACvB,MAAM,yBAAyB,GAAG,aAAa,CAAC;AAEhD,4EAA4E;AAC5E,MAAM,UAAU,GAAG,oBAAoB,CAAC;AACxC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAC1C,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAcxD,kDAAkD;AAClD,SAAS,UAAU,CACjB,IAAwB;IAExB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,IACE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EACzE,CAAC;QACD,OAAO;YACL,MAAM,EAAE,wBAAwB,IAAI,IAAI;YACxC,UAAU,EAAE,4CAA4C;SACzD,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAmC,EAAE,CAAC;IAClD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACnC,OAAO;gBACL,MAAM,EAAE,2BAA2B,GAAG,GAAG;gBACzC,UAAU,EAAE,2CAA2C;aACxD,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO;gBACL,MAAM,EAAE,wBAAwB,GAAG,GAAG;gBACtC,UAAU,EAAE,iBAAiB,GAAG,YAAY;aAC7C,CAAC;QACJ,CAAC;QACD,IAAI,cAAc,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;YACnC,OAAO;gBACL,MAAM,EAAE,yBAAyB,GAAG,KAAK,KAAK,IAAI;gBAClD,UAAU,EAAE,gDAAgD;aAC7D,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEtE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAClC,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,0BAA0B;gBAClC,UAAU,EACR,uGAAuG;aAC1G,CAAC;QACJ,CAAC;QACD,wDAAwD;QACxD,OAAO;YACL,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,8CAA8C;YACtD,UAAU,EAAE,gDAAgD;SAC7D,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpD,OAAO;YACL,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,qDAAqD;YAC7D,UAAU,EAAE,mDAAmD;SAChE,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC,CAAC;IAC9C,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;IACjF,CAAC;IACD,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO;YACL,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,uBAAuB;YAC/B,UAAU,EAAE,8DAA8D;SAC3E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,CAAC;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,IAAY,EACZ,aAAqB;IAErB,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,qEAAqE;IACrE,0EAA0E;IAC1E,sDAAsD;IACtD,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,OAAO,GAAG,aAAa,GAAG,CAAC,CAAC;QAElC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,WAAW,GAAG,CAAC,WAAW,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IAAI,WAAW;YAAE,SAAS;QAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACd,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,SAAS;QACX,CAAC;QACD,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,cAAc,CAAC,GAAG,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QACrC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACtD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,UAAU;oBACd,CAAC,CAAC,mCAAmC;oBACrC,CAAC,CAAC,8BAA8B;gBAClC,OAAO,EAAE,2BAA2B,MAAM,CAAC,MAAM,EAAE;gBACnD,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAClC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU,CACjD,CAAC;QACF,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,8BAA8B;gBACpC,OAAO,EAAE,+BAA+B,QAAQ,aAAa;gBAC7D,UAAU,EACR,sGAAsG;gBACxG,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gCAAgC,CAC9C,OAAe,EACf,IAAY,EACZ,IAAY;IAEZ,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,IAAI,GAAG,CAAC;gBACd,OAAO,EAAE,sDAAsD;gBAC/D,UAAU,EACR,kFAAkF;gBACpF,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lens-content-processor",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "Parser and validator for Lens educational content (Markdown modules, lenses, learning outcomes)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",