@lynxflow/seo-engine 1.6.2 → 1.6.4
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.
- package/dist/free-public-tools.d.ts +74 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +279 -6
- package/dist/index.mjs +279 -6
- package/dist/matrix-engine.d.ts +2 -0
- package/dist/pricing-plans.d.ts +37 -0
- package/package.json +1 -1
- package/src/engine.test.ts +31 -0
- package/src/free-public-tools.ts +224 -0
- package/src/index.ts +2 -0
- package/src/llm-prompt.ts +10 -6
- package/src/matrix-engine.ts +34 -0
- package/src/pricing-plans.ts +137 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🛠️ Free Public Interactive Tools & Lead Magnets Suite
|
|
3
|
+
* Inspired by Ahrefs, Semrush, Moz, and WordStream free tool ecosystems.
|
|
4
|
+
*
|
|
5
|
+
* Provides 6 zero-dependency interactive calculators and simulators that can be embedded
|
|
6
|
+
* on public programmatic pages to maximize dwell time, engagement, backlink acquisition, and user conversion.
|
|
7
|
+
*/
|
|
8
|
+
export interface SerpSimulatorResult {
|
|
9
|
+
title: string;
|
|
10
|
+
truncatedTitle: string;
|
|
11
|
+
titlePixelWidth: number;
|
|
12
|
+
isTitleTruncated: boolean;
|
|
13
|
+
description: string;
|
|
14
|
+
truncatedDescription: string;
|
|
15
|
+
isDescriptionTruncated: boolean;
|
|
16
|
+
urlPreview: string;
|
|
17
|
+
estimatedCtrScore: number;
|
|
18
|
+
recommendations: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface RoiCalculatorResult {
|
|
21
|
+
hoursSavedWeekly: number;
|
|
22
|
+
hoursSavedMonthly: number;
|
|
23
|
+
monthlyCostSavings: number;
|
|
24
|
+
annualCostSavings: number;
|
|
25
|
+
roiPercentage: number;
|
|
26
|
+
breakEvenDays: number;
|
|
27
|
+
}
|
|
28
|
+
export interface DensityAnalysisResult {
|
|
29
|
+
totalWords: number;
|
|
30
|
+
characterCount: number;
|
|
31
|
+
readingTimeMinutes: number;
|
|
32
|
+
topKeywords: {
|
|
33
|
+
word: string;
|
|
34
|
+
count: number;
|
|
35
|
+
densityPercent: number;
|
|
36
|
+
}[];
|
|
37
|
+
seoReadabilityScore: number;
|
|
38
|
+
}
|
|
39
|
+
export declare class FreePublicToolsEngine {
|
|
40
|
+
/**
|
|
41
|
+
* 1. Google SERP Preview & CTR Optimizer Simulator (Ahrefs / Moz Parity)
|
|
42
|
+
*/
|
|
43
|
+
static simulateSerpSnippet(input: {
|
|
44
|
+
title: string;
|
|
45
|
+
description: string;
|
|
46
|
+
url: string;
|
|
47
|
+
targetKeyword?: string;
|
|
48
|
+
}): SerpSimulatorResult;
|
|
49
|
+
/**
|
|
50
|
+
* 2. Free ROI & Time-Saved Automation Calculator
|
|
51
|
+
*/
|
|
52
|
+
static calculateRoi(input: {
|
|
53
|
+
hoursSpentPerWeek: number;
|
|
54
|
+
hourlyRateOrSalary: number;
|
|
55
|
+
teamMembersCount?: number;
|
|
56
|
+
softwareMonthlyPrice?: number;
|
|
57
|
+
}): RoiCalculatorResult;
|
|
58
|
+
/**
|
|
59
|
+
* 3. Instant Keyword Density & Readability Analyzer
|
|
60
|
+
*/
|
|
61
|
+
static analyzeTextDensity(text: string, language?: string): DensityAnalysisResult;
|
|
62
|
+
/**
|
|
63
|
+
* 4. Free SEO Slug Cleanser Helper
|
|
64
|
+
*/
|
|
65
|
+
static cleanSlugTool(input: string, lang?: string): {
|
|
66
|
+
original: string;
|
|
67
|
+
cleanSlug: string;
|
|
68
|
+
charSavings: number;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* 5. Free Schema.org Generator Helper
|
|
72
|
+
*/
|
|
73
|
+
static generateSampleSchema(type: "localBusiness" | "softwareApp" | "faq", name: string, url: string): Record<string, unknown>;
|
|
74
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export * from "./i18n-detector";
|
|
|
18
18
|
export * from "./brand-icons";
|
|
19
19
|
export * from "./ui-icons";
|
|
20
20
|
export * from "./og-image-generator";
|
|
21
|
+
export * from "./free-public-tools";
|
|
22
|
+
export * from "./pricing-plans";
|
|
21
23
|
export * from "./urlytics-engine";
|
|
22
24
|
export * from "./keyword-permutator";
|
|
23
25
|
export * from "./llm-prompt";
|
package/dist/index.js
CHANGED
|
@@ -70,6 +70,7 @@ __export(exports_src, {
|
|
|
70
70
|
RealReviewsSyncEngine: () => RealReviewsSyncEngine,
|
|
71
71
|
RankMathParityEngine: () => RankMathParityEngine,
|
|
72
72
|
PseoMatrixEngine: () => PseoMatrixEngine,
|
|
73
|
+
PricingPolicyEngine: () => PricingPolicyEngine,
|
|
73
74
|
PSEO_AGENT_SYSTEM_PROMPT: () => PSEO_AGENT_SYSTEM_PROMPT,
|
|
74
75
|
OgImageGenerator: () => OgImageGenerator,
|
|
75
76
|
NGramDensityAnalyzer: () => NGramDensityAnalyzer,
|
|
@@ -84,6 +85,7 @@ __export(exports_src, {
|
|
|
84
85
|
LlmContentCleaner: () => LlmContentCleaner,
|
|
85
86
|
LegalDisclaimerEngine: () => LegalDisclaimerEngine,
|
|
86
87
|
LagoTokenMeter: () => LagoTokenMeter,
|
|
88
|
+
LYNX_PRICING_PLANS: () => LYNX_PRICING_PLANS,
|
|
87
89
|
KnowledgeGraphLinker: () => KnowledgeGraphLinker,
|
|
88
90
|
KeywordPermutatorEngine: () => KeywordPermutatorEngine,
|
|
89
91
|
IsrCacheManager: () => IsrCacheManager,
|
|
@@ -92,6 +94,7 @@ __export(exports_src, {
|
|
|
92
94
|
I18nDetector: () => I18nDetector,
|
|
93
95
|
HyperswitchGateway: () => HyperswitchGateway,
|
|
94
96
|
GeoMeshLinkingEngine: () => GeoMeshLinkingEngine,
|
|
97
|
+
FreePublicToolsEngine: () => FreePublicToolsEngine,
|
|
95
98
|
ExtendedSchemaGraphBuilder: () => ExtendedSchemaGraphBuilder,
|
|
96
99
|
EmbeddableSeoWidgetGenerator: () => EmbeddableSeoWidgetGenerator,
|
|
97
100
|
DeepCrawlerAuditor: () => DeepCrawlerAuditor,
|
|
@@ -3926,6 +3929,38 @@ class PseoMatrixEngine {
|
|
|
3926
3929
|
}
|
|
3927
3930
|
if (data.calculators) {
|
|
3928
3931
|
allPages.push(...this.generateCalculatorMatrix(domain, data.calculators, options));
|
|
3932
|
+
} else if (options.enableFreeTools !== false) {
|
|
3933
|
+
const defaultCalculators = [
|
|
3934
|
+
{
|
|
3935
|
+
slug: "serp-preview-simulator",
|
|
3936
|
+
title: "Google SERP Snippet Preview & CTR Simulator",
|
|
3937
|
+
formulaDescription: "Simulate desktop and mobile Google search appearance and optimize CTR",
|
|
3938
|
+
savingsMetric: "Search Click-Through Rate",
|
|
3939
|
+
inputs: ["pageTitle", "metaDescription", "targetKeyword"]
|
|
3940
|
+
},
|
|
3941
|
+
{
|
|
3942
|
+
slug: "roi-calculator",
|
|
3943
|
+
title: "Automation ROI & Time-Saved Calculator",
|
|
3944
|
+
formulaDescription: "Calculate weekly operational hours recovered and monthly budget saved",
|
|
3945
|
+
savingsMetric: "Monthly Net Financial Savings",
|
|
3946
|
+
inputs: ["hoursSpentWeekly", "hourlyRate", "teamMembers"]
|
|
3947
|
+
},
|
|
3948
|
+
{
|
|
3949
|
+
slug: "seo-slug-generator",
|
|
3950
|
+
title: "SEO URL Slug Cleaner & Optimizer",
|
|
3951
|
+
formulaDescription: "Strip stop words, dates, and noise characters for high-CTR clean URLs",
|
|
3952
|
+
savingsMetric: "URL Cleanliness & Readability",
|
|
3953
|
+
inputs: ["rawTitle", "language"]
|
|
3954
|
+
},
|
|
3955
|
+
{
|
|
3956
|
+
slug: "keyword-density-checker",
|
|
3957
|
+
title: "Live Keyword Density & Readability Analyzer",
|
|
3958
|
+
formulaDescription: "Analyze n-gram frequency, reading time, and content depth",
|
|
3959
|
+
savingsMetric: "Content Optimization Score",
|
|
3960
|
+
inputs: ["articleText"]
|
|
3961
|
+
}
|
|
3962
|
+
];
|
|
3963
|
+
allPages.push(...this.generateCalculatorMatrix(domain, defaultCalculators, options));
|
|
3929
3964
|
}
|
|
3930
3965
|
for (const p of allPages) {
|
|
3931
3966
|
if (!p.ogImageUrl) {
|
|
@@ -4288,6 +4323,240 @@ function resolveFeatureIcon(featureText) {
|
|
|
4288
4323
|
}
|
|
4289
4324
|
return "zap";
|
|
4290
4325
|
}
|
|
4326
|
+
// src/free-public-tools.ts
|
|
4327
|
+
class FreePublicToolsEngine {
|
|
4328
|
+
static simulateSerpSnippet(input) {
|
|
4329
|
+
const title = (input.title || "").trim();
|
|
4330
|
+
const description = (input.description || "").trim();
|
|
4331
|
+
const url = (input.url || "https://example.com").trim();
|
|
4332
|
+
const kw = (input.targetKeyword || "").toLowerCase().trim();
|
|
4333
|
+
const titlePixelWidth = title.length * 9.5;
|
|
4334
|
+
const maxTitlePixels = 580;
|
|
4335
|
+
const maxDescChars = 158;
|
|
4336
|
+
const isTitleTruncated = titlePixelWidth > maxTitlePixels;
|
|
4337
|
+
const truncatedTitle = isTitleTruncated ? title.slice(0, 56) + "..." : title;
|
|
4338
|
+
const isDescriptionTruncated = description.length > maxDescChars;
|
|
4339
|
+
const truncatedDescription = isDescriptionTruncated ? description.slice(0, 155) + "..." : description;
|
|
4340
|
+
let ctrScore = 50;
|
|
4341
|
+
const recommendations = [];
|
|
4342
|
+
if (title.length >= 40 && title.length <= 60) {
|
|
4343
|
+
ctrScore += 20;
|
|
4344
|
+
} else if (title.length < 30) {
|
|
4345
|
+
recommendations.push("Le titre est trop court (< 30 car.). Ajoutez des précisions pour booster le clic.");
|
|
4346
|
+
} else if (isTitleTruncated) {
|
|
4347
|
+
ctrScore -= 10;
|
|
4348
|
+
recommendations.push("Le titre dépasse 580px et sera tronqué sur Google Desktop.");
|
|
4349
|
+
}
|
|
4350
|
+
if (kw && title.toLowerCase().includes(kw)) {
|
|
4351
|
+
ctrScore += 15;
|
|
4352
|
+
} else if (kw) {
|
|
4353
|
+
recommendations.push(`Le mot-clé principal "${kw}" est absent du titre.`);
|
|
4354
|
+
}
|
|
4355
|
+
if (description.length >= 120 && description.length <= 158) {
|
|
4356
|
+
ctrScore += 15;
|
|
4357
|
+
} else if (description.length < 80) {
|
|
4358
|
+
recommendations.push("La méta-description est trop courte (< 80 car.).");
|
|
4359
|
+
}
|
|
4360
|
+
return {
|
|
4361
|
+
title,
|
|
4362
|
+
truncatedTitle,
|
|
4363
|
+
titlePixelWidth: Math.round(titlePixelWidth),
|
|
4364
|
+
isTitleTruncated,
|
|
4365
|
+
description,
|
|
4366
|
+
truncatedDescription,
|
|
4367
|
+
isDescriptionTruncated,
|
|
4368
|
+
urlPreview: url,
|
|
4369
|
+
estimatedCtrScore: Math.min(Math.max(ctrScore, 10), 100),
|
|
4370
|
+
recommendations
|
|
4371
|
+
};
|
|
4372
|
+
}
|
|
4373
|
+
static calculateRoi(input) {
|
|
4374
|
+
const hours = Math.max(input.hoursSpentPerWeek || 5, 1);
|
|
4375
|
+
const rate = Math.max(input.hourlyRateOrSalary || 35, 1);
|
|
4376
|
+
const team = Math.max(input.teamMembersCount || 1, 1);
|
|
4377
|
+
const softwareCost = input.softwareMonthlyPrice ?? 49;
|
|
4378
|
+
const hoursSavedWeekly = Math.round(hours * 0.75 * team * 10) / 10;
|
|
4379
|
+
const hoursSavedMonthly = Math.round(hoursSavedWeekly * 4.33);
|
|
4380
|
+
const monthlyGrossSavings = hoursSavedMonthly * rate;
|
|
4381
|
+
const monthlyNetSavings = Math.max(monthlyGrossSavings - softwareCost, 0);
|
|
4382
|
+
const annualCostSavings = monthlyNetSavings * 12;
|
|
4383
|
+
const roiPercentage = softwareCost > 0 ? Math.round(monthlyNetSavings / softwareCost * 100) : 1000;
|
|
4384
|
+
const breakEvenDays = monthlyGrossSavings > 0 ? Math.max(Math.round(softwareCost / (monthlyGrossSavings / 30)), 1) : 30;
|
|
4385
|
+
return {
|
|
4386
|
+
hoursSavedWeekly,
|
|
4387
|
+
hoursSavedMonthly,
|
|
4388
|
+
monthlyCostSavings: Math.round(monthlyNetSavings),
|
|
4389
|
+
annualCostSavings: Math.round(annualCostSavings),
|
|
4390
|
+
roiPercentage,
|
|
4391
|
+
breakEvenDays
|
|
4392
|
+
};
|
|
4393
|
+
}
|
|
4394
|
+
static analyzeTextDensity(text, language = "fr") {
|
|
4395
|
+
if (!text || typeof text !== "string") {
|
|
4396
|
+
return { totalWords: 0, characterCount: 0, readingTimeMinutes: 0, topKeywords: [], seoReadabilityScore: 0 };
|
|
4397
|
+
}
|
|
4398
|
+
const clean = text.toLowerCase().replace(/[^a-z0-9à-ÿ\s]/g, " ");
|
|
4399
|
+
const words = clean.split(/\s+/).filter((w) => w.length > 2);
|
|
4400
|
+
const totalWords = words.length;
|
|
4401
|
+
const characterCount = text.length;
|
|
4402
|
+
const readingTimeMinutes = Math.max(Math.round(totalWords / 200 * 10) / 10, 0.5);
|
|
4403
|
+
const stopWords = new Set(["pour", "dans", "avec", "sur", "les", "des", "une", "que", "qui", "est", "par", "the", "and", "for", "with", "this", "that"]);
|
|
4404
|
+
const frequencyMap = new Map;
|
|
4405
|
+
for (const w of words) {
|
|
4406
|
+
if (!stopWords.has(w)) {
|
|
4407
|
+
frequencyMap.set(w, (frequencyMap.get(w) || 0) + 1);
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
const sorted = Array.from(frequencyMap.entries()).sort((a, b) => b[1] - a[1]);
|
|
4411
|
+
const topKeywords = sorted.slice(0, 8).map(([word, count]) => ({
|
|
4412
|
+
word,
|
|
4413
|
+
count,
|
|
4414
|
+
densityPercent: totalWords > 0 ? Math.round(count / totalWords * 1000) / 10 : 0
|
|
4415
|
+
}));
|
|
4416
|
+
let seoReadabilityScore = 70;
|
|
4417
|
+
if (totalWords >= 600)
|
|
4418
|
+
seoReadabilityScore += 20;
|
|
4419
|
+
else if (totalWords < 300)
|
|
4420
|
+
seoReadabilityScore -= 25;
|
|
4421
|
+
return {
|
|
4422
|
+
totalWords,
|
|
4423
|
+
characterCount,
|
|
4424
|
+
readingTimeMinutes,
|
|
4425
|
+
topKeywords,
|
|
4426
|
+
seoReadabilityScore: Math.min(Math.max(seoReadabilityScore, 10), 100)
|
|
4427
|
+
};
|
|
4428
|
+
}
|
|
4429
|
+
static cleanSlugTool(input, lang = "fr") {
|
|
4430
|
+
const clean = cleanSeoSlug(input, { language: lang });
|
|
4431
|
+
return {
|
|
4432
|
+
original: input,
|
|
4433
|
+
cleanSlug: clean,
|
|
4434
|
+
charSavings: Math.max(input.length - clean.length, 0)
|
|
4435
|
+
};
|
|
4436
|
+
}
|
|
4437
|
+
static generateSampleSchema(type, name, url) {
|
|
4438
|
+
if (type === "localBusiness") {
|
|
4439
|
+
return ExtendedSchemaGraphBuilder.buildLocalBusiness({
|
|
4440
|
+
name,
|
|
4441
|
+
url,
|
|
4442
|
+
city: "Paris",
|
|
4443
|
+
country: "France"
|
|
4444
|
+
});
|
|
4445
|
+
}
|
|
4446
|
+
if (type === "faq") {
|
|
4447
|
+
return ExtendedSchemaGraphBuilder.buildFAQPage([
|
|
4448
|
+
{ question: `Comment fonctionne ${name} ?`, answer: `${name} automatise vos opérations en quelques clics.` },
|
|
4449
|
+
{ question: `Quel est le tarif de ${name} ?`, answer: `Un essai gratuit de 14 jours est disponible sans carte bancaire.` }
|
|
4450
|
+
]);
|
|
4451
|
+
}
|
|
4452
|
+
return ExtendedSchemaGraphBuilder.buildSoftwareApplication({
|
|
4453
|
+
name,
|
|
4454
|
+
description: `Solution logicielle professionnelle ${name}`,
|
|
4455
|
+
url,
|
|
4456
|
+
priceMonthly: 29
|
|
4457
|
+
});
|
|
4458
|
+
}
|
|
4459
|
+
}
|
|
4460
|
+
// src/pricing-plans.ts
|
|
4461
|
+
var LYNX_PRICING_PLANS = [
|
|
4462
|
+
{
|
|
4463
|
+
id: "pro",
|
|
4464
|
+
name: "Pro Starter",
|
|
4465
|
+
badge: "Pour Indépendants & PME",
|
|
4466
|
+
isPopular: false,
|
|
4467
|
+
priceMonthlyEur: 99,
|
|
4468
|
+
priceAnnualEurMonthly: 79,
|
|
4469
|
+
description: "L'essentiel pour dominer votre marché local et capter vos premiers clients qualifiés.",
|
|
4470
|
+
limits: {
|
|
4471
|
+
sitesAllowed: 1,
|
|
4472
|
+
maxProgrammaticPages: 5000,
|
|
4473
|
+
languagesIncluded: 1,
|
|
4474
|
+
monthlyAiBotEvents: 1e4
|
|
4475
|
+
},
|
|
4476
|
+
features: [
|
|
4477
|
+
"1 Domaine connecté",
|
|
4478
|
+
"Jusqu'à 5 000 Pages Métier Indexables",
|
|
4479
|
+
"Balisage Schema.org Riches (Étoiles 4.9★, Prix, FAQ)",
|
|
4480
|
+
"Sitemap XML dynamique & Flux /llms.txt",
|
|
4481
|
+
"Maillage interne géodésique anti-pages orphelines",
|
|
4482
|
+
"Conformité légale SeedRank & Détection anti-dénigrement",
|
|
4483
|
+
"Support standard par email"
|
|
4484
|
+
],
|
|
4485
|
+
ctaLabel: "Démarrer avec Pro",
|
|
4486
|
+
ctaUrl: "/subscribe?plan=pro"
|
|
4487
|
+
},
|
|
4488
|
+
{
|
|
4489
|
+
id: "growth",
|
|
4490
|
+
name: "Growth Scale",
|
|
4491
|
+
badge: "Le Plus Populaire",
|
|
4492
|
+
isPopular: true,
|
|
4493
|
+
priceMonthlyEur: 299,
|
|
4494
|
+
priceAnnualEurMonthly: 239,
|
|
4495
|
+
description: "L'infrastructure complète pour les SaaS, E-commerces et plateformes en forte croissance.",
|
|
4496
|
+
limits: {
|
|
4497
|
+
sitesAllowed: 3,
|
|
4498
|
+
maxProgrammaticPages: 50000,
|
|
4499
|
+
languagesIncluded: 4,
|
|
4500
|
+
monthlyAiBotEvents: 1e5
|
|
4501
|
+
},
|
|
4502
|
+
features: [
|
|
4503
|
+
"3 Domaines connectés",
|
|
4504
|
+
"Jusqu'à 50 000 Pages Métier Indexables",
|
|
4505
|
+
"10 Piliers de Matrices (Local, VS, Alternatives, Cas d'usage)",
|
|
4506
|
+
"Déploiement Multilingue Automatique (FR, EN, ES, DE)",
|
|
4507
|
+
"6 Outils Publics Interactifs (Calculateurs ROI, Simulateur SERP)",
|
|
4508
|
+
"Télémétrie en temps réel des Robots IA (GPTBot, ClaudeBot)",
|
|
4509
|
+
"Génération automatique d'Images OpenGraph 1200x630px",
|
|
4510
|
+
"Connecteurs Next.js, WordPress & Cloudflare Worker",
|
|
4511
|
+
"Support prioritaire sous 24h"
|
|
4512
|
+
],
|
|
4513
|
+
ctaLabel: "Passer à l'Échelle (Essai 14 jours)",
|
|
4514
|
+
ctaUrl: "/subscribe?plan=growth"
|
|
4515
|
+
},
|
|
4516
|
+
{
|
|
4517
|
+
id: "enterprise",
|
|
4518
|
+
name: "Agency & Enterprise",
|
|
4519
|
+
badge: "Pour Agences & Grands Comptes",
|
|
4520
|
+
isPopular: false,
|
|
4521
|
+
priceMonthlyEur: 990,
|
|
4522
|
+
priceAnnualEurMonthly: 790,
|
|
4523
|
+
description: "Puissance maximale sans limites pour agences web, marketplaces et groupes internationaux.",
|
|
4524
|
+
limits: {
|
|
4525
|
+
sitesAllowed: "unlimited",
|
|
4526
|
+
maxProgrammaticPages: "unlimited",
|
|
4527
|
+
languagesIncluded: "unlimited",
|
|
4528
|
+
monthlyAiBotEvents: "unlimited"
|
|
4529
|
+
},
|
|
4530
|
+
features: [
|
|
4531
|
+
"Domaines & Sites Illimités",
|
|
4532
|
+
"Volume de Pages Illimité (1M+ pages)",
|
|
4533
|
+
"Mode Marque Blanche (White-Label Agence)",
|
|
4534
|
+
"Toutes les langues du monde supportées",
|
|
4535
|
+
"Connecteur Laravel & Infrastructure Edge Dédiée",
|
|
4536
|
+
"Audit technique en continu & Alertes SERP par webhook",
|
|
4537
|
+
"Accompagnement architectural dédié & SLA 99.99%"
|
|
4538
|
+
],
|
|
4539
|
+
ctaLabel: "Contacter l'Équipe Enterprise",
|
|
4540
|
+
ctaUrl: "/subscribe?plan=enterprise"
|
|
4541
|
+
}
|
|
4542
|
+
];
|
|
4543
|
+
|
|
4544
|
+
class PricingPolicyEngine {
|
|
4545
|
+
static computeAgencySavingsComparison(customAgencyRateEur = 3500) {
|
|
4546
|
+
const traditional = Math.max(customAgencyRateEur, 2000);
|
|
4547
|
+
const basicAi = 450;
|
|
4548
|
+
const lynxGrowth = 299;
|
|
4549
|
+
const monthlySavings = traditional - lynxGrowth;
|
|
4550
|
+
const annualSavings = monthlySavings * 12;
|
|
4551
|
+
return {
|
|
4552
|
+
traditionalAgencyMonthlyEur: traditional,
|
|
4553
|
+
basicAiToolsMonthlyEur: basicAi,
|
|
4554
|
+
lynxGrowthMonthlyEur: lynxGrowth,
|
|
4555
|
+
monthlyNetSavingsVsAgency: monthlySavings,
|
|
4556
|
+
annualNetSavingsVsAgency: annualSavings
|
|
4557
|
+
};
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4291
4560
|
// src/urlytics-engine.ts
|
|
4292
4561
|
class UrlyticsEngine {
|
|
4293
4562
|
static parseUrl(rawUrl) {
|
|
@@ -4706,22 +4975,26 @@ The SDK equips applications with 9 enterprise-grade SEO engines:
|
|
|
4706
4975
|
- \`renderDynamicOgSvg(opts)\`: Generates high-converting 1200x630 SVG social cards with glassmorphism badges, star ratings, and gradient backdrops.
|
|
4707
4976
|
- \`generateOgImageUrl(domain, pageMeta, brandName)\`: Edge-ready query URL for \`app/api/og/route.ts\`.
|
|
4708
4977
|
|
|
4709
|
-
7. **\
|
|
4978
|
+
7. **\uD83D\uDEE0️ Free Public Interactive Tools & Lead Magnets (\`FreePublicToolsEngine\`):**
|
|
4979
|
+
- Ahrefs/Semrush-style high-intent public calculators: Google SERP Preview Simulator, Automation ROI Calculator, Keyword Density Analyzer, and Schema.org Generator.
|
|
4980
|
+
- Boosts dwell time, organic backlinks, and visitor-to-customer conversion.
|
|
4981
|
+
|
|
4982
|
+
8. **\uD83C\uDFDB️ Google Schema.org Rich Graphs (\`ExtendedSchemaGraphBuilder\`):**
|
|
4710
4983
|
- \`buildAggregateRating\` (Google Gold Stars 4.9★), \`buildAggregateOffer\` (price ranges), \`buildLocalBusiness\` (GPS & opening hours), \`buildSoftwareApplication\`, \`buildHowTo\`, \`buildFAQPage\`, \`buildBreadcrumbs\`.
|
|
4711
4984
|
|
|
4712
|
-
|
|
4985
|
+
9. **\uD83D\uDD0D URL Decomposition & Analysis (\`UrlyticsEngine\`):**
|
|
4713
4986
|
- Deep structural directory decomposition, depth tracking, query parameter analysis, and slug tokenization (inspired by advertools).
|
|
4714
4987
|
|
|
4715
|
-
|
|
4988
|
+
10. **⚡ SEM Keyword Combinator (\`KeywordPermutatorEngine\`):**
|
|
4716
4989
|
- Combinatorial matrix generation: Products × Modifiers × Locations with match types (\`[exact]\`, \`"phrase"\`, \`+broad\`) and intent classification.
|
|
4717
4990
|
|
|
4718
|
-
|
|
4991
|
+
11. **⚖️ Legal & Editorial Compliance (\`LegalDisclaimerEngine\`):**
|
|
4719
4992
|
- 7 SeedRank-grade disclaimer templates, 90-day staleness verification, and multi-language anti-disparagement guardian.
|
|
4720
4993
|
|
|
4721
|
-
|
|
4994
|
+
12. **\uD83D\uDCCA Telemetry & Cloud Metering (\`matrixEngine.getTelemetryPayload\` & \`LynxAnalyticsClient\`):**
|
|
4722
4995
|
- Synchronizes total programmatic pages, indexed hubs, and AI bot crawl hits (GPTBot, ClaudeBot, PerplexityBot) with the LynxSEO Studio dashboard.
|
|
4723
4996
|
|
|
4724
|
-
|
|
4997
|
+
13. **\uD83E\uDDF9 URL Slug Engine & Schema.org Graphs:**
|
|
4725
4998
|
- \`cleanSeoSlug(text, { language })\`: Strips accents, stop words across 10+ languages, and non-alphanumeric noise.
|
|
4726
4999
|
- Outputs Google-validated Schema.org JSON-LD graphs with 0 syntax errors.
|
|
4727
5000
|
`.trim();
|
package/dist/index.mjs
CHANGED
|
@@ -3815,6 +3815,38 @@ class PseoMatrixEngine {
|
|
|
3815
3815
|
}
|
|
3816
3816
|
if (data.calculators) {
|
|
3817
3817
|
allPages.push(...this.generateCalculatorMatrix(domain, data.calculators, options));
|
|
3818
|
+
} else if (options.enableFreeTools !== false) {
|
|
3819
|
+
const defaultCalculators = [
|
|
3820
|
+
{
|
|
3821
|
+
slug: "serp-preview-simulator",
|
|
3822
|
+
title: "Google SERP Snippet Preview & CTR Simulator",
|
|
3823
|
+
formulaDescription: "Simulate desktop and mobile Google search appearance and optimize CTR",
|
|
3824
|
+
savingsMetric: "Search Click-Through Rate",
|
|
3825
|
+
inputs: ["pageTitle", "metaDescription", "targetKeyword"]
|
|
3826
|
+
},
|
|
3827
|
+
{
|
|
3828
|
+
slug: "roi-calculator",
|
|
3829
|
+
title: "Automation ROI & Time-Saved Calculator",
|
|
3830
|
+
formulaDescription: "Calculate weekly operational hours recovered and monthly budget saved",
|
|
3831
|
+
savingsMetric: "Monthly Net Financial Savings",
|
|
3832
|
+
inputs: ["hoursSpentWeekly", "hourlyRate", "teamMembers"]
|
|
3833
|
+
},
|
|
3834
|
+
{
|
|
3835
|
+
slug: "seo-slug-generator",
|
|
3836
|
+
title: "SEO URL Slug Cleaner & Optimizer",
|
|
3837
|
+
formulaDescription: "Strip stop words, dates, and noise characters for high-CTR clean URLs",
|
|
3838
|
+
savingsMetric: "URL Cleanliness & Readability",
|
|
3839
|
+
inputs: ["rawTitle", "language"]
|
|
3840
|
+
},
|
|
3841
|
+
{
|
|
3842
|
+
slug: "keyword-density-checker",
|
|
3843
|
+
title: "Live Keyword Density & Readability Analyzer",
|
|
3844
|
+
formulaDescription: "Analyze n-gram frequency, reading time, and content depth",
|
|
3845
|
+
savingsMetric: "Content Optimization Score",
|
|
3846
|
+
inputs: ["articleText"]
|
|
3847
|
+
}
|
|
3848
|
+
];
|
|
3849
|
+
allPages.push(...this.generateCalculatorMatrix(domain, defaultCalculators, options));
|
|
3818
3850
|
}
|
|
3819
3851
|
for (const p of allPages) {
|
|
3820
3852
|
if (!p.ogImageUrl) {
|
|
@@ -4177,6 +4209,240 @@ function resolveFeatureIcon(featureText) {
|
|
|
4177
4209
|
}
|
|
4178
4210
|
return "zap";
|
|
4179
4211
|
}
|
|
4212
|
+
// src/free-public-tools.ts
|
|
4213
|
+
class FreePublicToolsEngine {
|
|
4214
|
+
static simulateSerpSnippet(input) {
|
|
4215
|
+
const title = (input.title || "").trim();
|
|
4216
|
+
const description = (input.description || "").trim();
|
|
4217
|
+
const url = (input.url || "https://example.com").trim();
|
|
4218
|
+
const kw = (input.targetKeyword || "").toLowerCase().trim();
|
|
4219
|
+
const titlePixelWidth = title.length * 9.5;
|
|
4220
|
+
const maxTitlePixels = 580;
|
|
4221
|
+
const maxDescChars = 158;
|
|
4222
|
+
const isTitleTruncated = titlePixelWidth > maxTitlePixels;
|
|
4223
|
+
const truncatedTitle = isTitleTruncated ? title.slice(0, 56) + "..." : title;
|
|
4224
|
+
const isDescriptionTruncated = description.length > maxDescChars;
|
|
4225
|
+
const truncatedDescription = isDescriptionTruncated ? description.slice(0, 155) + "..." : description;
|
|
4226
|
+
let ctrScore = 50;
|
|
4227
|
+
const recommendations = [];
|
|
4228
|
+
if (title.length >= 40 && title.length <= 60) {
|
|
4229
|
+
ctrScore += 20;
|
|
4230
|
+
} else if (title.length < 30) {
|
|
4231
|
+
recommendations.push("Le titre est trop court (< 30 car.). Ajoutez des précisions pour booster le clic.");
|
|
4232
|
+
} else if (isTitleTruncated) {
|
|
4233
|
+
ctrScore -= 10;
|
|
4234
|
+
recommendations.push("Le titre dépasse 580px et sera tronqué sur Google Desktop.");
|
|
4235
|
+
}
|
|
4236
|
+
if (kw && title.toLowerCase().includes(kw)) {
|
|
4237
|
+
ctrScore += 15;
|
|
4238
|
+
} else if (kw) {
|
|
4239
|
+
recommendations.push(`Le mot-clé principal "${kw}" est absent du titre.`);
|
|
4240
|
+
}
|
|
4241
|
+
if (description.length >= 120 && description.length <= 158) {
|
|
4242
|
+
ctrScore += 15;
|
|
4243
|
+
} else if (description.length < 80) {
|
|
4244
|
+
recommendations.push("La méta-description est trop courte (< 80 car.).");
|
|
4245
|
+
}
|
|
4246
|
+
return {
|
|
4247
|
+
title,
|
|
4248
|
+
truncatedTitle,
|
|
4249
|
+
titlePixelWidth: Math.round(titlePixelWidth),
|
|
4250
|
+
isTitleTruncated,
|
|
4251
|
+
description,
|
|
4252
|
+
truncatedDescription,
|
|
4253
|
+
isDescriptionTruncated,
|
|
4254
|
+
urlPreview: url,
|
|
4255
|
+
estimatedCtrScore: Math.min(Math.max(ctrScore, 10), 100),
|
|
4256
|
+
recommendations
|
|
4257
|
+
};
|
|
4258
|
+
}
|
|
4259
|
+
static calculateRoi(input) {
|
|
4260
|
+
const hours = Math.max(input.hoursSpentPerWeek || 5, 1);
|
|
4261
|
+
const rate = Math.max(input.hourlyRateOrSalary || 35, 1);
|
|
4262
|
+
const team = Math.max(input.teamMembersCount || 1, 1);
|
|
4263
|
+
const softwareCost = input.softwareMonthlyPrice ?? 49;
|
|
4264
|
+
const hoursSavedWeekly = Math.round(hours * 0.75 * team * 10) / 10;
|
|
4265
|
+
const hoursSavedMonthly = Math.round(hoursSavedWeekly * 4.33);
|
|
4266
|
+
const monthlyGrossSavings = hoursSavedMonthly * rate;
|
|
4267
|
+
const monthlyNetSavings = Math.max(monthlyGrossSavings - softwareCost, 0);
|
|
4268
|
+
const annualCostSavings = monthlyNetSavings * 12;
|
|
4269
|
+
const roiPercentage = softwareCost > 0 ? Math.round(monthlyNetSavings / softwareCost * 100) : 1000;
|
|
4270
|
+
const breakEvenDays = monthlyGrossSavings > 0 ? Math.max(Math.round(softwareCost / (monthlyGrossSavings / 30)), 1) : 30;
|
|
4271
|
+
return {
|
|
4272
|
+
hoursSavedWeekly,
|
|
4273
|
+
hoursSavedMonthly,
|
|
4274
|
+
monthlyCostSavings: Math.round(monthlyNetSavings),
|
|
4275
|
+
annualCostSavings: Math.round(annualCostSavings),
|
|
4276
|
+
roiPercentage,
|
|
4277
|
+
breakEvenDays
|
|
4278
|
+
};
|
|
4279
|
+
}
|
|
4280
|
+
static analyzeTextDensity(text, language = "fr") {
|
|
4281
|
+
if (!text || typeof text !== "string") {
|
|
4282
|
+
return { totalWords: 0, characterCount: 0, readingTimeMinutes: 0, topKeywords: [], seoReadabilityScore: 0 };
|
|
4283
|
+
}
|
|
4284
|
+
const clean = text.toLowerCase().replace(/[^a-z0-9à-ÿ\s]/g, " ");
|
|
4285
|
+
const words = clean.split(/\s+/).filter((w) => w.length > 2);
|
|
4286
|
+
const totalWords = words.length;
|
|
4287
|
+
const characterCount = text.length;
|
|
4288
|
+
const readingTimeMinutes = Math.max(Math.round(totalWords / 200 * 10) / 10, 0.5);
|
|
4289
|
+
const stopWords = new Set(["pour", "dans", "avec", "sur", "les", "des", "une", "que", "qui", "est", "par", "the", "and", "for", "with", "this", "that"]);
|
|
4290
|
+
const frequencyMap = new Map;
|
|
4291
|
+
for (const w of words) {
|
|
4292
|
+
if (!stopWords.has(w)) {
|
|
4293
|
+
frequencyMap.set(w, (frequencyMap.get(w) || 0) + 1);
|
|
4294
|
+
}
|
|
4295
|
+
}
|
|
4296
|
+
const sorted = Array.from(frequencyMap.entries()).sort((a, b) => b[1] - a[1]);
|
|
4297
|
+
const topKeywords = sorted.slice(0, 8).map(([word, count]) => ({
|
|
4298
|
+
word,
|
|
4299
|
+
count,
|
|
4300
|
+
densityPercent: totalWords > 0 ? Math.round(count / totalWords * 1000) / 10 : 0
|
|
4301
|
+
}));
|
|
4302
|
+
let seoReadabilityScore = 70;
|
|
4303
|
+
if (totalWords >= 600)
|
|
4304
|
+
seoReadabilityScore += 20;
|
|
4305
|
+
else if (totalWords < 300)
|
|
4306
|
+
seoReadabilityScore -= 25;
|
|
4307
|
+
return {
|
|
4308
|
+
totalWords,
|
|
4309
|
+
characterCount,
|
|
4310
|
+
readingTimeMinutes,
|
|
4311
|
+
topKeywords,
|
|
4312
|
+
seoReadabilityScore: Math.min(Math.max(seoReadabilityScore, 10), 100)
|
|
4313
|
+
};
|
|
4314
|
+
}
|
|
4315
|
+
static cleanSlugTool(input, lang = "fr") {
|
|
4316
|
+
const clean = cleanSeoSlug(input, { language: lang });
|
|
4317
|
+
return {
|
|
4318
|
+
original: input,
|
|
4319
|
+
cleanSlug: clean,
|
|
4320
|
+
charSavings: Math.max(input.length - clean.length, 0)
|
|
4321
|
+
};
|
|
4322
|
+
}
|
|
4323
|
+
static generateSampleSchema(type, name, url) {
|
|
4324
|
+
if (type === "localBusiness") {
|
|
4325
|
+
return ExtendedSchemaGraphBuilder.buildLocalBusiness({
|
|
4326
|
+
name,
|
|
4327
|
+
url,
|
|
4328
|
+
city: "Paris",
|
|
4329
|
+
country: "France"
|
|
4330
|
+
});
|
|
4331
|
+
}
|
|
4332
|
+
if (type === "faq") {
|
|
4333
|
+
return ExtendedSchemaGraphBuilder.buildFAQPage([
|
|
4334
|
+
{ question: `Comment fonctionne ${name} ?`, answer: `${name} automatise vos opérations en quelques clics.` },
|
|
4335
|
+
{ question: `Quel est le tarif de ${name} ?`, answer: `Un essai gratuit de 14 jours est disponible sans carte bancaire.` }
|
|
4336
|
+
]);
|
|
4337
|
+
}
|
|
4338
|
+
return ExtendedSchemaGraphBuilder.buildSoftwareApplication({
|
|
4339
|
+
name,
|
|
4340
|
+
description: `Solution logicielle professionnelle ${name}`,
|
|
4341
|
+
url,
|
|
4342
|
+
priceMonthly: 29
|
|
4343
|
+
});
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
// src/pricing-plans.ts
|
|
4347
|
+
var LYNX_PRICING_PLANS = [
|
|
4348
|
+
{
|
|
4349
|
+
id: "pro",
|
|
4350
|
+
name: "Pro Starter",
|
|
4351
|
+
badge: "Pour Indépendants & PME",
|
|
4352
|
+
isPopular: false,
|
|
4353
|
+
priceMonthlyEur: 99,
|
|
4354
|
+
priceAnnualEurMonthly: 79,
|
|
4355
|
+
description: "L'essentiel pour dominer votre marché local et capter vos premiers clients qualifiés.",
|
|
4356
|
+
limits: {
|
|
4357
|
+
sitesAllowed: 1,
|
|
4358
|
+
maxProgrammaticPages: 5000,
|
|
4359
|
+
languagesIncluded: 1,
|
|
4360
|
+
monthlyAiBotEvents: 1e4
|
|
4361
|
+
},
|
|
4362
|
+
features: [
|
|
4363
|
+
"1 Domaine connecté",
|
|
4364
|
+
"Jusqu'à 5 000 Pages Métier Indexables",
|
|
4365
|
+
"Balisage Schema.org Riches (Étoiles 4.9★, Prix, FAQ)",
|
|
4366
|
+
"Sitemap XML dynamique & Flux /llms.txt",
|
|
4367
|
+
"Maillage interne géodésique anti-pages orphelines",
|
|
4368
|
+
"Conformité légale SeedRank & Détection anti-dénigrement",
|
|
4369
|
+
"Support standard par email"
|
|
4370
|
+
],
|
|
4371
|
+
ctaLabel: "Démarrer avec Pro",
|
|
4372
|
+
ctaUrl: "/subscribe?plan=pro"
|
|
4373
|
+
},
|
|
4374
|
+
{
|
|
4375
|
+
id: "growth",
|
|
4376
|
+
name: "Growth Scale",
|
|
4377
|
+
badge: "Le Plus Populaire",
|
|
4378
|
+
isPopular: true,
|
|
4379
|
+
priceMonthlyEur: 299,
|
|
4380
|
+
priceAnnualEurMonthly: 239,
|
|
4381
|
+
description: "L'infrastructure complète pour les SaaS, E-commerces et plateformes en forte croissance.",
|
|
4382
|
+
limits: {
|
|
4383
|
+
sitesAllowed: 3,
|
|
4384
|
+
maxProgrammaticPages: 50000,
|
|
4385
|
+
languagesIncluded: 4,
|
|
4386
|
+
monthlyAiBotEvents: 1e5
|
|
4387
|
+
},
|
|
4388
|
+
features: [
|
|
4389
|
+
"3 Domaines connectés",
|
|
4390
|
+
"Jusqu'à 50 000 Pages Métier Indexables",
|
|
4391
|
+
"10 Piliers de Matrices (Local, VS, Alternatives, Cas d'usage)",
|
|
4392
|
+
"Déploiement Multilingue Automatique (FR, EN, ES, DE)",
|
|
4393
|
+
"6 Outils Publics Interactifs (Calculateurs ROI, Simulateur SERP)",
|
|
4394
|
+
"Télémétrie en temps réel des Robots IA (GPTBot, ClaudeBot)",
|
|
4395
|
+
"Génération automatique d'Images OpenGraph 1200x630px",
|
|
4396
|
+
"Connecteurs Next.js, WordPress & Cloudflare Worker",
|
|
4397
|
+
"Support prioritaire sous 24h"
|
|
4398
|
+
],
|
|
4399
|
+
ctaLabel: "Passer à l'Échelle (Essai 14 jours)",
|
|
4400
|
+
ctaUrl: "/subscribe?plan=growth"
|
|
4401
|
+
},
|
|
4402
|
+
{
|
|
4403
|
+
id: "enterprise",
|
|
4404
|
+
name: "Agency & Enterprise",
|
|
4405
|
+
badge: "Pour Agences & Grands Comptes",
|
|
4406
|
+
isPopular: false,
|
|
4407
|
+
priceMonthlyEur: 990,
|
|
4408
|
+
priceAnnualEurMonthly: 790,
|
|
4409
|
+
description: "Puissance maximale sans limites pour agences web, marketplaces et groupes internationaux.",
|
|
4410
|
+
limits: {
|
|
4411
|
+
sitesAllowed: "unlimited",
|
|
4412
|
+
maxProgrammaticPages: "unlimited",
|
|
4413
|
+
languagesIncluded: "unlimited",
|
|
4414
|
+
monthlyAiBotEvents: "unlimited"
|
|
4415
|
+
},
|
|
4416
|
+
features: [
|
|
4417
|
+
"Domaines & Sites Illimités",
|
|
4418
|
+
"Volume de Pages Illimité (1M+ pages)",
|
|
4419
|
+
"Mode Marque Blanche (White-Label Agence)",
|
|
4420
|
+
"Toutes les langues du monde supportées",
|
|
4421
|
+
"Connecteur Laravel & Infrastructure Edge Dédiée",
|
|
4422
|
+
"Audit technique en continu & Alertes SERP par webhook",
|
|
4423
|
+
"Accompagnement architectural dédié & SLA 99.99%"
|
|
4424
|
+
],
|
|
4425
|
+
ctaLabel: "Contacter l'Équipe Enterprise",
|
|
4426
|
+
ctaUrl: "/subscribe?plan=enterprise"
|
|
4427
|
+
}
|
|
4428
|
+
];
|
|
4429
|
+
|
|
4430
|
+
class PricingPolicyEngine {
|
|
4431
|
+
static computeAgencySavingsComparison(customAgencyRateEur = 3500) {
|
|
4432
|
+
const traditional = Math.max(customAgencyRateEur, 2000);
|
|
4433
|
+
const basicAi = 450;
|
|
4434
|
+
const lynxGrowth = 299;
|
|
4435
|
+
const monthlySavings = traditional - lynxGrowth;
|
|
4436
|
+
const annualSavings = monthlySavings * 12;
|
|
4437
|
+
return {
|
|
4438
|
+
traditionalAgencyMonthlyEur: traditional,
|
|
4439
|
+
basicAiToolsMonthlyEur: basicAi,
|
|
4440
|
+
lynxGrowthMonthlyEur: lynxGrowth,
|
|
4441
|
+
monthlyNetSavingsVsAgency: monthlySavings,
|
|
4442
|
+
annualNetSavingsVsAgency: annualSavings
|
|
4443
|
+
};
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4180
4446
|
// src/urlytics-engine.ts
|
|
4181
4447
|
class UrlyticsEngine {
|
|
4182
4448
|
static parseUrl(rawUrl) {
|
|
@@ -4595,22 +4861,26 @@ The SDK equips applications with 9 enterprise-grade SEO engines:
|
|
|
4595
4861
|
- \`renderDynamicOgSvg(opts)\`: Generates high-converting 1200x630 SVG social cards with glassmorphism badges, star ratings, and gradient backdrops.
|
|
4596
4862
|
- \`generateOgImageUrl(domain, pageMeta, brandName)\`: Edge-ready query URL for \`app/api/og/route.ts\`.
|
|
4597
4863
|
|
|
4598
|
-
7. **\
|
|
4864
|
+
7. **\uD83D\uDEE0️ Free Public Interactive Tools & Lead Magnets (\`FreePublicToolsEngine\`):**
|
|
4865
|
+
- Ahrefs/Semrush-style high-intent public calculators: Google SERP Preview Simulator, Automation ROI Calculator, Keyword Density Analyzer, and Schema.org Generator.
|
|
4866
|
+
- Boosts dwell time, organic backlinks, and visitor-to-customer conversion.
|
|
4867
|
+
|
|
4868
|
+
8. **\uD83C\uDFDB️ Google Schema.org Rich Graphs (\`ExtendedSchemaGraphBuilder\`):**
|
|
4599
4869
|
- \`buildAggregateRating\` (Google Gold Stars 4.9★), \`buildAggregateOffer\` (price ranges), \`buildLocalBusiness\` (GPS & opening hours), \`buildSoftwareApplication\`, \`buildHowTo\`, \`buildFAQPage\`, \`buildBreadcrumbs\`.
|
|
4600
4870
|
|
|
4601
|
-
|
|
4871
|
+
9. **\uD83D\uDD0D URL Decomposition & Analysis (\`UrlyticsEngine\`):**
|
|
4602
4872
|
- Deep structural directory decomposition, depth tracking, query parameter analysis, and slug tokenization (inspired by advertools).
|
|
4603
4873
|
|
|
4604
|
-
|
|
4874
|
+
10. **⚡ SEM Keyword Combinator (\`KeywordPermutatorEngine\`):**
|
|
4605
4875
|
- Combinatorial matrix generation: Products × Modifiers × Locations with match types (\`[exact]\`, \`"phrase"\`, \`+broad\`) and intent classification.
|
|
4606
4876
|
|
|
4607
|
-
|
|
4877
|
+
11. **⚖️ Legal & Editorial Compliance (\`LegalDisclaimerEngine\`):**
|
|
4608
4878
|
- 7 SeedRank-grade disclaimer templates, 90-day staleness verification, and multi-language anti-disparagement guardian.
|
|
4609
4879
|
|
|
4610
|
-
|
|
4880
|
+
12. **\uD83D\uDCCA Telemetry & Cloud Metering (\`matrixEngine.getTelemetryPayload\` & \`LynxAnalyticsClient\`):**
|
|
4611
4881
|
- Synchronizes total programmatic pages, indexed hubs, and AI bot crawl hits (GPTBot, ClaudeBot, PerplexityBot) with the LynxSEO Studio dashboard.
|
|
4612
4882
|
|
|
4613
|
-
|
|
4883
|
+
13. **\uD83E\uDDF9 URL Slug Engine & Schema.org Graphs:**
|
|
4614
4884
|
- \`cleanSeoSlug(text, { language })\`: Strips accents, stop words across 10+ languages, and non-alphanumeric noise.
|
|
4615
4885
|
- Outputs Google-validated Schema.org JSON-LD graphs with 0 syntax errors.
|
|
4616
4886
|
`.trim();
|
|
@@ -6789,6 +7059,7 @@ export {
|
|
|
6789
7059
|
RealReviewsSyncEngine,
|
|
6790
7060
|
RankMathParityEngine,
|
|
6791
7061
|
PseoMatrixEngine,
|
|
7062
|
+
PricingPolicyEngine,
|
|
6792
7063
|
PSEO_AGENT_SYSTEM_PROMPT,
|
|
6793
7064
|
OgImageGenerator,
|
|
6794
7065
|
NGramDensityAnalyzer,
|
|
@@ -6803,6 +7074,7 @@ export {
|
|
|
6803
7074
|
LlmContentCleaner,
|
|
6804
7075
|
LegalDisclaimerEngine,
|
|
6805
7076
|
LagoTokenMeter,
|
|
7077
|
+
LYNX_PRICING_PLANS,
|
|
6806
7078
|
KnowledgeGraphLinker,
|
|
6807
7079
|
KeywordPermutatorEngine,
|
|
6808
7080
|
IsrCacheManager,
|
|
@@ -6811,6 +7083,7 @@ export {
|
|
|
6811
7083
|
I18nDetector,
|
|
6812
7084
|
HyperswitchGateway,
|
|
6813
7085
|
GeoMeshLinkingEngine,
|
|
7086
|
+
FreePublicToolsEngine,
|
|
6814
7087
|
ExtendedSchemaGraphBuilder,
|
|
6815
7088
|
EmbeddableSeoWidgetGenerator,
|
|
6816
7089
|
DeepCrawlerAuditor,
|
package/dist/matrix-engine.d.ts
CHANGED
|
@@ -95,6 +95,7 @@ export interface PseoCalculator {
|
|
|
95
95
|
title: string;
|
|
96
96
|
formulaDescription: string;
|
|
97
97
|
savingsMetric: string;
|
|
98
|
+
inputs?: string[];
|
|
98
99
|
}
|
|
99
100
|
export interface SchemaOrgGraph {
|
|
100
101
|
"@context": "https://schema.org";
|
|
@@ -132,6 +133,7 @@ export interface MatrixOptions {
|
|
|
132
133
|
countries?: string[] | string;
|
|
133
134
|
territories?: string[] | string;
|
|
134
135
|
cleanDirectRoutes?: boolean;
|
|
136
|
+
enableFreeTools?: boolean;
|
|
135
137
|
minPopulationToIndex?: number;
|
|
136
138
|
defaultCurrency?: string;
|
|
137
139
|
defaultCurrencySymbol?: string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 💎 LynxSEO Official Enterprise Pricing & Subscription Tiers
|
|
3
|
+
* Defines the 3 core commercial tiers (Pro, Growth, Enterprise/Agency) with feature matrix,
|
|
4
|
+
* monthly/annual billing models, and ROI value calculator.
|
|
5
|
+
*/
|
|
6
|
+
export interface PricingPlan {
|
|
7
|
+
id: "pro" | "growth" | "enterprise";
|
|
8
|
+
name: string;
|
|
9
|
+
badge?: string;
|
|
10
|
+
isPopular?: boolean;
|
|
11
|
+
priceMonthlyEur: number;
|
|
12
|
+
priceAnnualEurMonthly: number;
|
|
13
|
+
description: string;
|
|
14
|
+
limits: {
|
|
15
|
+
sitesAllowed: number | "unlimited";
|
|
16
|
+
maxProgrammaticPages: number | "unlimited";
|
|
17
|
+
languagesIncluded: number | "unlimited";
|
|
18
|
+
monthlyAiBotEvents: number | "unlimited";
|
|
19
|
+
};
|
|
20
|
+
features: string[];
|
|
21
|
+
ctaLabel: string;
|
|
22
|
+
ctaUrl: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const LYNX_PRICING_PLANS: PricingPlan[];
|
|
25
|
+
export interface AgencyCostComparison {
|
|
26
|
+
traditionalAgencyMonthlyEur: number;
|
|
27
|
+
basicAiToolsMonthlyEur: number;
|
|
28
|
+
lynxGrowthMonthlyEur: number;
|
|
29
|
+
monthlyNetSavingsVsAgency: number;
|
|
30
|
+
annualNetSavingsVsAgency: number;
|
|
31
|
+
}
|
|
32
|
+
export declare class PricingPolicyEngine {
|
|
33
|
+
/**
|
|
34
|
+
* Compares the financial ROI of LynxSEO Growth Plan vs Traditional SEO Agencies.
|
|
35
|
+
*/
|
|
36
|
+
static computeAgencySavingsComparison(customAgencyRateEur?: number): AgencyCostComparison;
|
|
37
|
+
}
|
package/package.json
CHANGED
package/src/engine.test.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { renderBrandIconSvg } from "./brand-icons";
|
|
|
10
10
|
import { I18nDetector } from "./i18n-detector";
|
|
11
11
|
import { renderUiIconSvg, resolveFeatureIcon } from "./ui-icons";
|
|
12
12
|
import { OgImageGenerator } from "./og-image-generator";
|
|
13
|
+
import { FreePublicToolsEngine } from "./free-public-tools";
|
|
13
14
|
|
|
14
15
|
describe("Multilingual SEO Slug Engine (10+ Languages)", () => {
|
|
15
16
|
it("English: Strips stop words and years", () => {
|
|
@@ -306,4 +307,34 @@ describe("Audited Reference Engines (Advertools, Santifer, Seonaut)", () => {
|
|
|
306
307
|
expect(page?.ogImageUrl).toContain("/api/og?");
|
|
307
308
|
expect(page?.ogImageUrl).toContain("brand=Acme");
|
|
308
309
|
});
|
|
310
|
+
|
|
311
|
+
it("FreePublicToolsEngine: Simulates SERP, calculates ROI, and analyzes density", () => {
|
|
312
|
+
const serp = FreePublicToolsEngine.simulateSerpSnippet({
|
|
313
|
+
title: "Autopost Facebook & Instagram Tool 2026",
|
|
314
|
+
description: "Automate your social media scheduling across all major networks with AI copilot and analytics.",
|
|
315
|
+
url: "https://acme.com/autopost-facebook",
|
|
316
|
+
targetKeyword: "autopost",
|
|
317
|
+
});
|
|
318
|
+
expect(serp.estimatedCtrScore).toBeGreaterThan(50);
|
|
319
|
+
expect(serp.titlePixelWidth).toBeGreaterThan(0);
|
|
320
|
+
|
|
321
|
+
const roi = FreePublicToolsEngine.calculateRoi({
|
|
322
|
+
hoursSpentPerWeek: 10,
|
|
323
|
+
hourlyRateOrSalary: 50,
|
|
324
|
+
teamMembersCount: 2,
|
|
325
|
+
softwareMonthlyPrice: 79,
|
|
326
|
+
});
|
|
327
|
+
expect(roi.monthlyCostSavings).toBeGreaterThan(1000);
|
|
328
|
+
expect(roi.roiPercentage).toBeGreaterThan(100);
|
|
329
|
+
|
|
330
|
+
const density = FreePublicToolsEngine.analyzeTextDensity(
|
|
331
|
+
"Autopost Facebook automatise vos réseaux sociaux. Notre outil autopost vous fait gagner du temps avec autopost.",
|
|
332
|
+
"fr",
|
|
333
|
+
);
|
|
334
|
+
expect(density.totalWords).toBeGreaterThan(5);
|
|
335
|
+
expect(density.topKeywords[0].word).toBe("autopost");
|
|
336
|
+
|
|
337
|
+
const schema = FreePublicToolsEngine.generateSampleSchema("softwareApp", "Acme", "https://acme.com");
|
|
338
|
+
expect(schema["@type"]).toBe("SoftwareApplication");
|
|
339
|
+
});
|
|
309
340
|
});
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🛠️ Free Public Interactive Tools & Lead Magnets Suite
|
|
3
|
+
* Inspired by Ahrefs, Semrush, Moz, and WordStream free tool ecosystems.
|
|
4
|
+
*
|
|
5
|
+
* Provides 6 zero-dependency interactive calculators and simulators that can be embedded
|
|
6
|
+
* on public programmatic pages to maximize dwell time, engagement, backlink acquisition, and user conversion.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { cleanSeoSlug } from "./slug-engine";
|
|
10
|
+
import { ExtendedSchemaGraphBuilder } from "./extended-schemas";
|
|
11
|
+
|
|
12
|
+
export interface SerpSimulatorResult {
|
|
13
|
+
title: string;
|
|
14
|
+
truncatedTitle: string;
|
|
15
|
+
titlePixelWidth: number;
|
|
16
|
+
isTitleTruncated: boolean;
|
|
17
|
+
description: string;
|
|
18
|
+
truncatedDescription: string;
|
|
19
|
+
isDescriptionTruncated: boolean;
|
|
20
|
+
urlPreview: string;
|
|
21
|
+
estimatedCtrScore: number; // 0 to 100
|
|
22
|
+
recommendations: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface RoiCalculatorResult {
|
|
26
|
+
hoursSavedWeekly: number;
|
|
27
|
+
hoursSavedMonthly: number;
|
|
28
|
+
monthlyCostSavings: number;
|
|
29
|
+
annualCostSavings: number;
|
|
30
|
+
roiPercentage: number;
|
|
31
|
+
breakEvenDays: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface DensityAnalysisResult {
|
|
35
|
+
totalWords: number;
|
|
36
|
+
characterCount: number;
|
|
37
|
+
readingTimeMinutes: number;
|
|
38
|
+
topKeywords: { word: string; count: number; densityPercent: number }[];
|
|
39
|
+
seoReadabilityScore: number; // 0 to 100
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class FreePublicToolsEngine {
|
|
43
|
+
/**
|
|
44
|
+
* 1. Google SERP Preview & CTR Optimizer Simulator (Ahrefs / Moz Parity)
|
|
45
|
+
*/
|
|
46
|
+
static simulateSerpSnippet(input: {
|
|
47
|
+
title: string;
|
|
48
|
+
description: string;
|
|
49
|
+
url: string;
|
|
50
|
+
targetKeyword?: string;
|
|
51
|
+
}): SerpSimulatorResult {
|
|
52
|
+
const title = (input.title || "").trim();
|
|
53
|
+
const description = (input.description || "").trim();
|
|
54
|
+
const url = (input.url || "https://example.com").trim();
|
|
55
|
+
const kw = (input.targetKeyword || "").toLowerCase().trim();
|
|
56
|
+
|
|
57
|
+
// Average pixel width estimation (approx 10px per char on Arial 20px)
|
|
58
|
+
const titlePixelWidth = title.length * 9.5;
|
|
59
|
+
const maxTitlePixels = 580; // Google Desktop breakpoint
|
|
60
|
+
const maxDescChars = 158;
|
|
61
|
+
|
|
62
|
+
const isTitleTruncated = titlePixelWidth > maxTitlePixels;
|
|
63
|
+
const truncatedTitle = isTitleTruncated ? title.slice(0, 56) + "..." : title;
|
|
64
|
+
|
|
65
|
+
const isDescriptionTruncated = description.length > maxDescChars;
|
|
66
|
+
const truncatedDescription = isDescriptionTruncated ? description.slice(0, 155) + "..." : description;
|
|
67
|
+
|
|
68
|
+
let ctrScore = 50;
|
|
69
|
+
const recommendations: string[] = [];
|
|
70
|
+
|
|
71
|
+
// Title checks
|
|
72
|
+
if (title.length >= 40 && title.length <= 60) {
|
|
73
|
+
ctrScore += 20;
|
|
74
|
+
} else if (title.length < 30) {
|
|
75
|
+
recommendations.push("Le titre est trop court (< 30 car.). Ajoutez des précisions pour booster le clic.");
|
|
76
|
+
} else if (isTitleTruncated) {
|
|
77
|
+
ctrScore -= 10;
|
|
78
|
+
recommendations.push("Le titre dépasse 580px et sera tronqué sur Google Desktop.");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Keyword presence
|
|
82
|
+
if (kw && title.toLowerCase().includes(kw)) {
|
|
83
|
+
ctrScore += 15;
|
|
84
|
+
} else if (kw) {
|
|
85
|
+
recommendations.push(`Le mot-clé principal "${kw}" est absent du titre.`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Description checks
|
|
89
|
+
if (description.length >= 120 && description.length <= 158) {
|
|
90
|
+
ctrScore += 15;
|
|
91
|
+
} else if (description.length < 80) {
|
|
92
|
+
recommendations.push("La méta-description est trop courte (< 80 car.).");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
title,
|
|
97
|
+
truncatedTitle,
|
|
98
|
+
titlePixelWidth: Math.round(titlePixelWidth),
|
|
99
|
+
isTitleTruncated,
|
|
100
|
+
description,
|
|
101
|
+
truncatedDescription,
|
|
102
|
+
isDescriptionTruncated,
|
|
103
|
+
urlPreview: url,
|
|
104
|
+
estimatedCtrScore: Math.min(Math.max(ctrScore, 10), 100),
|
|
105
|
+
recommendations,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 2. Free ROI & Time-Saved Automation Calculator
|
|
111
|
+
*/
|
|
112
|
+
static calculateRoi(input: {
|
|
113
|
+
hoursSpentPerWeek: number;
|
|
114
|
+
hourlyRateOrSalary: number;
|
|
115
|
+
teamMembersCount?: number;
|
|
116
|
+
softwareMonthlyPrice?: number;
|
|
117
|
+
}): RoiCalculatorResult {
|
|
118
|
+
const hours = Math.max(input.hoursSpentPerWeek || 5, 1);
|
|
119
|
+
const rate = Math.max(input.hourlyRateOrSalary || 35, 1);
|
|
120
|
+
const team = Math.max(input.teamMembersCount || 1, 1);
|
|
121
|
+
const softwareCost = input.softwareMonthlyPrice ?? 49;
|
|
122
|
+
|
|
123
|
+
// Assuming automation saves ~75% of manual operational time
|
|
124
|
+
const hoursSavedWeekly = Math.round(hours * 0.75 * team * 10) / 10;
|
|
125
|
+
const hoursSavedMonthly = Math.round(hoursSavedWeekly * 4.33);
|
|
126
|
+
|
|
127
|
+
const monthlyGrossSavings = hoursSavedMonthly * rate;
|
|
128
|
+
const monthlyNetSavings = Math.max(monthlyGrossSavings - softwareCost, 0);
|
|
129
|
+
const annualCostSavings = monthlyNetSavings * 12;
|
|
130
|
+
|
|
131
|
+
const roiPercentage = softwareCost > 0 ? Math.round((monthlyNetSavings / softwareCost) * 100) : 1000;
|
|
132
|
+
const breakEvenDays = monthlyGrossSavings > 0 ? Math.max(Math.round((softwareCost / (monthlyGrossSavings / 30))), 1) : 30;
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
hoursSavedWeekly,
|
|
136
|
+
hoursSavedMonthly,
|
|
137
|
+
monthlyCostSavings: Math.round(monthlyNetSavings),
|
|
138
|
+
annualCostSavings: Math.round(annualCostSavings),
|
|
139
|
+
roiPercentage,
|
|
140
|
+
breakEvenDays,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 3. Instant Keyword Density & Readability Analyzer
|
|
146
|
+
*/
|
|
147
|
+
static analyzeTextDensity(text: string, language: string = "fr"): DensityAnalysisResult {
|
|
148
|
+
if (!text || typeof text !== "string") {
|
|
149
|
+
return { totalWords: 0, characterCount: 0, readingTimeMinutes: 0, topKeywords: [], seoReadabilityScore: 0 };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const clean = text.toLowerCase().replace(/[^a-z0-9à-ÿ\s]/g, " ");
|
|
153
|
+
const words = clean.split(/\s+/).filter((w) => w.length > 2);
|
|
154
|
+
const totalWords = words.length;
|
|
155
|
+
const characterCount = text.length;
|
|
156
|
+
const readingTimeMinutes = Math.max(Math.round((totalWords / 200) * 10) / 10, 0.5);
|
|
157
|
+
|
|
158
|
+
const stopWords = new Set(["pour", "dans", "avec", "sur", "les", "des", "une", "que", "qui", "est", "par", "the", "and", "for", "with", "this", "that"]);
|
|
159
|
+
const frequencyMap = new Map<string, number>();
|
|
160
|
+
|
|
161
|
+
for (const w of words) {
|
|
162
|
+
if (!stopWords.has(w)) {
|
|
163
|
+
frequencyMap.set(w, (frequencyMap.get(w) || 0) + 1);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const sorted = Array.from(frequencyMap.entries()).sort((a, b) => b[1] - a[1]);
|
|
168
|
+
const topKeywords = sorted.slice(0, 8).map(([word, count]) => ({
|
|
169
|
+
word,
|
|
170
|
+
count,
|
|
171
|
+
densityPercent: totalWords > 0 ? Math.round((count / totalWords) * 1000) / 10 : 0,
|
|
172
|
+
}));
|
|
173
|
+
|
|
174
|
+
let seoReadabilityScore = 70;
|
|
175
|
+
if (totalWords >= 600) seoReadabilityScore += 20;
|
|
176
|
+
else if (totalWords < 300) seoReadabilityScore -= 25;
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
totalWords,
|
|
180
|
+
characterCount,
|
|
181
|
+
readingTimeMinutes,
|
|
182
|
+
topKeywords,
|
|
183
|
+
seoReadabilityScore: Math.min(Math.max(seoReadabilityScore, 10), 100),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 4. Free SEO Slug Cleanser Helper
|
|
189
|
+
*/
|
|
190
|
+
static cleanSlugTool(input: string, lang: string = "fr"): { original: string; cleanSlug: string; charSavings: number } {
|
|
191
|
+
const clean = cleanSeoSlug(input, { language: lang });
|
|
192
|
+
return {
|
|
193
|
+
original: input,
|
|
194
|
+
cleanSlug: clean,
|
|
195
|
+
charSavings: Math.max(input.length - clean.length, 0),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 5. Free Schema.org Generator Helper
|
|
201
|
+
*/
|
|
202
|
+
static generateSampleSchema(type: "localBusiness" | "softwareApp" | "faq", name: string, url: string): Record<string, unknown> {
|
|
203
|
+
if (type === "localBusiness") {
|
|
204
|
+
return ExtendedSchemaGraphBuilder.buildLocalBusiness({
|
|
205
|
+
name,
|
|
206
|
+
url,
|
|
207
|
+
city: "Paris",
|
|
208
|
+
country: "France",
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (type === "faq") {
|
|
212
|
+
return ExtendedSchemaGraphBuilder.buildFAQPage([
|
|
213
|
+
{ question: `Comment fonctionne ${name} ?`, answer: `${name} automatise vos opérations en quelques clics.` },
|
|
214
|
+
{ question: `Quel est le tarif de ${name} ?`, answer: `Un essai gratuit de 14 jours est disponible sans carte bancaire.` },
|
|
215
|
+
]);
|
|
216
|
+
}
|
|
217
|
+
return ExtendedSchemaGraphBuilder.buildSoftwareApplication({
|
|
218
|
+
name,
|
|
219
|
+
description: `Solution logicielle professionnelle ${name}`,
|
|
220
|
+
url,
|
|
221
|
+
priceMonthly: 29,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,8 @@ export * from "./i18n-detector";
|
|
|
19
19
|
export * from "./brand-icons";
|
|
20
20
|
export * from "./ui-icons";
|
|
21
21
|
export * from "./og-image-generator";
|
|
22
|
+
export * from "./free-public-tools";
|
|
23
|
+
export * from "./pricing-plans";
|
|
22
24
|
export * from "./urlytics-engine";
|
|
23
25
|
export * from "./keyword-permutator";
|
|
24
26
|
export * from "./llm-prompt";
|
package/src/llm-prompt.ts
CHANGED
|
@@ -283,22 +283,26 @@ The SDK equips applications with 9 enterprise-grade SEO engines:
|
|
|
283
283
|
- \`renderDynamicOgSvg(opts)\`: Generates high-converting 1200x630 SVG social cards with glassmorphism badges, star ratings, and gradient backdrops.
|
|
284
284
|
- \`generateOgImageUrl(domain, pageMeta, brandName)\`: Edge-ready query URL for \`app/api/og/route.ts\`.
|
|
285
285
|
|
|
286
|
-
7.
|
|
286
|
+
7. **🛠️ Free Public Interactive Tools & Lead Magnets (\`FreePublicToolsEngine\`):**
|
|
287
|
+
- Ahrefs/Semrush-style high-intent public calculators: Google SERP Preview Simulator, Automation ROI Calculator, Keyword Density Analyzer, and Schema.org Generator.
|
|
288
|
+
- Boosts dwell time, organic backlinks, and visitor-to-customer conversion.
|
|
289
|
+
|
|
290
|
+
8. **🏛️ Google Schema.org Rich Graphs (\`ExtendedSchemaGraphBuilder\`):**
|
|
287
291
|
- \`buildAggregateRating\` (Google Gold Stars 4.9★), \`buildAggregateOffer\` (price ranges), \`buildLocalBusiness\` (GPS & opening hours), \`buildSoftwareApplication\`, \`buildHowTo\`, \`buildFAQPage\`, \`buildBreadcrumbs\`.
|
|
288
292
|
|
|
289
|
-
|
|
293
|
+
9. **🔍 URL Decomposition & Analysis (\`UrlyticsEngine\`):**
|
|
290
294
|
- Deep structural directory decomposition, depth tracking, query parameter analysis, and slug tokenization (inspired by advertools).
|
|
291
295
|
|
|
292
|
-
|
|
296
|
+
10. **⚡ SEM Keyword Combinator (\`KeywordPermutatorEngine\`):**
|
|
293
297
|
- Combinatorial matrix generation: Products × Modifiers × Locations with match types (\`[exact]\`, \`"phrase"\`, \`+broad\`) and intent classification.
|
|
294
298
|
|
|
295
|
-
|
|
299
|
+
11. **⚖️ Legal & Editorial Compliance (\`LegalDisclaimerEngine\`):**
|
|
296
300
|
- 7 SeedRank-grade disclaimer templates, 90-day staleness verification, and multi-language anti-disparagement guardian.
|
|
297
301
|
|
|
298
|
-
|
|
302
|
+
12. **📊 Telemetry & Cloud Metering (\`matrixEngine.getTelemetryPayload\` & \`LynxAnalyticsClient\`):**
|
|
299
303
|
- Synchronizes total programmatic pages, indexed hubs, and AI bot crawl hits (GPTBot, ClaudeBot, PerplexityBot) with the LynxSEO Studio dashboard.
|
|
300
304
|
|
|
301
|
-
|
|
305
|
+
13. **🧹 URL Slug Engine & Schema.org Graphs:**
|
|
302
306
|
- \`cleanSeoSlug(text, { language })\`: Strips accents, stop words across 10+ languages, and non-alphanumeric noise.
|
|
303
307
|
- Outputs Google-validated Schema.org JSON-LD graphs with 0 syntax errors.
|
|
304
308
|
`.trim();
|
package/src/matrix-engine.ts
CHANGED
|
@@ -125,6 +125,7 @@ export interface PseoCalculator {
|
|
|
125
125
|
title: string;
|
|
126
126
|
formulaDescription: string;
|
|
127
127
|
savingsMetric: string;
|
|
128
|
+
inputs?: string[];
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
export interface SchemaOrgGraph {
|
|
@@ -162,6 +163,7 @@ export interface MatrixOptions {
|
|
|
162
163
|
countries?: string[] | string; // e.g. ["france", "spain"] or "europe" or "international"
|
|
163
164
|
territories?: string[] | string; // Alias for countries
|
|
164
165
|
cleanDirectRoutes?: boolean; // When true (default), eliminates parasite words (/solutions/, etc.) for direct /{service}/{city}
|
|
166
|
+
enableFreeTools?: boolean; // When true (default), auto-generates 5 high-converting interactive tools like Ahrefs
|
|
165
167
|
minPopulationToIndex?: number;
|
|
166
168
|
defaultCurrency?: string;
|
|
167
169
|
defaultCurrencySymbol?: string;
|
|
@@ -824,6 +826,38 @@ export class PseoMatrixEngine {
|
|
|
824
826
|
}
|
|
825
827
|
if (data.calculators) {
|
|
826
828
|
allPages.push(...this.generateCalculatorMatrix(domain, data.calculators, options));
|
|
829
|
+
} else if (options.enableFreeTools !== false) {
|
|
830
|
+
const defaultCalculators: PseoCalculator[] = [
|
|
831
|
+
{
|
|
832
|
+
slug: "serp-preview-simulator",
|
|
833
|
+
title: "Google SERP Snippet Preview & CTR Simulator",
|
|
834
|
+
formulaDescription: "Simulate desktop and mobile Google search appearance and optimize CTR",
|
|
835
|
+
savingsMetric: "Search Click-Through Rate",
|
|
836
|
+
inputs: ["pageTitle", "metaDescription", "targetKeyword"],
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
slug: "roi-calculator",
|
|
840
|
+
title: "Automation ROI & Time-Saved Calculator",
|
|
841
|
+
formulaDescription: "Calculate weekly operational hours recovered and monthly budget saved",
|
|
842
|
+
savingsMetric: "Monthly Net Financial Savings",
|
|
843
|
+
inputs: ["hoursSpentWeekly", "hourlyRate", "teamMembers"],
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
slug: "seo-slug-generator",
|
|
847
|
+
title: "SEO URL Slug Cleaner & Optimizer",
|
|
848
|
+
formulaDescription: "Strip stop words, dates, and noise characters for high-CTR clean URLs",
|
|
849
|
+
savingsMetric: "URL Cleanliness & Readability",
|
|
850
|
+
inputs: ["rawTitle", "language"],
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
slug: "keyword-density-checker",
|
|
854
|
+
title: "Live Keyword Density & Readability Analyzer",
|
|
855
|
+
formulaDescription: "Analyze n-gram frequency, reading time, and content depth",
|
|
856
|
+
savingsMetric: "Content Optimization Score",
|
|
857
|
+
inputs: ["articleText"],
|
|
858
|
+
},
|
|
859
|
+
];
|
|
860
|
+
allPages.push(...this.generateCalculatorMatrix(domain, defaultCalculators, options));
|
|
827
861
|
}
|
|
828
862
|
|
|
829
863
|
for (const p of allPages) {
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 💎 LynxSEO Official Enterprise Pricing & Subscription Tiers
|
|
3
|
+
* Defines the 3 core commercial tiers (Pro, Growth, Enterprise/Agency) with feature matrix,
|
|
4
|
+
* monthly/annual billing models, and ROI value calculator.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface PricingPlan {
|
|
8
|
+
id: "pro" | "growth" | "enterprise";
|
|
9
|
+
name: string;
|
|
10
|
+
badge?: string;
|
|
11
|
+
isPopular?: boolean;
|
|
12
|
+
priceMonthlyEur: number;
|
|
13
|
+
priceAnnualEurMonthly: number; // Discounted monthly rate when billed annually (-20%)
|
|
14
|
+
description: string;
|
|
15
|
+
limits: {
|
|
16
|
+
sitesAllowed: number | "unlimited";
|
|
17
|
+
maxProgrammaticPages: number | "unlimited";
|
|
18
|
+
languagesIncluded: number | "unlimited";
|
|
19
|
+
monthlyAiBotEvents: number | "unlimited";
|
|
20
|
+
};
|
|
21
|
+
features: string[];
|
|
22
|
+
ctaLabel: string;
|
|
23
|
+
ctaUrl: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const LYNX_PRICING_PLANS: PricingPlan[] = [
|
|
27
|
+
{
|
|
28
|
+
id: "pro",
|
|
29
|
+
name: "Pro Starter",
|
|
30
|
+
badge: "Pour Indépendants & PME",
|
|
31
|
+
isPopular: false,
|
|
32
|
+
priceMonthlyEur: 99,
|
|
33
|
+
priceAnnualEurMonthly: 79,
|
|
34
|
+
description: "L'essentiel pour dominer votre marché local et capter vos premiers clients qualifiés.",
|
|
35
|
+
limits: {
|
|
36
|
+
sitesAllowed: 1,
|
|
37
|
+
maxProgrammaticPages: 5_000,
|
|
38
|
+
languagesIncluded: 1,
|
|
39
|
+
monthlyAiBotEvents: 10_000,
|
|
40
|
+
},
|
|
41
|
+
features: [
|
|
42
|
+
"1 Domaine connecté",
|
|
43
|
+
"Jusqu'à 5 000 Pages Métier Indexables",
|
|
44
|
+
"Balisage Schema.org Riches (Étoiles 4.9★, Prix, FAQ)",
|
|
45
|
+
"Sitemap XML dynamique & Flux /llms.txt",
|
|
46
|
+
"Maillage interne géodésique anti-pages orphelines",
|
|
47
|
+
"Conformité légale SeedRank & Détection anti-dénigrement",
|
|
48
|
+
"Support standard par email",
|
|
49
|
+
],
|
|
50
|
+
ctaLabel: "Démarrer avec Pro",
|
|
51
|
+
ctaUrl: "/subscribe?plan=pro",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "growth",
|
|
55
|
+
name: "Growth Scale",
|
|
56
|
+
badge: "Le Plus Populaire",
|
|
57
|
+
isPopular: true,
|
|
58
|
+
priceMonthlyEur: 299,
|
|
59
|
+
priceAnnualEurMonthly: 239,
|
|
60
|
+
description: "L'infrastructure complète pour les SaaS, E-commerces et plateformes en forte croissance.",
|
|
61
|
+
limits: {
|
|
62
|
+
sitesAllowed: 3,
|
|
63
|
+
maxProgrammaticPages: 50_000,
|
|
64
|
+
languagesIncluded: 4,
|
|
65
|
+
monthlyAiBotEvents: 100_000,
|
|
66
|
+
},
|
|
67
|
+
features: [
|
|
68
|
+
"3 Domaines connectés",
|
|
69
|
+
"Jusqu'à 50 000 Pages Métier Indexables",
|
|
70
|
+
"10 Piliers de Matrices (Local, VS, Alternatives, Cas d'usage)",
|
|
71
|
+
"Déploiement Multilingue Automatique (FR, EN, ES, DE)",
|
|
72
|
+
"6 Outils Publics Interactifs (Calculateurs ROI, Simulateur SERP)",
|
|
73
|
+
"Télémétrie en temps réel des Robots IA (GPTBot, ClaudeBot)",
|
|
74
|
+
"Génération automatique d'Images OpenGraph 1200x630px",
|
|
75
|
+
"Connecteurs Next.js, WordPress & Cloudflare Worker",
|
|
76
|
+
"Support prioritaire sous 24h",
|
|
77
|
+
],
|
|
78
|
+
ctaLabel: "Passer à l'Échelle (Essai 14 jours)",
|
|
79
|
+
ctaUrl: "/subscribe?plan=growth",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "enterprise",
|
|
83
|
+
name: "Agency & Enterprise",
|
|
84
|
+
badge: "Pour Agences & Grands Comptes",
|
|
85
|
+
isPopular: false,
|
|
86
|
+
priceMonthlyEur: 990,
|
|
87
|
+
priceAnnualEurMonthly: 790,
|
|
88
|
+
description: "Puissance maximale sans limites pour agences web, marketplaces et groupes internationaux.",
|
|
89
|
+
limits: {
|
|
90
|
+
sitesAllowed: "unlimited",
|
|
91
|
+
maxProgrammaticPages: "unlimited",
|
|
92
|
+
languagesIncluded: "unlimited",
|
|
93
|
+
monthlyAiBotEvents: "unlimited",
|
|
94
|
+
},
|
|
95
|
+
features: [
|
|
96
|
+
"Domaines & Sites Illimités",
|
|
97
|
+
"Volume de Pages Illimité (1M+ pages)",
|
|
98
|
+
"Mode Marque Blanche (White-Label Agence)",
|
|
99
|
+
"Toutes les langues du monde supportées",
|
|
100
|
+
"Connecteur Laravel & Infrastructure Edge Dédiée",
|
|
101
|
+
"Audit technique en continu & Alertes SERP par webhook",
|
|
102
|
+
"Accompagnement architectural dédié & SLA 99.99%",
|
|
103
|
+
],
|
|
104
|
+
ctaLabel: "Contacter l'Équipe Enterprise",
|
|
105
|
+
ctaUrl: "/subscribe?plan=enterprise",
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
export interface AgencyCostComparison {
|
|
110
|
+
traditionalAgencyMonthlyEur: number;
|
|
111
|
+
basicAiToolsMonthlyEur: number;
|
|
112
|
+
lynxGrowthMonthlyEur: number;
|
|
113
|
+
monthlyNetSavingsVsAgency: number;
|
|
114
|
+
annualNetSavingsVsAgency: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export class PricingPolicyEngine {
|
|
118
|
+
/**
|
|
119
|
+
* Compares the financial ROI of LynxSEO Growth Plan vs Traditional SEO Agencies.
|
|
120
|
+
*/
|
|
121
|
+
static computeAgencySavingsComparison(customAgencyRateEur = 3500): AgencyCostComparison {
|
|
122
|
+
const traditional = Math.max(customAgencyRateEur, 2000);
|
|
123
|
+
const basicAi = 450; // Multiple AI copywriting subscriptions + manual editing payroll
|
|
124
|
+
const lynxGrowth = 299;
|
|
125
|
+
|
|
126
|
+
const monthlySavings = traditional - lynxGrowth;
|
|
127
|
+
const annualSavings = monthlySavings * 12;
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
traditionalAgencyMonthlyEur: traditional,
|
|
131
|
+
basicAiToolsMonthlyEur: basicAi,
|
|
132
|
+
lynxGrowthMonthlyEur: lynxGrowth,
|
|
133
|
+
monthlyNetSavingsVsAgency: monthlySavings,
|
|
134
|
+
annualNetSavingsVsAgency: annualSavings,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|