aeoptimize 0.1.1

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.
@@ -0,0 +1,609 @@
1
+ // ── Structure Rules (25 pts) ───────────────────────────────────────
2
+ const headingHierarchy = {
3
+ id: 'heading-hierarchy',
4
+ dimension: 'structure',
5
+ weight: 8,
6
+ evaluate(doc) {
7
+ const issues = [];
8
+ const suggestions = [];
9
+ const { headings } = doc;
10
+ if (headings.length === 0) {
11
+ issues.push({
12
+ dimension: 'structure',
13
+ severity: 'critical',
14
+ message: 'No headings found. AI engines rely on heading structure to understand content hierarchy.',
15
+ });
16
+ return { score: 0, maxScore: 8, issues, suggestions };
17
+ }
18
+ let score = 8;
19
+ // Check for single H1
20
+ const h1s = headings.filter((h) => h.level === 1);
21
+ if (h1s.length === 0) {
22
+ score -= 3;
23
+ issues.push({
24
+ dimension: 'structure',
25
+ severity: 'warning',
26
+ message: 'No H1 heading found. Every page should have exactly one H1.',
27
+ });
28
+ }
29
+ else if (h1s.length > 1) {
30
+ score -= 2;
31
+ issues.push({
32
+ dimension: 'structure',
33
+ severity: 'warning',
34
+ message: `Found ${h1s.length} H1 headings. Use exactly one H1 per page.`,
35
+ });
36
+ }
37
+ // Check for skipped levels (e.g., H1 -> H3)
38
+ for (let i = 1; i < headings.length; i++) {
39
+ const prev = headings[i - 1].level;
40
+ const curr = headings[i].level;
41
+ if (curr > prev + 1) {
42
+ score -= 2;
43
+ issues.push({
44
+ dimension: 'structure',
45
+ severity: 'warning',
46
+ message: `Heading level skipped: H${prev} → H${curr}. This confuses AI content parsing.`,
47
+ });
48
+ break;
49
+ }
50
+ }
51
+ // Check heading count relative to content
52
+ const wordCount = doc.rawText.split(/\s+/).length;
53
+ if (wordCount > 500 && headings.length < 3) {
54
+ score -= 1;
55
+ suggestions.push({
56
+ dimension: 'structure',
57
+ action: 'Add more headings to break up long content',
58
+ impact: 'medium',
59
+ detail: `${wordCount} words with only ${headings.length} headings. Aim for one heading per 200-300 words.`,
60
+ });
61
+ }
62
+ return { score: Math.max(0, score), maxScore: 8, issues, suggestions };
63
+ },
64
+ };
65
+ const paragraphLength = {
66
+ id: 'paragraph-length',
67
+ dimension: 'structure',
68
+ weight: 7,
69
+ evaluate(doc) {
70
+ const issues = [];
71
+ const suggestions = [];
72
+ const { paragraphs } = doc;
73
+ if (paragraphs.length === 0) {
74
+ return { score: 0, maxScore: 7, issues: [{ dimension: 'structure', severity: 'warning', message: 'No paragraphs detected.' }], suggestions };
75
+ }
76
+ const longParagraphs = paragraphs.filter((p) => p.split(/\s+/).length > 150);
77
+ const ratio = longParagraphs.length / paragraphs.length;
78
+ let score = 7;
79
+ if (ratio > 0.5) {
80
+ score -= 5;
81
+ issues.push({
82
+ dimension: 'structure',
83
+ severity: 'critical',
84
+ message: `${longParagraphs.length}/${paragraphs.length} paragraphs exceed 150 words. LLMs struggle to extract citable quotes from long paragraphs.`,
85
+ });
86
+ }
87
+ else if (ratio > 0.2) {
88
+ score -= 3;
89
+ issues.push({
90
+ dimension: 'structure',
91
+ severity: 'warning',
92
+ message: `${longParagraphs.length} paragraphs exceed 150 words. Split them for better AI citability.`,
93
+ });
94
+ }
95
+ if (longParagraphs.length > 0) {
96
+ suggestions.push({
97
+ dimension: 'structure',
98
+ action: 'Split long paragraphs into self-contained statements',
99
+ impact: 'high',
100
+ detail: 'Ideal paragraph length for AI extraction: 40-80 words. Each paragraph should express one complete idea.',
101
+ });
102
+ }
103
+ return { score: Math.max(0, score), maxScore: 7, issues, suggestions };
104
+ },
105
+ };
106
+ const faqPresence = {
107
+ id: 'faq-presence',
108
+ dimension: 'structure',
109
+ weight: 5,
110
+ evaluate(doc) {
111
+ const issues = [];
112
+ const suggestions = [];
113
+ const hasFaqHeading = doc.headings.some((h) => /faq|frequently asked|common questions/i.test(h.text));
114
+ const hasFaqSchema = doc.jsonLd.some((ld) => ld['@type'] === 'FAQPage');
115
+ const hasQuestionHeadings = doc.headings.filter((h) => h.text.endsWith('?')).length >= 2;
116
+ let score = 0;
117
+ if (hasFaqSchema)
118
+ score += 3;
119
+ if (hasFaqHeading || hasQuestionHeadings)
120
+ score += 2;
121
+ if (score === 0) {
122
+ suggestions.push({
123
+ dimension: 'structure',
124
+ action: 'Add FAQ section with question-format headings',
125
+ impact: 'high',
126
+ detail: 'FAQ sections are highly cited by AI search engines. Structure as H2/H3 questions with concise answers.',
127
+ });
128
+ }
129
+ else if (!hasFaqSchema && (hasFaqHeading || hasQuestionHeadings)) {
130
+ suggestions.push({
131
+ dimension: 'structure',
132
+ action: 'Add FAQPage JSON-LD schema for existing FAQ content',
133
+ impact: 'medium',
134
+ detail: 'You have FAQ-like content but no FAQPage schema markup.',
135
+ });
136
+ }
137
+ return { score: Math.min(5, score), maxScore: 5, issues, suggestions };
138
+ },
139
+ };
140
+ const listUsage = {
141
+ id: 'list-usage',
142
+ dimension: 'structure',
143
+ weight: 5,
144
+ evaluate(doc) {
145
+ const suggestions = [];
146
+ // Check for list-like patterns in raw text
147
+ const hasLists = /(?:<[ou]l>|^[-*]\s|^\d+\.\s)/m.test(doc.html || doc.markdown || '');
148
+ const wordCount = doc.rawText.split(/\s+/).length;
149
+ let score = 5;
150
+ if (!hasLists && wordCount > 300) {
151
+ score = 2;
152
+ suggestions.push({
153
+ dimension: 'structure',
154
+ action: 'Add bullet or numbered lists for scannable content',
155
+ impact: 'low',
156
+ detail: 'Lists help AI engines extract key points. Convert sequences or steps into structured lists.',
157
+ });
158
+ }
159
+ return { score, maxScore: 5, issues: [], suggestions };
160
+ },
161
+ };
162
+ // ── Citability Rules (25 pts) ──────────────────────────────────────
163
+ const selfContainedStatements = {
164
+ id: 'self-contained-statements',
165
+ dimension: 'citability',
166
+ weight: 8,
167
+ evaluate(doc) {
168
+ const issues = [];
169
+ const suggestions = [];
170
+ if (doc.paragraphs.length === 0) {
171
+ return { score: 0, maxScore: 8, issues, suggestions };
172
+ }
173
+ // Heuristic: paragraphs starting with pronouns or relative references are not self-contained
174
+ const danglingStarts = /^(this|that|these|those|it|they|he|she|however|moreover|furthermore|additionally|also|but|and|or)\b/i;
175
+ const danglingParagraphs = doc.paragraphs.filter((p) => danglingStarts.test(p.trim()));
176
+ const ratio = danglingParagraphs.length / doc.paragraphs.length;
177
+ let score = 8;
178
+ if (ratio > 0.4) {
179
+ score -= 5;
180
+ issues.push({
181
+ dimension: 'citability',
182
+ severity: 'warning',
183
+ message: `${danglingParagraphs.length}/${doc.paragraphs.length} paragraphs start with pronouns or conjunctions, making them hard to cite in isolation.`,
184
+ });
185
+ }
186
+ else if (ratio > 0.2) {
187
+ score -= 3;
188
+ }
189
+ if (danglingParagraphs.length > 0) {
190
+ suggestions.push({
191
+ dimension: 'citability',
192
+ action: 'Rewrite paragraphs to be self-contained',
193
+ impact: 'high',
194
+ detail: 'Each paragraph should make sense without reading the previous one. Replace "This feature..." with "[Product name] feature...".',
195
+ });
196
+ }
197
+ return { score: Math.max(0, score), maxScore: 8, issues, suggestions };
198
+ },
199
+ };
200
+ const dataStatsPresence = {
201
+ id: 'data-stats-presence',
202
+ dimension: 'citability',
203
+ weight: 7,
204
+ evaluate(doc) {
205
+ const suggestions = [];
206
+ // Look for numbers, percentages, dates, monetary values
207
+ const dataPatterns = /(\d+%|\$[\d,.]+|€[\d,.]+|\d{4}[-/]\d{2}[-/]\d{2}|\d+\s*(users|customers|companies|countries|years|months|hours|minutes|seconds|ms|GB|MB|TB|requests|transactions))/gi;
208
+ const matches = doc.rawText.match(dataPatterns) || [];
209
+ const wordCount = doc.rawText.split(/\s+/).length;
210
+ const dataPerKWords = (matches.length / wordCount) * 1000;
211
+ let score;
212
+ if (dataPerKWords >= 3) {
213
+ score = 7;
214
+ }
215
+ else if (dataPerKWords >= 1) {
216
+ score = 5;
217
+ }
218
+ else if (matches.length > 0) {
219
+ score = 3;
220
+ }
221
+ else {
222
+ score = 1;
223
+ suggestions.push({
224
+ dimension: 'citability',
225
+ action: 'Add specific data points, statistics, or metrics',
226
+ impact: 'high',
227
+ detail: 'AI engines strongly prefer content with concrete numbers. Add dates, percentages, counts, or benchmarks.',
228
+ });
229
+ }
230
+ return { score, maxScore: 7, issues: [], suggestions };
231
+ },
232
+ };
233
+ const clearDefinitions = {
234
+ id: 'clear-definitions',
235
+ dimension: 'citability',
236
+ weight: 5,
237
+ evaluate(doc) {
238
+ const suggestions = [];
239
+ // Look for "X is Y" patterns, definition lists
240
+ const definitionPatterns = /\b\w+\s+(?:is|are|refers to|means|defines?|defined as)\s+/gi;
241
+ const matches = doc.rawText.match(definitionPatterns) || [];
242
+ const hasDlElements = /<dl/i.test(doc.html || '');
243
+ let score = 0;
244
+ if (matches.length >= 3 || hasDlElements)
245
+ score = 5;
246
+ else if (matches.length >= 1)
247
+ score = 3;
248
+ else {
249
+ score = 1;
250
+ suggestions.push({
251
+ dimension: 'citability',
252
+ action: 'Add clear definitions for key terms',
253
+ impact: 'medium',
254
+ detail: 'Use "X is Y" pattern to define concepts. AI engines often extract these as featured snippets.',
255
+ });
256
+ }
257
+ return { score, maxScore: 5, issues: [], suggestions };
258
+ },
259
+ };
260
+ const attribution = {
261
+ id: 'attribution',
262
+ dimension: 'citability',
263
+ weight: 5,
264
+ evaluate(doc) {
265
+ const issues = [];
266
+ const suggestions = [];
267
+ let score = 0;
268
+ // Check for author metadata
269
+ const hasAuthor = doc.metaTags['author'] || doc.metaTags['article:author'] || doc.jsonLd.some((ld) => ld.author);
270
+ if (hasAuthor)
271
+ score += 2;
272
+ // Check for date
273
+ const hasDate = doc.metaTags['article:published_time'] || doc.metaTags['date'] || doc.jsonLd.some((ld) => ld.datePublished);
274
+ if (hasDate)
275
+ score += 2;
276
+ // Check for source citations in content
277
+ const hasCitations = /(?:according to|source:|cited from|reference:|via\s)/i.test(doc.rawText);
278
+ if (hasCitations)
279
+ score += 1;
280
+ if (score < 3) {
281
+ suggestions.push({
282
+ dimension: 'citability',
283
+ action: 'Add author and publication date metadata',
284
+ impact: 'medium',
285
+ detail: 'AI engines weigh attributed content higher. Add meta author, published date, and source citations.',
286
+ });
287
+ }
288
+ return { score: Math.min(5, score), maxScore: 5, issues, suggestions };
289
+ },
290
+ };
291
+ // ── Schema Rules (20 pts) ──────────────────────────────────────────
292
+ const jsonLdPresence = {
293
+ id: 'json-ld-presence',
294
+ dimension: 'schema',
295
+ weight: 6,
296
+ evaluate(doc) {
297
+ const issues = [];
298
+ if (doc.jsonLd.length === 0) {
299
+ issues.push({
300
+ dimension: 'schema',
301
+ severity: 'critical',
302
+ message: 'No JSON-LD structured data found. AI engines rely heavily on structured data to understand content.',
303
+ });
304
+ return { score: 0, maxScore: 6, issues, suggestions: [] };
305
+ }
306
+ return { score: 6, maxScore: 6, issues, suggestions: [] };
307
+ },
308
+ };
309
+ const jsonLdCompleteness = {
310
+ id: 'json-ld-completeness',
311
+ dimension: 'schema',
312
+ weight: 7,
313
+ evaluate(doc) {
314
+ const issues = [];
315
+ const suggestions = [];
316
+ if (doc.jsonLd.length === 0) {
317
+ return { score: 0, maxScore: 7, issues, suggestions };
318
+ }
319
+ const requiredFields = ['@type', 'name', 'description'];
320
+ let totalScore = 0;
321
+ let checked = 0;
322
+ for (const ld of doc.jsonLd) {
323
+ checked++;
324
+ const obj = ld;
325
+ const missing = requiredFields.filter((f) => !obj[f]);
326
+ if (missing.length === 0) {
327
+ totalScore += 7;
328
+ }
329
+ else {
330
+ totalScore += Math.max(0, 7 - missing.length * 2);
331
+ issues.push({
332
+ dimension: 'schema',
333
+ severity: 'warning',
334
+ message: `JSON-LD (${obj['@type'] || 'unknown'}) missing fields: ${missing.join(', ')}`,
335
+ });
336
+ }
337
+ }
338
+ const score = Math.round(totalScore / checked);
339
+ // Check for author/datePublished on Article types
340
+ const articles = doc.jsonLd.filter((ld) => /article/i.test(ld['@type'] || ''));
341
+ for (const article of articles) {
342
+ const obj = article;
343
+ if (!obj.author) {
344
+ suggestions.push({
345
+ dimension: 'schema',
346
+ action: 'Add author field to Article schema',
347
+ impact: 'medium',
348
+ detail: 'Articles with author attribution are more likely to be cited by AI.',
349
+ });
350
+ }
351
+ if (!obj.datePublished) {
352
+ suggestions.push({
353
+ dimension: 'schema',
354
+ action: 'Add datePublished to Article schema',
355
+ impact: 'medium',
356
+ detail: 'AI engines prefer content with clear publication dates.',
357
+ });
358
+ }
359
+ }
360
+ return { score: Math.min(7, score), maxScore: 7, issues, suggestions };
361
+ },
362
+ };
363
+ const aiRelevantSchemaTypes = {
364
+ id: 'ai-relevant-schema-types',
365
+ dimension: 'schema',
366
+ weight: 7,
367
+ evaluate(doc) {
368
+ const suggestions = [];
369
+ const aiRelevantTypes = ['Article', 'FAQPage', 'HowTo', 'Product', 'Organization', 'BreadcrumbList', 'WebPage', 'TechArticle'];
370
+ const foundTypes = new Set(doc.jsonLd.map((ld) => ld['@type']).filter(Boolean));
371
+ const relevantFound = aiRelevantTypes.filter((t) => foundTypes.has(t));
372
+ let score;
373
+ if (relevantFound.length >= 3) {
374
+ score = 7;
375
+ }
376
+ else if (relevantFound.length >= 2) {
377
+ score = 5;
378
+ }
379
+ else if (relevantFound.length === 1) {
380
+ score = 3;
381
+ }
382
+ else {
383
+ score = 0;
384
+ suggestions.push({
385
+ dimension: 'schema',
386
+ action: 'Add AI-relevant schema types',
387
+ impact: 'high',
388
+ detail: `Consider adding: ${aiRelevantTypes.slice(0, 4).join(', ')}. These types are most frequently extracted by AI search engines.`,
389
+ });
390
+ }
391
+ return { score, maxScore: 7, issues: [], suggestions };
392
+ },
393
+ };
394
+ // ── AI Metadata Rules (15 pts) ─────────────────────────────────────
395
+ const llmsTxtPresence = {
396
+ id: 'llms-txt-presence',
397
+ dimension: 'aiMetadata',
398
+ weight: 5,
399
+ evaluate(doc) {
400
+ const suggestions = [];
401
+ // For now, check meta tags for llms.txt reference or if the doc itself is llms.txt
402
+ const hasLlmsTxtMeta = !!doc.metaTags['llms-txt'] || doc.links.some((l) => /llms\.txt/i.test(l.href));
403
+ if (!hasLlmsTxtMeta) {
404
+ suggestions.push({
405
+ dimension: 'aiMetadata',
406
+ action: 'Create and link an llms.txt file',
407
+ impact: 'high',
408
+ detail: 'llms.txt is the emerging standard for making your site AI-readable. Use `aeo generate` to create one.',
409
+ });
410
+ return { score: 0, maxScore: 5, issues: [], suggestions };
411
+ }
412
+ return { score: 5, maxScore: 5, issues: [], suggestions };
413
+ },
414
+ };
415
+ const robotsTxtAiConfig = {
416
+ id: 'robots-txt-ai-config',
417
+ dimension: 'aiMetadata',
418
+ weight: 5,
419
+ evaluate(doc) {
420
+ const suggestions = [];
421
+ // This rule checks meta robots and hints; actual robots.txt checking is done at directory/URL level
422
+ const robotsMeta = doc.metaTags['robots'] || '';
423
+ const hasNoindex = /noindex/i.test(robotsMeta);
424
+ if (hasNoindex) {
425
+ return {
426
+ score: 0,
427
+ maxScore: 5,
428
+ issues: [{
429
+ dimension: 'aiMetadata',
430
+ severity: 'critical',
431
+ message: 'Page has noindex meta tag. AI crawlers will skip this page.',
432
+ }],
433
+ suggestions,
434
+ };
435
+ }
436
+ // Give partial credit — full robots.txt analysis requires directory-level scan
437
+ suggestions.push({
438
+ dimension: 'aiMetadata',
439
+ action: 'Configure robots.txt with explicit AI crawler rules',
440
+ impact: 'medium',
441
+ detail: 'Add rules for GPTBot, ClaudeBot, PerplexityBot, Google-Extended to control AI crawler access.',
442
+ });
443
+ return { score: 3, maxScore: 5, issues: [], suggestions };
444
+ },
445
+ };
446
+ const metaDescriptionQuality = {
447
+ id: 'meta-description-quality',
448
+ dimension: 'aiMetadata',
449
+ weight: 5,
450
+ evaluate(doc) {
451
+ const issues = [];
452
+ const suggestions = [];
453
+ const desc = doc.metaTags['description'] || doc.metaTags['og:description'] || '';
454
+ if (!desc) {
455
+ issues.push({
456
+ dimension: 'aiMetadata',
457
+ severity: 'warning',
458
+ message: 'No meta description found. AI engines use this as a primary content summary.',
459
+ });
460
+ return { score: 0, maxScore: 5, issues, suggestions };
461
+ }
462
+ let score = 3;
463
+ // Check length
464
+ if (desc.length >= 50 && desc.length <= 160) {
465
+ score += 2;
466
+ }
467
+ else if (desc.length < 50) {
468
+ score += 0;
469
+ suggestions.push({
470
+ dimension: 'aiMetadata',
471
+ action: 'Expand meta description to 50-160 characters',
472
+ impact: 'low',
473
+ detail: `Current length: ${desc.length} characters. Too short for AI to use as summary.`,
474
+ });
475
+ }
476
+ else {
477
+ score += 1;
478
+ suggestions.push({
479
+ dimension: 'aiMetadata',
480
+ action: 'Shorten meta description to under 160 characters',
481
+ impact: 'low',
482
+ detail: `Current length: ${desc.length} characters. May be truncated by AI engines.`,
483
+ });
484
+ }
485
+ return { score, maxScore: 5, issues, suggestions };
486
+ },
487
+ };
488
+ // ── Content Density Rules (15 pts) ─────────────────────────────────
489
+ const contentBoilerplateRatio = {
490
+ id: 'content-boilerplate-ratio',
491
+ dimension: 'contentDensity',
492
+ weight: 5,
493
+ evaluate(doc) {
494
+ const suggestions = [];
495
+ // Simple heuristic: ratio of paragraph text to total text
496
+ const paragraphText = doc.paragraphs.join(' ');
497
+ const paragraphWords = paragraphText.split(/\s+/).filter(Boolean).length;
498
+ const totalWords = doc.rawText.split(/\s+/).filter(Boolean).length;
499
+ if (totalWords === 0) {
500
+ return { score: 0, maxScore: 5, issues: [{ dimension: 'contentDensity', severity: 'warning', message: 'No text content found.' }], suggestions };
501
+ }
502
+ const ratio = paragraphWords / totalWords;
503
+ let score;
504
+ if (ratio >= 0.6) {
505
+ score = 5;
506
+ }
507
+ else if (ratio >= 0.4) {
508
+ score = 3;
509
+ }
510
+ else {
511
+ score = 1;
512
+ suggestions.push({
513
+ dimension: 'contentDensity',
514
+ action: 'Increase content-to-boilerplate ratio',
515
+ impact: 'medium',
516
+ detail: `Only ${Math.round(ratio * 100)}% of page text is in content paragraphs. Use semantic HTML (<main>, <article>) to help AI identify primary content.`,
517
+ });
518
+ }
519
+ return { score, maxScore: 5, issues: [], suggestions };
520
+ },
521
+ };
522
+ const keywordStuffingDetection = {
523
+ id: 'keyword-stuffing-detection',
524
+ dimension: 'contentDensity',
525
+ weight: 5,
526
+ evaluate(doc) {
527
+ const issues = [];
528
+ const suggestions = [];
529
+ const words = doc.rawText.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
530
+ if (words.length < 50) {
531
+ return { score: 5, maxScore: 5, issues, suggestions };
532
+ }
533
+ // Count word frequency, excluding common stop words
534
+ const stopWords = new Set(['that', 'this', 'with', 'from', 'have', 'been', 'they', 'their', 'will', 'would', 'could', 'should', 'about', 'which', 'when', 'what', 'there', 'where', 'your', 'more', 'some', 'than', 'them', 'into', 'other', 'also', 'just', 'only', 'very', 'does', 'each']);
535
+ const freq = new Map();
536
+ for (const word of words) {
537
+ if (stopWords.has(word))
538
+ continue;
539
+ freq.set(word, (freq.get(word) || 0) + 1);
540
+ }
541
+ const threshold = words.length * 0.03; // 3%
542
+ const stuffed = [...freq.entries()].filter(([, count]) => count > threshold).sort((a, b) => b[1] - a[1]);
543
+ if (stuffed.length > 0) {
544
+ const topStuffed = stuffed.slice(0, 3).map(([word, count]) => `"${word}" (${((count / words.length) * 100).toFixed(1)}%)`);
545
+ issues.push({
546
+ dimension: 'contentDensity',
547
+ severity: 'warning',
548
+ message: `Potential keyword stuffing: ${topStuffed.join(', ')}. AI engines penalize repetitive content.`,
549
+ });
550
+ return { score: 1, maxScore: 5, issues, suggestions: [{ dimension: 'contentDensity', action: 'Reduce keyword repetition', impact: 'high', detail: 'Use synonyms and natural language variation instead of repeating the same terms.' }] };
551
+ }
552
+ return { score: 5, maxScore: 5, issues, suggestions };
553
+ },
554
+ };
555
+ const contentUniquenessSignals = {
556
+ id: 'content-uniqueness-signals',
557
+ dimension: 'contentDensity',
558
+ weight: 5,
559
+ evaluate(doc) {
560
+ const suggestions = [];
561
+ let score = 2; // Base score
562
+ // Check for original data indicators
563
+ const hasOriginalData = /(?:our\s+(?:data|research|analysis|survey|study)|we\s+(?:found|discovered|measured|tested|analyzed))/i.test(doc.rawText);
564
+ if (hasOriginalData)
565
+ score += 2;
566
+ // Check for code examples
567
+ const hasCode = /<code|<pre|```/i.test(doc.html || doc.markdown || '');
568
+ if (hasCode)
569
+ score += 1;
570
+ if (score < 4) {
571
+ suggestions.push({
572
+ dimension: 'contentDensity',
573
+ action: 'Add original data, examples, or unique insights',
574
+ impact: 'medium',
575
+ detail: 'AI engines prefer content with original research, unique data points, or practical examples over generic information.',
576
+ });
577
+ }
578
+ return { score: Math.min(5, score), maxScore: 5, issues: [], suggestions };
579
+ },
580
+ };
581
+ // ── Export all rules ───────────────────────────────────────────────
582
+ export const allRules = [
583
+ // Structure (25 pts)
584
+ headingHierarchy,
585
+ paragraphLength,
586
+ faqPresence,
587
+ listUsage,
588
+ // Citability (25 pts)
589
+ selfContainedStatements,
590
+ dataStatsPresence,
591
+ clearDefinitions,
592
+ attribution,
593
+ // Schema (20 pts)
594
+ jsonLdPresence,
595
+ jsonLdCompleteness,
596
+ aiRelevantSchemaTypes,
597
+ // AI Metadata (15 pts)
598
+ llmsTxtPresence,
599
+ robotsTxtAiConfig,
600
+ metaDescriptionQuality,
601
+ // Content Density (15 pts)
602
+ contentBoilerplateRatio,
603
+ keywordStuffingDetection,
604
+ contentUniquenessSignals,
605
+ ];
606
+ export function getRulesByDimension(dimension) {
607
+ return allRules.filter((r) => r.dimension === dimension);
608
+ }
609
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/core/rules.ts"],"names":[],"mappings":"AAEA,sEAAsE;AAEtE,MAAM,gBAAgB,GAAgB;IACpC,EAAE,EAAE,mBAAmB;IACvB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QAEzB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,0FAA0F;aACpG,CAAC,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QACxD,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,sBAAsB;QACtB,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;QAClD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,KAAK,IAAI,CAAC,CAAC;YACX,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,6DAA6D;aACvE,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,KAAK,IAAI,CAAC,CAAC;YACX,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,SAAS,GAAG,CAAC,MAAM,4CAA4C;aACzE,CAAC,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC/B,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;gBACpB,KAAK,IAAI,CAAC,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC;oBACV,SAAS,EAAE,WAAW;oBACtB,QAAQ,EAAE,SAAS;oBACnB,OAAO,EAAE,2BAA2B,IAAI,OAAO,IAAI,qCAAqC;iBACzF,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QAClD,IAAI,SAAS,GAAG,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,KAAK,IAAI,CAAC,CAAC;YACX,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,4CAA4C;gBACpD,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,GAAG,SAAS,oBAAoB,QAAQ,CAAC,MAAM,mDAAmD;aAC3G,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;CACF,CAAC;AAEF,MAAM,eAAe,GAAgB;IACnC,EAAE,EAAE,kBAAkB;IACtB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC;QAE3B,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;QAC/I,CAAC;QAED,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QAExD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,CAAC;YACX,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,GAAG,cAAc,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,6FAA6F;aACpJ,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YACvB,KAAK,IAAI,CAAC,CAAC;YACX,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,GAAG,cAAc,CAAC,MAAM,oEAAoE;aACtG,CAAC,CAAC;QACL,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,sDAAsD;gBAC9D,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,yGAAyG;aAClH,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;CACF,CAAC;AAEF,MAAM,WAAW,GAAgB;IAC/B,EAAE,EAAE,cAAc;IAClB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,MAAM,aAAa,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wCAAwC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACtG,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC;QAC7E,MAAM,mBAAmB,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;QAEzF,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,YAAY;YAAE,KAAK,IAAI,CAAC,CAAC;QAC7B,IAAI,aAAa,IAAI,mBAAmB;YAAE,KAAK,IAAI,CAAC,CAAC;QAErD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,+CAA+C;gBACvD,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,wGAAwG;aACjH,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,CAAC,YAAY,IAAI,CAAC,aAAa,IAAI,mBAAmB,CAAC,EAAE,CAAC;YACnE,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,qDAAqD;gBAC7D,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,yDAAyD;aAClE,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;CACF,CAAC;AAEF,MAAM,SAAS,GAAgB;IAC7B,EAAE,EAAE,YAAY;IAChB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,2CAA2C;QAC3C,MAAM,QAAQ,GAAG,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACtF,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QAElD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,QAAQ,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;YACjC,KAAK,GAAG,CAAC,CAAC;YACV,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,oDAAoD;gBAC5D,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,6FAA6F;aACtG,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IACzD,CAAC;CACF,CAAC;AAEF,sEAAsE;AAEtE,MAAM,uBAAuB,GAAgB;IAC3C,EAAE,EAAE,2BAA2B;IAC/B,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QACxD,CAAC;QAED,6FAA6F;QAC7F,MAAM,cAAc,GAAG,sGAAsG,CAAC;QAC9H,MAAM,kBAAkB,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACvF,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QAEhE,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,CAAC;YACX,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,YAAY;gBACvB,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,GAAG,kBAAkB,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,yFAAyF;aACxJ,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YACvB,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;QAED,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,yCAAyC;gBACjD,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,gIAAgI;aACzI,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAgB;IACrC,EAAE,EAAE,qBAAqB;IACzB,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,wDAAwD;QACxD,MAAM,YAAY,GAAG,sKAAsK,CAAC;QAC5L,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAEtD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QAClD,MAAM,aAAa,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;QAE1D,IAAI,KAAa,CAAC;QAClB,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACvB,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YAC9B,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,CAAC,CAAC;YACV,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,kDAAkD;gBAC1D,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,0GAA0G;aACnH,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IACzD,CAAC;CACF,CAAC;AAEF,MAAM,gBAAgB,GAAgB;IACpC,EAAE,EAAE,mBAAmB;IACvB,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,+CAA+C;QAC/C,MAAM,kBAAkB,GAAG,6DAA6D,CAAC;QACzF,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;QAE5D,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAElD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,aAAa;YAAE,KAAK,GAAG,CAAC,CAAC;aAC/C,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC;YAAE,KAAK,GAAG,CAAC,CAAC;aACnC,CAAC;YACJ,KAAK,GAAG,CAAC,CAAC;YACV,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,qCAAqC;gBAC7C,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,+FAA+F;aACxG,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IACzD,CAAC;CACF,CAAC;AAEF,MAAM,WAAW,GAAgB;IAC/B,EAAE,EAAE,aAAa;IACjB,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,4BAA4B;QAC5B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACtH,IAAI,SAAS;YAAE,KAAK,IAAI,CAAC,CAAC;QAE1B,iBAAiB;QACjB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,wBAAwB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;QACjI,IAAI,OAAO;YAAE,KAAK,IAAI,CAAC,CAAC;QAExB,wCAAwC;QACxC,MAAM,YAAY,GAAG,uDAAuD,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/F,IAAI,YAAY;YAAE,KAAK,IAAI,CAAC,CAAC;QAE7B,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,0CAA0C;gBAClD,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,oGAAoG;aAC7G,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;CACF,CAAC;AAEF,sEAAsE;AAEtE,MAAM,cAAc,GAAgB;IAClC,EAAE,EAAE,kBAAkB;IACtB,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,QAAQ;gBACnB,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,qGAAqG;aAC/G,CAAC,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QAC5D,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5D,CAAC;CACF,CAAC;AAEF,MAAM,kBAAkB,GAAgB;IACtC,EAAE,EAAE,sBAAsB;IAC1B,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QACxD,CAAC;QAED,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;QACxD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,EAA6B,CAAC;YAC1C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAEtD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,UAAU,IAAI,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,UAAU,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAClD,MAAM,CAAC,IAAI,CAAC;oBACV,SAAS,EAAE,QAAQ;oBACnB,QAAQ,EAAE,SAAS;oBACnB,OAAO,EAAE,YAAY,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,qBAAqB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBACxF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC;QAE/C,kDAAkD;QAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACpF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,OAAkC,CAAC;YAC/C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,WAAW,CAAC,IAAI,CAAC;oBACf,SAAS,EAAE,QAAQ;oBACnB,MAAM,EAAE,oCAAoC;oBAC5C,MAAM,EAAE,QAAQ;oBAChB,MAAM,EAAE,qEAAqE;iBAC9E,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACvB,WAAW,CAAC,IAAI,CAAC;oBACf,SAAS,EAAE,QAAQ;oBACnB,MAAM,EAAE,qCAAqC;oBAC7C,MAAM,EAAE,QAAQ;oBAChB,MAAM,EAAE,yDAAyD;iBAClE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;CACF,CAAC;AAEF,MAAM,qBAAqB,GAAgB;IACzC,EAAE,EAAE,0BAA0B;IAC9B,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QAC/H,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACrF,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEvE,IAAI,KAAa,CAAC;QAClB,IAAI,aAAa,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC9B,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,aAAa,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACrC,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,CAAC,CAAC;YACV,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE,8BAA8B;gBACtC,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,oBAAoB,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mEAAmE;aACtI,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IACzD,CAAC;CACF,CAAC;AAEF,sEAAsE;AAEtE,MAAM,eAAe,GAAgB;IACnC,EAAE,EAAE,mBAAmB;IACvB,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,mFAAmF;QACnF,MAAM,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtG,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,kCAAkC;gBAC1C,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,uGAAuG;aAChH,CAAC,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;QAC5D,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IAC5D,CAAC;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAgB;IACrC,EAAE,EAAE,sBAAsB;IAC1B,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,oGAAoG;QACpG,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE/C,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,CAAC;wBACP,SAAS,EAAE,YAAY;wBACvB,QAAQ,EAAE,UAAU;wBACpB,OAAO,EAAE,6DAA6D;qBACvE,CAAC;gBACF,WAAW;aACZ,CAAC;QACJ,CAAC;QAED,+EAA+E;QAC/E,WAAW,CAAC,IAAI,CAAC;YACf,SAAS,EAAE,YAAY;YACvB,MAAM,EAAE,qDAAqD;YAC7D,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,+FAA+F;SACxG,CAAC,CAAC;QAEH,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IAC5D,CAAC;CACF,CAAC;AAEF,MAAM,sBAAsB,GAAgB;IAC1C,EAAE,EAAE,0BAA0B;IAC9B,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;QAEjF,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,YAAY;gBACvB,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,8EAA8E;aACxF,CAAC,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QACxD,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,eAAe;QACf,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAC5C,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC5B,KAAK,IAAI,CAAC,CAAC;YACX,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,8CAA8C;gBACtD,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,mBAAmB,IAAI,CAAC,MAAM,kDAAkD;aACzF,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,CAAC,CAAC;YACX,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,kDAAkD;gBAC1D,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,mBAAmB,IAAI,CAAC,MAAM,8CAA8C;aACrF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACrD,CAAC;CACF,CAAC;AAEF,sEAAsE;AAEtE,MAAM,uBAAuB,GAAgB;IAC3C,EAAE,EAAE,2BAA2B;IAC/B,SAAS,EAAE,gBAAgB;IAC3B,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,0DAA0D;QAC1D,MAAM,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QACzE,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAEnE,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;QACnJ,CAAC;QAED,MAAM,KAAK,GAAG,cAAc,GAAG,UAAU,CAAC;QAE1C,IAAI,KAAa,CAAC;QAClB,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjB,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,CAAC,CAAC;YACV,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,gBAAgB;gBAC3B,MAAM,EAAE,uCAAuC;gBAC/C,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,qHAAqH;aAC7J,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IACzD,CAAC;CACF,CAAC;AAEF,MAAM,wBAAwB,GAAgB;IAC5C,EAAE,EAAE,4BAA4B;IAChC,SAAS,EAAE,gBAAgB;IAC3B,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjF,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACtB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QACxD,CAAC;QAED,oDAAoD;QACpD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9R,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAClC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,KAAK;QAC5C,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC3H,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,gBAAgB;gBAC3B,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,+BAA+B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,2CAA2C;aACzG,CAAC,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,2BAA2B,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kFAAkF,EAAE,CAAC,EAAE,CAAC;QAC5O,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACxD,CAAC;CACF,CAAC;AAEF,MAAM,wBAAwB,GAAgB;IAC5C,EAAE,EAAE,4BAA4B;IAChC,SAAS,EAAE,gBAAgB;IAC3B,MAAM,EAAE,CAAC;IACT,QAAQ,CAAC,GAAmB;QAC1B,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,aAAa;QAE5B,qCAAqC;QACrC,MAAM,eAAe,GAAG,uGAAuG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClJ,IAAI,eAAe;YAAE,KAAK,IAAI,CAAC,CAAC;QAEhC,0BAA0B;QAC1B,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACvE,IAAI,OAAO;YAAE,KAAK,IAAI,CAAC,CAAC;QAExB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,WAAW,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,gBAAgB;gBAC3B,MAAM,EAAE,iDAAiD;gBACzD,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,uHAAuH;aAChI,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IAC7E,CAAC;CACF,CAAC;AAEF,sEAAsE;AAEtE,MAAM,CAAC,MAAM,QAAQ,GAAkB;IACrC,qBAAqB;IACrB,gBAAgB;IAChB,eAAe;IACf,WAAW;IACX,SAAS;IACT,sBAAsB;IACtB,uBAAuB;IACvB,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,qBAAqB;IACrB,uBAAuB;IACvB,eAAe;IACf,iBAAiB;IACjB,sBAAsB;IACtB,2BAA2B;IAC3B,uBAAuB;IACvB,wBAAwB;IACxB,wBAAwB;CACzB,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ParsedDocument, PageAnalysis, ScanReport, ScanTarget } from './types.js';
2
+ export declare function parseHtml(html: string, url: string): ParsedDocument;
3
+ export declare function parseMarkdown(md: string, url: string): ParsedDocument;
4
+ export declare function scanDocument(doc: ParsedDocument): PageAnalysis;
5
+ export declare function scanFile(filePath: string): Promise<PageAnalysis>;
6
+ export declare function scanDirectory(dirPath: string): Promise<ScanReport>;
7
+ export declare function scanUrl(url: string): Promise<ScanReport>;
8
+ export declare function scan(target: ScanTarget): Promise<ScanReport>;