@lynxflow/seo-engine 1.8.2 → 1.8.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/connectors/wordpress/lynxseo-admin-app.js +25 -0
- package/connectors/wordpress/lynxseo-connector.php +24 -0
- package/connectors/wordpress/lynxseo-connector.zip +0 -0
- package/dist/extended-schemas.d.ts +2 -2
- package/dist/index.js +698 -338
- package/dist/index.mjs +10 -7
- package/package.json +1 -1
- package/src/extended-schemas.ts +8 -4
- package/src/features-knowledge-harvester.ts +190 -0
- package/src/index.ts +2 -1
- package/src/og-image-generator.ts +5 -5
- package/src/power-words-psychology.ts +269 -160
package/dist/index.js
CHANGED
|
@@ -1,120 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
function __accessProp(key) {
|
|
6
|
-
return this[key];
|
|
7
|
-
}
|
|
8
|
-
var __toCommonJS = (from) => {
|
|
9
|
-
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
10
|
-
if (entry)
|
|
11
|
-
return entry;
|
|
12
|
-
entry = __defProp({}, "__esModule", { value: true });
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (var key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(entry, key))
|
|
16
|
-
__defProp(entry, key, {
|
|
17
|
-
get: __accessProp.bind(from, key),
|
|
18
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
__moduleCache.set(from, entry);
|
|
22
|
-
return entry;
|
|
23
|
-
};
|
|
24
|
-
var __moduleCache;
|
|
25
|
-
var __returnValue = (v) => v;
|
|
26
|
-
function __exportSetter(name, newValue) {
|
|
27
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
-
}
|
|
29
|
-
var __export = (target, all) => {
|
|
30
|
-
for (var name in all)
|
|
31
|
-
__defProp(target, name, {
|
|
32
|
-
get: all[name],
|
|
33
|
-
enumerable: true,
|
|
34
|
-
configurable: true,
|
|
35
|
-
set: __exportSetter.bind(all, name)
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
// src/index.ts
|
|
40
|
-
var exports_src = {};
|
|
41
|
-
__export(exports_src, {
|
|
42
|
-
validateSeoSlug: () => validateSeoSlug,
|
|
43
|
-
resolveFeatureIcon: () => resolveFeatureIcon,
|
|
44
|
-
resolveBuiltInLocations: () => resolveBuiltInLocations,
|
|
45
|
-
resolveBrandIcon: () => resolveBrandIcon,
|
|
46
|
-
renderUiIconSvg: () => renderUiIconSvg,
|
|
47
|
-
renderBrandIconSvg: () => renderBrandIconSvg,
|
|
48
|
-
getSeoAgentPrompt: () => getSeoAgentPrompt,
|
|
49
|
-
default: () => src_default,
|
|
50
|
-
createLynxSeoEngine: () => createLynxSeoEngine,
|
|
51
|
-
cleanSeoSlug: () => cleanSeoSlug,
|
|
52
|
-
YoastParityEngine: () => YoastParityEngine,
|
|
53
|
-
VideoYouTubeAnalyzer: () => VideoYouTubeAnalyzer,
|
|
54
|
-
UrlyticsEngine: () => UrlyticsEngine,
|
|
55
|
-
UI_ICONS: () => UI_ICONS,
|
|
56
|
-
TokenQuotaManager: () => TokenQuotaManager,
|
|
57
|
-
TechnicalRulesAuditor: () => TechnicalRulesAuditor,
|
|
58
|
-
TeamRbacEngine: () => TeamRbacEngine,
|
|
59
|
-
SocialVideoSeoAnalyticsEngine: () => SocialVideoSeoAnalyticsEngine,
|
|
60
|
-
SocialTrendSeoGenerator: () => SocialTrendSeoGenerator,
|
|
61
|
-
SocialGrowthSuite: () => SocialGrowthSuite,
|
|
62
|
-
SocialAdsSocialSeoEngine: () => SocialAdsSocialSeoEngine,
|
|
63
|
-
SiteAuditor: () => SiteAuditor,
|
|
64
|
-
SerpRankHistoryEngine: () => SerpRankHistoryEngine,
|
|
65
|
-
SerpClient: () => SerpClient,
|
|
66
|
-
SeoOpportunitiesDecayDetector: () => SeoOpportunitiesDecayDetector,
|
|
67
|
-
SchemaGraphBuilder: () => SchemaGraphBuilder,
|
|
68
|
-
SUPPORTED_CANONICAL_LOCALES: () => SUPPORTED_CANONICAL_LOCALES,
|
|
69
|
-
SCHEMA_LOCAL_BUSINESS_MAP: () => SCHEMA_LOCAL_BUSINESS_MAP,
|
|
70
|
-
RssSyndicationFeedGenerator: () => RssSyndicationFeedGenerator,
|
|
71
|
-
RealReviewsSyncEngine: () => RealReviewsSyncEngine,
|
|
72
|
-
RankMathParityEngine: () => RankMathParityEngine,
|
|
73
|
-
PseoMatrixEngine: () => PseoMatrixEngine,
|
|
74
|
-
PowerWordsPsychologyEngine: () => PowerWordsPsychologyEngine,
|
|
75
|
-
PSEO_AGENT_SYSTEM_PROMPT: () => PSEO_AGENT_SYSTEM_PROMPT,
|
|
76
|
-
OgImageGenerator: () => OgImageGenerator,
|
|
77
|
-
NGramDensityAnalyzer: () => NGramDensityAnalyzer,
|
|
78
|
-
McpSeoServerHub: () => McpSeoServerHub,
|
|
79
|
-
MasterMarketingEngine: () => MasterMarketingEngine,
|
|
80
|
-
MULTILINGUAL_STOP_WORDS: () => MULTILINGUAL_STOP_WORDS,
|
|
81
|
-
MULTILINGUAL_POWER_WORDS: () => MULTILINGUAL_POWER_WORDS,
|
|
82
|
-
MULTILINGUAL_DISCLAIMERS: () => MULTILINGUAL_DISCLAIMERS,
|
|
83
|
-
MULTILINGUAL_BANNED_DISPARAGING_WORDS: () => MULTILINGUAL_BANNED_DISPARAGING_WORDS,
|
|
84
|
-
LynxSeoEngine: () => LynxSeoEngine,
|
|
85
|
-
LynxSeo: () => LynxSeo,
|
|
86
|
-
LynxAnalyticsClient: () => LynxAnalyticsClient,
|
|
87
|
-
LlmContentCleaner: () => LlmContentCleaner,
|
|
88
|
-
LegalDisclaimerEngine: () => LegalDisclaimerEngine,
|
|
89
|
-
LagoTokenMeter: () => LagoTokenMeter,
|
|
90
|
-
KnowledgeGraphLinker: () => KnowledgeGraphLinker,
|
|
91
|
-
KeywordPermutatorEngine: () => KeywordPermutatorEngine,
|
|
92
|
-
IsrCacheManager: () => IsrCacheManager,
|
|
93
|
-
InstantMatrixSearchEngine: () => InstantMatrixSearchEngine,
|
|
94
|
-
IndexNowClient: () => IndexNowClient,
|
|
95
|
-
I18nDetector: () => I18nDetector,
|
|
96
|
-
HyperswitchGateway: () => HyperswitchGateway,
|
|
97
|
-
GoogleBusinessProfileEngine: () => GoogleBusinessProfileEngine,
|
|
98
|
-
GeoMeshLinkingEngine: () => GeoMeshLinkingEngine,
|
|
99
|
-
FreePublicToolsEngine: () => FreePublicToolsEngine,
|
|
100
|
-
ExtendedSchemaGraphBuilder: () => ExtendedSchemaGraphBuilder,
|
|
101
|
-
EmbeddableSeoWidgetGenerator: () => EmbeddableSeoWidgetGenerator,
|
|
102
|
-
DeepCrawlerAuditor: () => DeepCrawlerAuditor,
|
|
103
|
-
CrosslinkScorerEngine: () => CrosslinkScorerEngine,
|
|
104
|
-
CroCopywritingEngine: () => CroCopywritingEngine,
|
|
105
|
-
CopywritingFrameworksMaster: () => CopywritingFrameworksMaster,
|
|
106
|
-
BrandDnaCalendarEngine: () => BrandDnaCalendarEngine,
|
|
107
|
-
BacklinksClient: () => BacklinksClient,
|
|
108
|
-
BUILT_IN_LOCATIONS_DATABASE: () => BUILT_IN_LOCATIONS_DATABASE,
|
|
109
|
-
BRAND_ICONS: () => BRAND_ICONS,
|
|
110
|
-
ApiKeyGuardian: () => ApiKeyGuardian,
|
|
111
|
-
AiCopilotClient: () => AiCopilotClient,
|
|
112
|
-
AiBotsLogAnalyzer: () => AiBotsLogAnalyzer,
|
|
113
|
-
AdIntelligenceCroEngine: () => AdIntelligenceCroEngine
|
|
114
|
-
});
|
|
115
|
-
module.exports = __toCommonJS(exports_src);
|
|
116
|
-
|
|
117
|
-
// src/token-quota-manager.ts
|
|
1
|
+
// packages/lynx-seo-engine/src/token-quota-manager.ts
|
|
118
2
|
class TokenQuotaManager {
|
|
119
3
|
tier;
|
|
120
4
|
monthlyCreditBudget;
|
|
@@ -162,7 +46,7 @@ class TokenQuotaManager {
|
|
|
162
46
|
}
|
|
163
47
|
}
|
|
164
48
|
|
|
165
|
-
// src/auth-key.ts
|
|
49
|
+
// packages/lynx-seo-engine/src/auth-key.ts
|
|
166
50
|
class ApiKeyGuardian {
|
|
167
51
|
static domainRegistry = new Map;
|
|
168
52
|
static uniquePageRegistry = new Map;
|
|
@@ -336,7 +220,7 @@ class ApiKeyGuardian {
|
|
|
336
220
|
}
|
|
337
221
|
}
|
|
338
222
|
|
|
339
|
-
// src/i18n-dictionary.ts
|
|
223
|
+
// packages/lynx-seo-engine/src/i18n-dictionary.ts
|
|
340
224
|
var DICTIONARIES = {
|
|
341
225
|
fr: {
|
|
342
226
|
geoTitle: (s, city, country, b) => `${s} à ${city} (${country}) — ${b}`,
|
|
@@ -692,7 +576,7 @@ function isSupportedLanguage(lang) {
|
|
|
692
576
|
return Boolean(DICTIONARIES[code]);
|
|
693
577
|
}
|
|
694
578
|
|
|
695
|
-
// src/indexnow-client.ts
|
|
579
|
+
// packages/lynx-seo-engine/src/indexnow-client.ts
|
|
696
580
|
var SUCCESS_STATUSES = new Set([200, 202]);
|
|
697
581
|
var MAX_URLS_PER_REQUEST = 1e4;
|
|
698
582
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
@@ -748,7 +632,7 @@ class IndexNowClient {
|
|
|
748
632
|
}
|
|
749
633
|
}
|
|
750
634
|
|
|
751
|
-
// src/analytics-client.ts
|
|
635
|
+
// packages/lynx-seo-engine/src/analytics-client.ts
|
|
752
636
|
class LynxAnalyticsClient {
|
|
753
637
|
apiKey;
|
|
754
638
|
endpoint;
|
|
@@ -977,7 +861,7 @@ class LynxAnalyticsClient {
|
|
|
977
861
|
}
|
|
978
862
|
}
|
|
979
863
|
|
|
980
|
-
// src/serp-client.ts
|
|
864
|
+
// packages/lynx-seo-engine/src/serp-client.ts
|
|
981
865
|
class SerpClient {
|
|
982
866
|
apiKey;
|
|
983
867
|
endpoint;
|
|
@@ -1030,7 +914,7 @@ class SerpClient {
|
|
|
1030
914
|
}
|
|
1031
915
|
}
|
|
1032
916
|
|
|
1033
|
-
// src/backlinks-client.ts
|
|
917
|
+
// packages/lynx-seo-engine/src/backlinks-client.ts
|
|
1034
918
|
class BacklinksClient {
|
|
1035
919
|
apiKey;
|
|
1036
920
|
endpoint;
|
|
@@ -1086,7 +970,7 @@ class BacklinksClient {
|
|
|
1086
970
|
}
|
|
1087
971
|
}
|
|
1088
972
|
|
|
1089
|
-
// src/ai-copilot-client.ts
|
|
973
|
+
// packages/lynx-seo-engine/src/ai-copilot-client.ts
|
|
1090
974
|
class AiCopilotClient {
|
|
1091
975
|
apiKey;
|
|
1092
976
|
endpoint;
|
|
@@ -1150,7 +1034,7 @@ Optimiser votre stratégie avec ${params.targetKeywords.join(", ")}.
|
|
|
1150
1034
|
}
|
|
1151
1035
|
}
|
|
1152
1036
|
|
|
1153
|
-
// src/lago-token-meter.ts
|
|
1037
|
+
// packages/lynx-seo-engine/src/lago-token-meter.ts
|
|
1154
1038
|
class LagoTokenMeter {
|
|
1155
1039
|
lagoApiUrl;
|
|
1156
1040
|
apiKey;
|
|
@@ -1231,7 +1115,7 @@ class HyperswitchGateway {
|
|
|
1231
1115
|
}
|
|
1232
1116
|
}
|
|
1233
1117
|
|
|
1234
|
-
// src/site-auditor.ts
|
|
1118
|
+
// packages/lynx-seo-engine/src/site-auditor.ts
|
|
1235
1119
|
class SiteAuditor {
|
|
1236
1120
|
static inspectMeta(params) {
|
|
1237
1121
|
const checks = [];
|
|
@@ -1277,7 +1161,7 @@ class SiteAuditor {
|
|
|
1277
1161
|
}
|
|
1278
1162
|
}
|
|
1279
1163
|
|
|
1280
|
-
// src/schema-builder.ts
|
|
1164
|
+
// packages/lynx-seo-engine/src/schema-builder.ts
|
|
1281
1165
|
class SchemaGraphBuilder {
|
|
1282
1166
|
static buildGraph(opts) {
|
|
1283
1167
|
const productNode = {
|
|
@@ -1372,7 +1256,7 @@ class SchemaGraphBuilder {
|
|
|
1372
1256
|
}
|
|
1373
1257
|
}
|
|
1374
1258
|
|
|
1375
|
-
// src/site-crawler.ts
|
|
1259
|
+
// packages/lynx-seo-engine/src/site-crawler.ts
|
|
1376
1260
|
class DeepCrawlerAuditor {
|
|
1377
1261
|
static DEFAULT_USER_AGENT = "LynxFlowSeoBot/1.2 (+https://lynxintel.io/bot; technical audit)";
|
|
1378
1262
|
static inspectHtmlSnapshot(url, html, statusCode = 200, responseTimeMs = 45) {
|
|
@@ -1661,7 +1545,7 @@ class DeepCrawlerAuditor {
|
|
|
1661
1545
|
}
|
|
1662
1546
|
}
|
|
1663
1547
|
|
|
1664
|
-
// src/cro-copywriting-engine.ts
|
|
1548
|
+
// packages/lynx-seo-engine/src/cro-copywriting-engine.ts
|
|
1665
1549
|
class CroCopywritingEngine {
|
|
1666
1550
|
static generatePasCopy(solutionName, targetNiche) {
|
|
1667
1551
|
return {
|
|
@@ -1723,7 +1607,7 @@ class CroCopywritingEngine {
|
|
|
1723
1607
|
}
|
|
1724
1608
|
}
|
|
1725
1609
|
|
|
1726
|
-
// src/llm-content-cleaner.ts
|
|
1610
|
+
// packages/lynx-seo-engine/src/llm-content-cleaner.ts
|
|
1727
1611
|
class LlmContentCleaner {
|
|
1728
1612
|
static cleanForLlm(content) {
|
|
1729
1613
|
return this.htmlToCleanMarkdown(content);
|
|
@@ -1751,7 +1635,7 @@ $1
|
|
|
1751
1635
|
}
|
|
1752
1636
|
}
|
|
1753
1637
|
|
|
1754
|
-
// src/engine.ts
|
|
1638
|
+
// packages/lynx-seo-engine/src/engine.ts
|
|
1755
1639
|
class LynxSeoEngine {
|
|
1756
1640
|
config;
|
|
1757
1641
|
servicesMap;
|
|
@@ -2349,7 +2233,7 @@ ${servicesList}
|
|
|
2349
2233
|
`;
|
|
2350
2234
|
}
|
|
2351
2235
|
}
|
|
2352
|
-
// src/slug-engine.ts
|
|
2236
|
+
// packages/lynx-seo-engine/src/slug-engine.ts
|
|
2353
2237
|
var MULTILINGUAL_STOP_WORDS = {
|
|
2354
2238
|
en: new Set([
|
|
2355
2239
|
"the",
|
|
@@ -2740,7 +2624,7 @@ function validateSeoSlug(slug) {
|
|
|
2740
2624
|
errors
|
|
2741
2625
|
};
|
|
2742
2626
|
}
|
|
2743
|
-
// src/legal-disclaimers.ts
|
|
2627
|
+
// packages/lynx-seo-engine/src/legal-disclaimers.ts
|
|
2744
2628
|
var MULTILINGUAL_DISCLAIMERS = {
|
|
2745
2629
|
en: {
|
|
2746
2630
|
comparison: {
|
|
@@ -3036,7 +2920,7 @@ class LegalDisclaimerEngine {
|
|
|
3036
2920
|
};
|
|
3037
2921
|
}
|
|
3038
2922
|
}
|
|
3039
|
-
// src/extended-schemas.ts
|
|
2923
|
+
// packages/lynx-seo-engine/src/extended-schemas.ts
|
|
3040
2924
|
var SCHEMA_LOCAL_BUSINESS_MAP = {
|
|
3041
2925
|
plumber: "Plumber",
|
|
3042
2926
|
plumbing: "Plumber",
|
|
@@ -3200,10 +3084,13 @@ class ExtendedSchemaGraphBuilder {
|
|
|
3200
3084
|
};
|
|
3201
3085
|
}
|
|
3202
3086
|
static buildAggregateRating(opts) {
|
|
3087
|
+
if (!opts.ratingValue || !opts.reviewCount || opts.reviewCount <= 0) {
|
|
3088
|
+
return null;
|
|
3089
|
+
}
|
|
3203
3090
|
return {
|
|
3204
3091
|
"@type": "AggregateRating",
|
|
3205
|
-
ratingValue: opts.ratingValue
|
|
3206
|
-
reviewCount: opts.reviewCount
|
|
3092
|
+
ratingValue: opts.ratingValue,
|
|
3093
|
+
reviewCount: opts.reviewCount,
|
|
3207
3094
|
bestRating: opts.bestRating ?? 5,
|
|
3208
3095
|
worstRating: opts.worstRating ?? 1,
|
|
3209
3096
|
itemReviewed: {
|
|
@@ -3257,7 +3144,7 @@ class ExtendedSchemaGraphBuilder {
|
|
|
3257
3144
|
}
|
|
3258
3145
|
}
|
|
3259
3146
|
|
|
3260
|
-
// src/built-in-locations.ts
|
|
3147
|
+
// packages/lynx-seo-engine/src/built-in-locations.ts
|
|
3261
3148
|
var BUILT_IN_LOCATIONS_DATABASE = {
|
|
3262
3149
|
fr: [
|
|
3263
3150
|
{ slug: "paris", name: "Paris", region: "Île-de-France", country: "France", population: 2161000, currency: "EUR", currencySymbol: "€", latitude: 48.8566, longitude: 2.3522, neighborSlugs: ["boulogne-billancourt", "saint-denis", "montreuil"] },
|
|
@@ -3401,7 +3288,7 @@ function resolveBuiltInLocations(territories) {
|
|
|
3401
3288
|
return results.length > 0 ? results : [...BUILT_IN_LOCATIONS_DATABASE.fr];
|
|
3402
3289
|
}
|
|
3403
3290
|
|
|
3404
|
-
// src/og-image-generator.ts
|
|
3291
|
+
// packages/lynx-seo-engine/src/og-image-generator.ts
|
|
3405
3292
|
class OgImageGenerator {
|
|
3406
3293
|
static generateOgImageUrl(domain, pageMeta, brandName) {
|
|
3407
3294
|
const cleanDomain = domain.replace(/\/+$/, "");
|
|
@@ -3421,8 +3308,8 @@ class OgImageGenerator {
|
|
|
3421
3308
|
const badge = opts.badgeText || "OFFICIAL";
|
|
3422
3309
|
const title = opts.title.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3423
3310
|
const loc = opts.locationName ? `\uD83D\uDCCD ${opts.locationName}` : "⚡ Instant Cloud Setup";
|
|
3424
|
-
const rating = opts.ratingValue
|
|
3425
|
-
const reviews = opts.reviewCount
|
|
3311
|
+
const rating = opts.ratingValue;
|
|
3312
|
+
const reviews = opts.reviewCount;
|
|
3426
3313
|
const accent = opts.brandColor || "#6366F1";
|
|
3427
3314
|
return `<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
3428
3315
|
<defs>
|
|
@@ -3465,12 +3352,12 @@ class OgImageGenerator {
|
|
|
3465
3352
|
${title.length > 38 ? `<tspan x="80" dy="68">${title.slice(38, 80)}</tspan>` : ""}
|
|
3466
3353
|
</text>
|
|
3467
3354
|
|
|
3468
|
-
<!-- Trust Stars & Social Proof -->
|
|
3469
|
-
|
|
3355
|
+
<!-- Trust Stars & Social Proof (Only if real verified reviews exist) -->
|
|
3356
|
+
${rating && reviews ? `<g transform="translate(80, 470)">
|
|
3470
3357
|
<text x="0" y="32" fill="#FBBF24" font-size="24">★★★★★</text>
|
|
3471
3358
|
<text x="140" y="30" fill="#F8FAFC" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="20" font-weight="800">${rating} / 5</text>
|
|
3472
3359
|
<text x="210" y="30" fill="#64748B" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="16" font-weight="500">(${reviews.toLocaleString()} verified reviews)</text>
|
|
3473
|
-
</g
|
|
3360
|
+
</g>` : ""}
|
|
3474
3361
|
|
|
3475
3362
|
<!-- Footer Brand -->
|
|
3476
3363
|
<g transform="translate(80, 540)">
|
|
@@ -3482,7 +3369,7 @@ class OgImageGenerator {
|
|
|
3482
3369
|
}
|
|
3483
3370
|
}
|
|
3484
3371
|
|
|
3485
|
-
// src/matrix-engine.ts
|
|
3372
|
+
// packages/lynx-seo-engine/src/matrix-engine.ts
|
|
3486
3373
|
class PseoMatrixEngine {
|
|
3487
3374
|
legalEngine;
|
|
3488
3375
|
constructor(legalOptions) {
|
|
@@ -4101,7 +3988,7 @@ ${urls}
|
|
|
4101
3988
|
};
|
|
4102
3989
|
}
|
|
4103
3990
|
}
|
|
4104
|
-
// src/i18n-detector.ts
|
|
3991
|
+
// packages/lynx-seo-engine/src/i18n-detector.ts
|
|
4105
3992
|
var SUPPORTED_CANONICAL_LOCALES = [
|
|
4106
3993
|
"en",
|
|
4107
3994
|
"fr",
|
|
@@ -4178,7 +4065,7 @@ class I18nDetector {
|
|
|
4178
4065
|
};
|
|
4179
4066
|
}
|
|
4180
4067
|
}
|
|
4181
|
-
// src/brand-icons.ts
|
|
4068
|
+
// packages/lynx-seo-engine/src/brand-icons.ts
|
|
4182
4069
|
var BRAND_ICONS = {
|
|
4183
4070
|
facebook: {
|
|
4184
4071
|
name: "Facebook",
|
|
@@ -4294,7 +4181,7 @@ function renderBrandIconSvg(input, className = "w-5 h-5 inline-block") {
|
|
|
4294
4181
|
return "";
|
|
4295
4182
|
return `<svg class="${className}" viewBox="${icon.viewBox}" fill="currentColor" aria-hidden="true"><path d="${icon.svgPath}"/></svg>`;
|
|
4296
4183
|
}
|
|
4297
|
-
// src/ui-icons.ts
|
|
4184
|
+
// packages/lynx-seo-engine/src/ui-icons.ts
|
|
4298
4185
|
var UI_ICONS = {
|
|
4299
4186
|
zap: {
|
|
4300
4187
|
name: "Zap / Lightning",
|
|
@@ -4407,7 +4294,7 @@ function resolveFeatureIcon(featureText) {
|
|
|
4407
4294
|
}
|
|
4408
4295
|
return "zap";
|
|
4409
4296
|
}
|
|
4410
|
-
// src/free-public-tools.ts
|
|
4297
|
+
// packages/lynx-seo-engine/src/free-public-tools.ts
|
|
4411
4298
|
class FreePublicToolsEngine {
|
|
4412
4299
|
static simulateSerpSnippet(input) {
|
|
4413
4300
|
const title = (input.title || "").trim();
|
|
@@ -4541,7 +4428,7 @@ class FreePublicToolsEngine {
|
|
|
4541
4428
|
});
|
|
4542
4429
|
}
|
|
4543
4430
|
}
|
|
4544
|
-
// src/urlytics-engine.ts
|
|
4431
|
+
// packages/lynx-seo-engine/src/urlytics-engine.ts
|
|
4545
4432
|
class UrlyticsEngine {
|
|
4546
4433
|
static parseUrl(rawUrl) {
|
|
4547
4434
|
if (!rawUrl || typeof rawUrl !== "string") {
|
|
@@ -4603,7 +4490,7 @@ class UrlyticsEngine {
|
|
|
4603
4490
|
return urls.map((u) => this.parseUrl(u));
|
|
4604
4491
|
}
|
|
4605
4492
|
}
|
|
4606
|
-
// src/keyword-permutator.ts
|
|
4493
|
+
// packages/lynx-seo-engine/src/keyword-permutator.ts
|
|
4607
4494
|
class KeywordPermutatorEngine {
|
|
4608
4495
|
static generateKeywordMatrix(options) {
|
|
4609
4496
|
const { products, words = [], locations = [], maxCombinations = 5000 } = options;
|
|
@@ -4679,7 +4566,7 @@ class KeywordPermutatorEngine {
|
|
|
4679
4566
|
return results;
|
|
4680
4567
|
}
|
|
4681
4568
|
}
|
|
4682
|
-
// src/llm-prompt.ts
|
|
4569
|
+
// packages/lynx-seo-engine/src/llm-prompt.ts
|
|
4683
4570
|
var PSEO_AGENT_SYSTEM_PROMPT = `
|
|
4684
4571
|
You are the Programmatic SEO Implementation Specialist powered by @lynxflow/seo-engine.
|
|
4685
4572
|
Your role is to configure, resolve, and maintain programmatic SEO pages, XML sitemaps, Schema.org JSON-LD graphs, and compliance rules.
|
|
@@ -4993,7 +4880,7 @@ ${PSEO_AGENT_SYSTEM_PROMPT}
|
|
|
4993
4880
|
- Domain: ${customContext.domain || "https://example.com"}
|
|
4994
4881
|
`.trim();
|
|
4995
4882
|
}
|
|
4996
|
-
// src/geo-mesh-linking.ts
|
|
4883
|
+
// packages/lynx-seo-engine/src/geo-mesh-linking.ts
|
|
4997
4884
|
class GeoMeshLinkingEngine {
|
|
4998
4885
|
static computeDistanceKm(coord1, coord2) {
|
|
4999
4886
|
const R = 6371;
|
|
@@ -5025,7 +4912,7 @@ class GeoMeshLinkingEngine {
|
|
|
5025
4912
|
return sameRegion.slice(0, maxNeighbors).map((c) => ({ city: c }));
|
|
5026
4913
|
}
|
|
5027
4914
|
}
|
|
5028
|
-
// src/brand-dna-calendar.ts
|
|
4915
|
+
// packages/lynx-seo-engine/src/brand-dna-calendar.ts
|
|
5029
4916
|
class BrandDnaCalendarEngine {
|
|
5030
4917
|
static generate4WeekCalendar(dna, services, topCities = ["Paris", "Lyon", "Marseille", "Bordeaux"]) {
|
|
5031
4918
|
const calendar = [];
|
|
@@ -5105,7 +4992,7 @@ class BrandDnaCalendarEngine {
|
|
|
5105
4992
|
return calendar;
|
|
5106
4993
|
}
|
|
5107
4994
|
}
|
|
5108
|
-
// src/technical-rules-auditor.ts
|
|
4995
|
+
// packages/lynx-seo-engine/src/technical-rules-auditor.ts
|
|
5109
4996
|
class TechnicalRulesAuditor {
|
|
5110
4997
|
static auditPage(page) {
|
|
5111
4998
|
const issues = [];
|
|
@@ -5223,7 +5110,7 @@ class TechnicalRulesAuditor {
|
|
|
5223
5110
|
return issues;
|
|
5224
5111
|
}
|
|
5225
5112
|
}
|
|
5226
|
-
// src/ai-bots-log-analyzer.ts
|
|
5113
|
+
// packages/lynx-seo-engine/src/ai-bots-log-analyzer.ts
|
|
5227
5114
|
class AiBotsLogAnalyzer {
|
|
5228
5115
|
static classifyUserAgent(ua) {
|
|
5229
5116
|
const lowerUa = ua.toLowerCase();
|
|
@@ -5294,7 +5181,7 @@ class AiBotsLogAnalyzer {
|
|
|
5294
5181
|
return result;
|
|
5295
5182
|
}
|
|
5296
5183
|
}
|
|
5297
|
-
// src/serp-history-alerts.ts
|
|
5184
|
+
// packages/lynx-seo-engine/src/serp-history-alerts.ts
|
|
5298
5185
|
class SerpRankHistoryEngine {
|
|
5299
5186
|
static analyzeRankShift(previousSnapshot, currentSnapshot) {
|
|
5300
5187
|
const prev = previousSnapshot.position;
|
|
@@ -5335,7 +5222,7 @@ class SerpRankHistoryEngine {
|
|
|
5335
5222
|
return null;
|
|
5336
5223
|
}
|
|
5337
5224
|
}
|
|
5338
|
-
// src/seo-opportunities-decay.ts
|
|
5225
|
+
// packages/lynx-seo-engine/src/seo-opportunities-decay.ts
|
|
5339
5226
|
class SeoOpportunitiesDecayDetector {
|
|
5340
5227
|
static getExpectedCtr(position) {
|
|
5341
5228
|
if (position <= 1)
|
|
@@ -5424,7 +5311,7 @@ class SeoOpportunitiesDecayDetector {
|
|
|
5424
5311
|
return cannibalized;
|
|
5425
5312
|
}
|
|
5426
5313
|
}
|
|
5427
|
-
// src/knowledge-graph-linker.ts
|
|
5314
|
+
// packages/lynx-seo-engine/src/knowledge-graph-linker.ts
|
|
5428
5315
|
class KnowledgeGraphLinker {
|
|
5429
5316
|
static buildSearchUrl(query, apiKey, limit = 5, languages = ["fr", "en"]) {
|
|
5430
5317
|
const params = new URLSearchParams({
|
|
@@ -5472,7 +5359,7 @@ class KnowledgeGraphLinker {
|
|
|
5472
5359
|
return Array.from(new Set(links));
|
|
5473
5360
|
}
|
|
5474
5361
|
}
|
|
5475
|
-
// src/mcp-seo-server.ts
|
|
5362
|
+
// packages/lynx-seo-engine/src/mcp-seo-server.ts
|
|
5476
5363
|
class McpSeoServerHub {
|
|
5477
5364
|
static getRegisteredTools() {
|
|
5478
5365
|
return [
|
|
@@ -5561,7 +5448,7 @@ class McpSeoServerHub {
|
|
|
5561
5448
|
}
|
|
5562
5449
|
}
|
|
5563
5450
|
}
|
|
5564
|
-
// src/master-marketing-engine.ts
|
|
5451
|
+
// packages/lynx-seo-engine/src/master-marketing-engine.ts
|
|
5565
5452
|
class MasterMarketingEngine {
|
|
5566
5453
|
static generateDirectoryListings(domain = "lynxintel.io", brandName = "LynxSEO") {
|
|
5567
5454
|
return [
|
|
@@ -5786,7 +5673,7 @@ class MasterMarketingEngine {
|
|
|
5786
5673
|
};
|
|
5787
5674
|
}
|
|
5788
5675
|
}
|
|
5789
|
-
// src/social-video-seo.ts
|
|
5676
|
+
// packages/lynx-seo-engine/src/social-video-seo.ts
|
|
5790
5677
|
class SocialVideoSeoAnalyticsEngine {
|
|
5791
5678
|
static buildVideoObjectSchema(opts) {
|
|
5792
5679
|
const schema = {
|
|
@@ -5834,7 +5721,7 @@ class SocialVideoSeoAnalyticsEngine {
|
|
|
5834
5721
|
};
|
|
5835
5722
|
}
|
|
5836
5723
|
}
|
|
5837
|
-
// src/social-trend-seo.ts
|
|
5724
|
+
// packages/lynx-seo-engine/src/social-trend-seo.ts
|
|
5838
5725
|
class SocialTrendSeoGenerator {
|
|
5839
5726
|
static generateActionFromTrend(trend, serviceSlug = "crm-pipeline", serviceName = "CRM Pipeline Commercial") {
|
|
5840
5727
|
const cleanTopic = trend.topicName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
@@ -5894,7 +5781,7 @@ class SocialTrendSeoGenerator {
|
|
|
5894
5781
|
];
|
|
5895
5782
|
}
|
|
5896
5783
|
}
|
|
5897
|
-
// src/crosslink-scorer.ts
|
|
5784
|
+
// packages/lynx-seo-engine/src/crosslink-scorer.ts
|
|
5898
5785
|
class CrosslinkScorerEngine {
|
|
5899
5786
|
static computeCrosslinkScore(source, candidate) {
|
|
5900
5787
|
if (source.slug === candidate.slug)
|
|
@@ -5945,7 +5832,7 @@ class CrosslinkScorerEngine {
|
|
|
5945
5832
|
return suggestions.sort((a, b) => b.score - a.score).slice(0, maxLinks);
|
|
5946
5833
|
}
|
|
5947
5834
|
}
|
|
5948
|
-
// src/instant-matrix-search.ts
|
|
5835
|
+
// packages/lynx-seo-engine/src/instant-matrix-search.ts
|
|
5949
5836
|
class InstantMatrixSearchEngine {
|
|
5950
5837
|
static search(query, pages, limit = 10) {
|
|
5951
5838
|
const cleanQuery = query.trim().toLowerCase();
|
|
@@ -5967,7 +5854,7 @@ class InstantMatrixSearchEngine {
|
|
|
5967
5854
|
}).filter((item) => item.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((item) => item.page);
|
|
5968
5855
|
}
|
|
5969
5856
|
}
|
|
5970
|
-
// src/rss-syndication-feed.ts
|
|
5857
|
+
// packages/lynx-seo-engine/src/rss-syndication-feed.ts
|
|
5971
5858
|
class RssSyndicationFeedGenerator {
|
|
5972
5859
|
static generateRss2(opts) {
|
|
5973
5860
|
const itemsXml = opts.items.map((item) => `
|
|
@@ -5996,7 +5883,7 @@ ${itemsXml}
|
|
|
5996
5883
|
</rss>`.trim();
|
|
5997
5884
|
}
|
|
5998
5885
|
}
|
|
5999
|
-
// src/embeddable-seo-widget.ts
|
|
5886
|
+
// packages/lynx-seo-engine/src/embeddable-seo-widget.ts
|
|
6000
5887
|
class EmbeddableSeoWidgetGenerator {
|
|
6001
5888
|
static generateWidgetJs(apiBaseUrl) {
|
|
6002
5889
|
return `
|
|
@@ -6044,7 +5931,7 @@ class EmbeddableSeoWidgetGenerator {
|
|
|
6044
5931
|
`.trim();
|
|
6045
5932
|
}
|
|
6046
5933
|
}
|
|
6047
|
-
// src/ngram-density-analyzer.ts
|
|
5934
|
+
// packages/lynx-seo-engine/src/ngram-density-analyzer.ts
|
|
6048
5935
|
class NGramDensityAnalyzer {
|
|
6049
5936
|
static stopwords = new Set([
|
|
6050
5937
|
"le",
|
|
@@ -6153,7 +6040,7 @@ class NGramDensityAnalyzer {
|
|
|
6153
6040
|
})).sort((a, b) => b.count - a.count);
|
|
6154
6041
|
}
|
|
6155
6042
|
}
|
|
6156
|
-
// src/isr-cache-manager.ts
|
|
6043
|
+
// packages/lynx-seo-engine/src/isr-cache-manager.ts
|
|
6157
6044
|
class IsrCacheManager {
|
|
6158
6045
|
static cache = new Map;
|
|
6159
6046
|
static defaultTtlMs = 24 * 3600 * 1000;
|
|
@@ -6191,7 +6078,7 @@ class IsrCacheManager {
|
|
|
6191
6078
|
return this.cache.size;
|
|
6192
6079
|
}
|
|
6193
6080
|
}
|
|
6194
|
-
// src/copy-frameworks-master.ts
|
|
6081
|
+
// packages/lynx-seo-engine/src/copy-frameworks-master.ts
|
|
6195
6082
|
class CopywritingFrameworksMaster {
|
|
6196
6083
|
static generateHeadlines(opts) {
|
|
6197
6084
|
return {
|
|
@@ -6225,7 +6112,7 @@ class CopywritingFrameworksMaster {
|
|
|
6225
6112
|
];
|
|
6226
6113
|
}
|
|
6227
6114
|
}
|
|
6228
|
-
// src/social-ads-seo.ts
|
|
6115
|
+
// packages/lynx-seo-engine/src/social-ads-seo.ts
|
|
6229
6116
|
class SocialAdsSocialSeoEngine {
|
|
6230
6117
|
static auditLinkedInTrendsForSeo(industry = "avocats", serviceSlug = "crm-pipeline", serviceName = "CRM Pipeline") {
|
|
6231
6118
|
return [
|
|
@@ -6361,7 +6248,7 @@ ${template.targetHashtags.join(" ")}
|
|
|
6361
6248
|
];
|
|
6362
6249
|
}
|
|
6363
6250
|
}
|
|
6364
|
-
// src/ad-intelligence-cro.ts
|
|
6251
|
+
// packages/lynx-seo-engine/src/ad-intelligence-cro.ts
|
|
6365
6252
|
class AdIntelligenceCroEngine {
|
|
6366
6253
|
static inspectCompetitorAds(competitorDomain, serviceName = "CRM Pipeline") {
|
|
6367
6254
|
const brand = competitorDomain.replace(/^https?:\/\//, "").split(".")[0];
|
|
@@ -6445,7 +6332,7 @@ Avec ${opts.serviceName}, tout est automatisé en tâche de fond pour vous appor
|
|
|
6445
6332
|
];
|
|
6446
6333
|
}
|
|
6447
6334
|
}
|
|
6448
|
-
// src/rank-math-parity.ts
|
|
6335
|
+
// packages/lynx-seo-engine/src/rank-math-parity.ts
|
|
6449
6336
|
class RankMathParityEngine {
|
|
6450
6337
|
static calculateOnPageScore(opts) {
|
|
6451
6338
|
const kw = opts.focusKeyword.trim().toLowerCase();
|
|
@@ -6599,7 +6486,7 @@ class RankMathParityEngine {
|
|
|
6599
6486
|
`);
|
|
6600
6487
|
}
|
|
6601
6488
|
}
|
|
6602
|
-
// src/yoast-parity.ts
|
|
6489
|
+
// packages/lynx-seo-engine/src/yoast-parity.ts
|
|
6603
6490
|
class YoastParityEngine {
|
|
6604
6491
|
static frenchTransitionWords = [
|
|
6605
6492
|
"en effet",
|
|
@@ -6714,7 +6601,7 @@ class YoastParityEngine {
|
|
|
6714
6601
|
};
|
|
6715
6602
|
}
|
|
6716
6603
|
}
|
|
6717
|
-
// src/social-growth-suite.ts
|
|
6604
|
+
// packages/lynx-seo-engine/src/social-growth-suite.ts
|
|
6718
6605
|
class SocialGrowthSuite {
|
|
6719
6606
|
static generateCarouselDeck(opts) {
|
|
6720
6607
|
return {
|
|
@@ -6920,7 +6807,7 @@ Voici le guide complet en 6 slides pour automatiser votre acquisition en 2026 \u
|
|
|
6920
6807
|
];
|
|
6921
6808
|
}
|
|
6922
6809
|
}
|
|
6923
|
-
// src/team-rbac.ts
|
|
6810
|
+
// packages/lynx-seo-engine/src/team-rbac.ts
|
|
6924
6811
|
var ROLE_PERMISSIONS = {
|
|
6925
6812
|
owner: [
|
|
6926
6813
|
"project:delete",
|
|
@@ -6957,7 +6844,7 @@ class TeamRbacEngine {
|
|
|
6957
6844
|
return permissions.includes(action);
|
|
6958
6845
|
}
|
|
6959
6846
|
}
|
|
6960
|
-
// src/real-reviews-sync.ts
|
|
6847
|
+
// packages/lynx-seo-engine/src/real-reviews-sync.ts
|
|
6961
6848
|
class RealReviewsSyncEngine {
|
|
6962
6849
|
static async fetchGooglePlacesReviews(opts) {
|
|
6963
6850
|
try {
|
|
@@ -7080,7 +6967,7 @@ class RealReviewsSyncEngine {
|
|
|
7080
6967
|
`;
|
|
7081
6968
|
}
|
|
7082
6969
|
}
|
|
7083
|
-
// src/google-business-profile.ts
|
|
6970
|
+
// packages/lynx-seo-engine/src/google-business-profile.ts
|
|
7084
6971
|
class GoogleBusinessProfileEngine {
|
|
7085
6972
|
static generateLocalBusinessSchema(config) {
|
|
7086
6973
|
const schema = {
|
|
@@ -7294,7 +7181,7 @@ class GoogleBusinessProfileEngine {
|
|
|
7294
7181
|
};
|
|
7295
7182
|
}
|
|
7296
7183
|
}
|
|
7297
|
-
// src/video-youtube-analyzer.ts
|
|
7184
|
+
// packages/lynx-seo-engine/src/video-youtube-analyzer.ts
|
|
7298
7185
|
class VideoYouTubeAnalyzer {
|
|
7299
7186
|
static extractVideoId(urlOrIframe) {
|
|
7300
7187
|
const regExp = /(?:youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
|
|
@@ -7348,7 +7235,7 @@ class VideoYouTubeAnalyzer {
|
|
|
7348
7235
|
`.trim();
|
|
7349
7236
|
}
|
|
7350
7237
|
}
|
|
7351
|
-
// src/power-words-psychology.ts
|
|
7238
|
+
// packages/lynx-seo-engine/src/power-words-psychology.ts
|
|
7352
7239
|
var MULTILINGUAL_POWER_WORDS = {
|
|
7353
7240
|
fr: {
|
|
7354
7241
|
authority: [
|
|
@@ -7368,7 +7255,8 @@ var MULTILINGUAL_POWER_WORDS = {
|
|
|
7368
7255
|
"authentique",
|
|
7369
7256
|
"infaillible",
|
|
7370
7257
|
"reconnu",
|
|
7371
|
-
"démontré"
|
|
7258
|
+
"démontré",
|
|
7259
|
+
"avis"
|
|
7372
7260
|
],
|
|
7373
7261
|
urgency: [
|
|
7374
7262
|
"rapide",
|
|
@@ -7383,7 +7271,8 @@ var MULTILINGUAL_POWER_WORDS = {
|
|
|
7383
7271
|
"en 5 min",
|
|
7384
7272
|
"en 10 min",
|
|
7385
7273
|
"aujourd'hui",
|
|
7386
|
-
"débloquer"
|
|
7274
|
+
"débloquer",
|
|
7275
|
+
"vite"
|
|
7387
7276
|
],
|
|
7388
7277
|
value: [
|
|
7389
7278
|
"gratuit",
|
|
@@ -7399,7 +7288,9 @@ var MULTILINGUAL_POWER_WORDS = {
|
|
|
7399
7288
|
"économisez",
|
|
7400
7289
|
"inclus",
|
|
7401
7290
|
"accessible",
|
|
7402
|
-
"inédit"
|
|
7291
|
+
"inédit",
|
|
7292
|
+
"remise",
|
|
7293
|
+
"promo"
|
|
7403
7294
|
],
|
|
7404
7295
|
curiosity: [
|
|
7405
7296
|
"exclusif",
|
|
@@ -7415,7 +7306,8 @@ var MULTILINGUAL_POWER_WORDS = {
|
|
|
7415
7306
|
"choc",
|
|
7416
7307
|
"incontournable",
|
|
7417
7308
|
"mystère",
|
|
7418
|
-
"incroyable"
|
|
7309
|
+
"incroyable",
|
|
7310
|
+
"vérité"
|
|
7419
7311
|
],
|
|
7420
7312
|
sentimentPositive: [
|
|
7421
7313
|
"parfait",
|
|
@@ -7444,7 +7336,8 @@ var MULTILINGUAL_POWER_WORDS = {
|
|
|
7444
7336
|
"catastrophe",
|
|
7445
7337
|
"risqué",
|
|
7446
7338
|
"menace",
|
|
7447
|
-
"perte"
|
|
7339
|
+
"perte",
|
|
7340
|
+
"alerte"
|
|
7448
7341
|
]
|
|
7449
7342
|
},
|
|
7450
7343
|
en: {
|
|
@@ -7463,7 +7356,9 @@ var MULTILINGUAL_POWER_WORDS = {
|
|
|
7463
7356
|
"authority",
|
|
7464
7357
|
"case study",
|
|
7465
7358
|
"benchmark",
|
|
7466
|
-
"professional"
|
|
7359
|
+
"professional",
|
|
7360
|
+
"review",
|
|
7361
|
+
"formula"
|
|
7467
7362
|
],
|
|
7468
7363
|
urgency: [
|
|
7469
7364
|
"instant",
|
|
@@ -7475,228 +7370,618 @@ var MULTILINGUAL_POWER_WORDS = {
|
|
|
7475
7370
|
"deadline",
|
|
7476
7371
|
"last chance",
|
|
7477
7372
|
"step-by-step",
|
|
7478
|
-
"
|
|
7479
|
-
"
|
|
7480
|
-
"
|
|
7373
|
+
"in 5 minutes",
|
|
7374
|
+
"immediate",
|
|
7375
|
+
"urgent",
|
|
7376
|
+
"unlock",
|
|
7377
|
+
"rapid"
|
|
7481
7378
|
],
|
|
7482
7379
|
value: [
|
|
7483
7380
|
"free",
|
|
7484
7381
|
"affordable",
|
|
7485
|
-
"guaranteed",
|
|
7486
7382
|
"save",
|
|
7487
|
-
"
|
|
7488
|
-
"
|
|
7383
|
+
"guaranteed",
|
|
7384
|
+
"easy",
|
|
7489
7385
|
"bonus",
|
|
7490
|
-
"
|
|
7491
|
-
"priceless",
|
|
7386
|
+
"discount",
|
|
7492
7387
|
"effortless",
|
|
7493
7388
|
"lifetime",
|
|
7494
|
-
"
|
|
7389
|
+
"roi",
|
|
7390
|
+
"value",
|
|
7391
|
+
"exclusive deal",
|
|
7392
|
+
"profitable"
|
|
7495
7393
|
],
|
|
7496
7394
|
curiosity: [
|
|
7497
7395
|
"secret",
|
|
7498
|
-
"secrets",
|
|
7499
|
-
"exclusive",
|
|
7500
7396
|
"revealed",
|
|
7397
|
+
"insider",
|
|
7501
7398
|
"hacks",
|
|
7502
|
-
"
|
|
7503
|
-
"
|
|
7504
|
-
"
|
|
7505
|
-
"uncovered",
|
|
7399
|
+
"why",
|
|
7400
|
+
"how to",
|
|
7401
|
+
"untold",
|
|
7506
7402
|
"surprising",
|
|
7507
|
-
"
|
|
7508
|
-
"
|
|
7509
|
-
"
|
|
7403
|
+
"shocking",
|
|
7404
|
+
"hidden",
|
|
7405
|
+
"must-know",
|
|
7406
|
+
"unbelievable",
|
|
7407
|
+
"myth"
|
|
7510
7408
|
],
|
|
7511
7409
|
sentimentPositive: [
|
|
7512
7410
|
"amazing",
|
|
7513
|
-
"awesome",
|
|
7514
7411
|
"brilliant",
|
|
7412
|
+
"powerful",
|
|
7515
7413
|
"epic",
|
|
7516
|
-
"legendary",
|
|
7517
|
-
"superb",
|
|
7518
|
-
"stunning",
|
|
7519
7414
|
"perfect",
|
|
7520
|
-
"
|
|
7521
|
-
"
|
|
7522
|
-
"
|
|
7523
|
-
"
|
|
7415
|
+
"stunning",
|
|
7416
|
+
"thriving",
|
|
7417
|
+
"seamless",
|
|
7418
|
+
"exceptional",
|
|
7419
|
+
"masterpiece",
|
|
7420
|
+
"unbeatable"
|
|
7524
7421
|
],
|
|
7525
7422
|
sentimentNegative: [
|
|
7526
7423
|
"mistake",
|
|
7527
7424
|
"warning",
|
|
7528
|
-
"
|
|
7425
|
+
"fail",
|
|
7426
|
+
"avoid",
|
|
7427
|
+
"risk",
|
|
7428
|
+
"trap",
|
|
7529
7429
|
"worst",
|
|
7530
|
-
"danger",
|
|
7531
|
-
"toxic",
|
|
7532
|
-
"destroy",
|
|
7533
|
-
"ruin",
|
|
7534
7430
|
"scam",
|
|
7535
|
-
"
|
|
7431
|
+
"danger",
|
|
7432
|
+
"flaw"
|
|
7536
7433
|
]
|
|
7537
7434
|
},
|
|
7538
7435
|
es: {
|
|
7539
|
-
authority: [
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7436
|
+
authority: [
|
|
7437
|
+
"definitiva",
|
|
7438
|
+
"completa",
|
|
7439
|
+
"guía",
|
|
7440
|
+
"experto",
|
|
7441
|
+
"oficial",
|
|
7442
|
+
"certificado",
|
|
7443
|
+
"mejor",
|
|
7444
|
+
"mejores",
|
|
7445
|
+
"comparativa",
|
|
7446
|
+
"profesional",
|
|
7447
|
+
"comprobado",
|
|
7448
|
+
"líder",
|
|
7449
|
+
"análisis"
|
|
7450
|
+
],
|
|
7451
|
+
urgency: [
|
|
7452
|
+
"rápido",
|
|
7453
|
+
"ahora",
|
|
7454
|
+
"urgente",
|
|
7455
|
+
"hoy",
|
|
7456
|
+
"2026",
|
|
7457
|
+
"en 5 minutos",
|
|
7458
|
+
"inmediato",
|
|
7459
|
+
"última oportunidad",
|
|
7460
|
+
"fácil"
|
|
7461
|
+
],
|
|
7462
|
+
value: [
|
|
7463
|
+
"gratis",
|
|
7464
|
+
"económico",
|
|
7465
|
+
"ahorra",
|
|
7466
|
+
"garantizado",
|
|
7467
|
+
"rentable",
|
|
7468
|
+
"oferta",
|
|
7469
|
+
"descuento",
|
|
7470
|
+
"exclusivo"
|
|
7471
|
+
],
|
|
7472
|
+
curiosity: [
|
|
7473
|
+
"secreto",
|
|
7474
|
+
"revelado",
|
|
7475
|
+
"trucos",
|
|
7476
|
+
"por qué",
|
|
7477
|
+
"cómo",
|
|
7478
|
+
"impactante",
|
|
7479
|
+
"increíble",
|
|
7480
|
+
"descubre",
|
|
7481
|
+
"método"
|
|
7482
|
+
],
|
|
7483
|
+
sentimentPositive: [
|
|
7484
|
+
"excelente",
|
|
7485
|
+
"increíble",
|
|
7486
|
+
"perfecto",
|
|
7487
|
+
"potente",
|
|
7488
|
+
"maravilloso",
|
|
7489
|
+
"éxito",
|
|
7490
|
+
"fantástico"
|
|
7491
|
+
],
|
|
7492
|
+
sentimentNegative: [
|
|
7493
|
+
"error",
|
|
7494
|
+
"peligro",
|
|
7495
|
+
"evita",
|
|
7496
|
+
"peor",
|
|
7497
|
+
"estafa",
|
|
7498
|
+
"trampa",
|
|
7499
|
+
"fracaso",
|
|
7500
|
+
"riesgo"
|
|
7501
|
+
]
|
|
7545
7502
|
},
|
|
7546
7503
|
de: {
|
|
7547
|
-
authority: [
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7504
|
+
authority: [
|
|
7505
|
+
"ultimativ",
|
|
7506
|
+
"vollständig",
|
|
7507
|
+
"leitfaden",
|
|
7508
|
+
"experte",
|
|
7509
|
+
"offiziell",
|
|
7510
|
+
"zertifiziert",
|
|
7511
|
+
"beste",
|
|
7512
|
+
"bester",
|
|
7513
|
+
"vergleich",
|
|
7514
|
+
"profi"
|
|
7515
|
+
],
|
|
7516
|
+
urgency: [
|
|
7517
|
+
"schnell",
|
|
7518
|
+
"jetzt",
|
|
7519
|
+
"sofort",
|
|
7520
|
+
"2026",
|
|
7521
|
+
"in 5 minuten",
|
|
7522
|
+
"heute",
|
|
7523
|
+
"dringend",
|
|
7524
|
+
"einfach"
|
|
7525
|
+
],
|
|
7526
|
+
value: [
|
|
7527
|
+
"kostenlos",
|
|
7528
|
+
"gratis",
|
|
7529
|
+
"sparen",
|
|
7530
|
+
"garantiert",
|
|
7531
|
+
"rabatt",
|
|
7532
|
+
"günstig",
|
|
7533
|
+
"angebot",
|
|
7534
|
+
"profitabel"
|
|
7535
|
+
],
|
|
7536
|
+
curiosity: [
|
|
7537
|
+
"geheimnis",
|
|
7538
|
+
"enthüllt",
|
|
7539
|
+
"tricks",
|
|
7540
|
+
"tipps",
|
|
7541
|
+
"warum",
|
|
7542
|
+
"wie man",
|
|
7543
|
+
"unglaublich",
|
|
7544
|
+
"entdecken"
|
|
7545
|
+
],
|
|
7546
|
+
sentimentPositive: [
|
|
7547
|
+
"hervorragend",
|
|
7548
|
+
"perfekt",
|
|
7549
|
+
"genial",
|
|
7550
|
+
"erfolg",
|
|
7551
|
+
"fantastisch",
|
|
7552
|
+
"wunderbar",
|
|
7553
|
+
"stark"
|
|
7554
|
+
],
|
|
7555
|
+
sentimentNegative: [
|
|
7556
|
+
"fehler",
|
|
7557
|
+
"gefahr",
|
|
7558
|
+
"vermeiden",
|
|
7559
|
+
"schlimmste",
|
|
7560
|
+
"betrug",
|
|
7561
|
+
"risiko",
|
|
7562
|
+
"warnung"
|
|
7563
|
+
]
|
|
7553
7564
|
},
|
|
7554
7565
|
it: {
|
|
7555
|
-
authority: [
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7566
|
+
authority: [
|
|
7567
|
+
"guida",
|
|
7568
|
+
"completa",
|
|
7569
|
+
"esperto",
|
|
7570
|
+
"ufficiale",
|
|
7571
|
+
"certificato",
|
|
7572
|
+
"migliore",
|
|
7573
|
+
"migliori",
|
|
7574
|
+
"confronto",
|
|
7575
|
+
"definitiva",
|
|
7576
|
+
"professionale"
|
|
7577
|
+
],
|
|
7578
|
+
urgency: [
|
|
7579
|
+
"veloce",
|
|
7580
|
+
"ora",
|
|
7581
|
+
"subito",
|
|
7582
|
+
"immediato",
|
|
7583
|
+
"2026",
|
|
7584
|
+
"in 5 minuti",
|
|
7585
|
+
"oggi",
|
|
7586
|
+
"urgente"
|
|
7587
|
+
],
|
|
7588
|
+
value: [
|
|
7589
|
+
"gratis",
|
|
7590
|
+
"gratuito",
|
|
7591
|
+
"risparmia",
|
|
7592
|
+
"garantito",
|
|
7593
|
+
"sconto",
|
|
7594
|
+
"facile",
|
|
7595
|
+
"offerta",
|
|
7596
|
+
"conveniente"
|
|
7597
|
+
],
|
|
7598
|
+
curiosity: [
|
|
7599
|
+
"segreto",
|
|
7600
|
+
"svelato",
|
|
7601
|
+
"trucchi",
|
|
7602
|
+
"perché",
|
|
7603
|
+
"come fare",
|
|
7604
|
+
"incredibile",
|
|
7605
|
+
"scopri",
|
|
7606
|
+
"metodo"
|
|
7607
|
+
],
|
|
7608
|
+
sentimentPositive: [
|
|
7609
|
+
"perfetto",
|
|
7610
|
+
"incredibile",
|
|
7611
|
+
"fantastico",
|
|
7612
|
+
"successo",
|
|
7613
|
+
"eccezionale",
|
|
7614
|
+
"meraviglioso"
|
|
7615
|
+
],
|
|
7616
|
+
sentimentNegative: [
|
|
7617
|
+
"errore",
|
|
7618
|
+
"pericolo",
|
|
7619
|
+
"evitare",
|
|
7620
|
+
"peggiore",
|
|
7621
|
+
"truffa",
|
|
7622
|
+
"rischio",
|
|
7623
|
+
"trappola"
|
|
7624
|
+
]
|
|
7561
7625
|
},
|
|
7562
7626
|
nl: {
|
|
7563
|
-
authority: ["
|
|
7564
|
-
urgency: ["snel", "nu", "direct", "
|
|
7565
|
-
value: ["gratis", "
|
|
7566
|
-
curiosity: ["geheim", "
|
|
7567
|
-
sentimentPositive: ["
|
|
7568
|
-
sentimentNegative: ["fout", "gevaar", "
|
|
7627
|
+
authority: ["ultiem", "gids", "expert", "officieel", "beste", "vergelijk", "compleet", "bewezen"],
|
|
7628
|
+
urgency: ["snel", "nu", "direct", "vandaag", "2026", "meteen", "eenvoudig"],
|
|
7629
|
+
value: ["gratis", "bespaar", "gegarandeerd", "korting", "goedkoop", "voordeel"],
|
|
7630
|
+
curiosity: ["geheim", "onthuld", "tips", "waarom", "hoe", "ontdek"],
|
|
7631
|
+
sentimentPositive: ["geweldig", "perfect", "uitstekend", "succes", "fantastisch"],
|
|
7632
|
+
sentimentNegative: ["fout", "gevaar", "vermijd", "slechtste", "oplichting", "risico"]
|
|
7569
7633
|
},
|
|
7570
7634
|
pt: {
|
|
7571
|
-
authority: ["guia", "completo", "definitivo", "especialista", "oficial", "melhor", "melhores", "
|
|
7572
|
-
urgency: ["rápido", "agora", "imediato", "
|
|
7573
|
-
value: ["grátis", "gratuito", "
|
|
7574
|
-
curiosity: ["segredo", "
|
|
7575
|
-
sentimentPositive: ["
|
|
7576
|
-
sentimentNegative: ["erro", "perigo", "
|
|
7635
|
+
authority: ["guia", "completo", "definitivo", "especialista", "oficial", "melhor", "melhores", "comparativo"],
|
|
7636
|
+
urgency: ["rápido", "agora", "imediato", "hoje", "2026", "em 5 minutos", "urgente"],
|
|
7637
|
+
value: ["grátis", "gratuito", "economize", "garantido", "desconto", "fácil", "oferta"],
|
|
7638
|
+
curiosity: ["segredo", "revelado", "dicas", "por que", "como fazer", "incrível", "descubra"],
|
|
7639
|
+
sentimentPositive: ["perfeito", "incrível", "fantástico", "sucesso", "excelente"],
|
|
7640
|
+
sentimentNegative: ["erro", "perigo", "evite", "pior", "golpe", "risco", "cilada"]
|
|
7641
|
+
},
|
|
7642
|
+
ar: {
|
|
7643
|
+
authority: ["دليل", "شامل", "رسمي", "خبير", "أفضل", "مقارنة", "معتمد", "نهائي"],
|
|
7644
|
+
urgency: ["سريع", "الآن", "فوري", "اليوم", "2026", "في دقائق", "عاجل"],
|
|
7645
|
+
value: ["مجانا", "وفر", "مضمون", "خصم", "سهل", "عرض", "مميز"],
|
|
7646
|
+
curiosity: ["سر", "كشف", "أسرار", "لماذا", "كيف", "مذهل", "اكتشف"],
|
|
7647
|
+
sentimentPositive: ["رائع", "ممتاز", "ناجح", "مبهر", "مثالي"],
|
|
7648
|
+
sentimentNegative: ["خطأ", "تحذير", "تجنب", "فخ", "احتيال", "خطر"]
|
|
7649
|
+
},
|
|
7650
|
+
ru: {
|
|
7651
|
+
authority: ["руководство", "полный", "эксперт", "официальный", "лучший", "лучшие", "сравнение", "проверенный"],
|
|
7652
|
+
urgency: ["быстро", "сейчас", "срочно", "сегодня", "2026", "за 5 минут", "немедленно"],
|
|
7653
|
+
value: ["бесплатно", "скидка", "гарантия", "выгодно", "легко", "акция"],
|
|
7654
|
+
curiosity: ["секрет", "раскрыт", "лайфхаки", "почему", "как", "невероятный", "узнайте"],
|
|
7655
|
+
sentimentPositive: ["отлично", "идеально", "успех", "потрясающий", "великолепный"],
|
|
7656
|
+
sentimentNegative: ["ошибка", "опасность", "избегать", "худший", "обман", "риск"]
|
|
7657
|
+
},
|
|
7658
|
+
zh: {
|
|
7659
|
+
authority: ["终极", "完整", "指南", "专家", "官方", "最佳", "对比", "评测", "权威"],
|
|
7660
|
+
urgency: ["快速", "立即", "今天", "2026", "5分钟", "马上", "紧急"],
|
|
7661
|
+
value: ["免费", "省钱", "保证", "优惠", "简单", "折扣", "高性价比"],
|
|
7662
|
+
curiosity: ["秘密", "揭秘", "技巧", "为什么", "如何", "必看", "探索"],
|
|
7663
|
+
sentimentPositive: ["完美", "惊人", "卓越", "成功", "极佳", "出色"],
|
|
7664
|
+
sentimentNegative: ["错误", "陷阱", "避免", "危险", "骗局", "风险"]
|
|
7665
|
+
},
|
|
7666
|
+
ja: {
|
|
7667
|
+
authority: ["完全ガイド", "究極", "公式", "専門家", "おすすめ", "徹底比較", "決定版", "プロ"],
|
|
7668
|
+
urgency: ["今すぐ", "速報", "最短", "2026年", "今日", "5分で", "簡単"],
|
|
7669
|
+
value: ["無料", "お得", "割引", "保証", "コスパ", "特典", "プレゼント"],
|
|
7670
|
+
curiosity: ["秘密", "裏ワザ", "暴露", "なぜ", "方法", "必見", "真実"],
|
|
7671
|
+
sentimentPositive: ["最高", "完璧", "圧倒的", "成功", "絶賛", "素晴らしい"],
|
|
7672
|
+
sentimentNegative: ["失敗", "注意", "危険", "避けるべき", "詐欺", "罠"]
|
|
7673
|
+
},
|
|
7674
|
+
hi: {
|
|
7675
|
+
authority: ["गाइड", "सम्पूर्ण", "विशेषज्ञ", "आधिकारिक", "सर्वश्रेष्ठ", "तुलना", "सटीक"],
|
|
7676
|
+
urgency: ["तुरंत", "अभी", "आज", "2026", "5 मिनट में", "जल्दी"],
|
|
7677
|
+
value: ["मुफ्त", "बचत", "गारंटी", "छूट", "आसान", "ऑफर"],
|
|
7678
|
+
curiosity: ["रहस्य", "खुलासा", "टिप्स", "क्यों", "कैसे", "अनोखा"],
|
|
7679
|
+
sentimentPositive: ["उत्कृष्ट", "शानदार", "सफल", "अद्भुत", "बेहतरीन"],
|
|
7680
|
+
sentimentNegative: ["गलती", "खतरा", "सावधान", "धोखा", "नुकसान"]
|
|
7577
7681
|
}
|
|
7578
7682
|
};
|
|
7579
7683
|
|
|
7580
7684
|
class PowerWordsPsychologyEngine {
|
|
7581
|
-
static
|
|
7582
|
-
const
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7685
|
+
static registerLanguageWords(langCode, words) {
|
|
7686
|
+
const code = langCode.toLowerCase().trim();
|
|
7687
|
+
if (!MULTILINGUAL_POWER_WORDS[code]) {
|
|
7688
|
+
MULTILINGUAL_POWER_WORDS[code] = {
|
|
7689
|
+
authority: [],
|
|
7690
|
+
urgency: [],
|
|
7691
|
+
value: [],
|
|
7692
|
+
curiosity: [],
|
|
7693
|
+
sentimentPositive: [],
|
|
7694
|
+
sentimentNegative: []
|
|
7695
|
+
};
|
|
7696
|
+
}
|
|
7697
|
+
if (words.authority)
|
|
7698
|
+
MULTILINGUAL_POWER_WORDS[code].authority.push(...words.authority);
|
|
7699
|
+
if (words.urgency)
|
|
7700
|
+
MULTILINGUAL_POWER_WORDS[code].urgency.push(...words.urgency);
|
|
7701
|
+
if (words.value)
|
|
7702
|
+
MULTILINGUAL_POWER_WORDS[code].value.push(...words.value);
|
|
7703
|
+
if (words.curiosity)
|
|
7704
|
+
MULTILINGUAL_POWER_WORDS[code].curiosity.push(...words.curiosity);
|
|
7705
|
+
if (words.sentimentPositive)
|
|
7706
|
+
MULTILINGUAL_POWER_WORDS[code].sentimentPositive.push(...words.sentimentPositive);
|
|
7707
|
+
if (words.sentimentNegative)
|
|
7708
|
+
MULTILINGUAL_POWER_WORDS[code].sentimentNegative.push(...words.sentimentNegative);
|
|
7709
|
+
}
|
|
7710
|
+
static getSupportedLanguages() {
|
|
7711
|
+
return Object.keys(MULTILINGUAL_POWER_WORDS);
|
|
7712
|
+
}
|
|
7713
|
+
static analyzeTitle(title, lang = "fr") {
|
|
7714
|
+
const raw = (title || "").toLowerCase().trim();
|
|
7715
|
+
const langKey = lang.toLowerCase().trim();
|
|
7716
|
+
const primaryBank = MULTILINGUAL_POWER_WORDS[langKey] || MULTILINGUAL_POWER_WORDS["en"] || MULTILINGUAL_POWER_WORDS["fr"];
|
|
7717
|
+
const allBanks = [primaryBank];
|
|
7718
|
+
if (langKey !== "en" && MULTILINGUAL_POWER_WORDS["en"])
|
|
7719
|
+
allBanks.push(MULTILINGUAL_POWER_WORDS["en"]);
|
|
7720
|
+
const detectedWords = [];
|
|
7721
|
+
let authorityMatch = false;
|
|
7722
|
+
let urgencyMatch = false;
|
|
7723
|
+
let valueMatch = false;
|
|
7724
|
+
let curiosityMatch = false;
|
|
7725
|
+
let positiveCount = 0;
|
|
7726
|
+
let negativeCount = 0;
|
|
7727
|
+
for (const bank of allBanks) {
|
|
7728
|
+
for (const word of bank.authority) {
|
|
7729
|
+
if (raw.includes(word.toLowerCase())) {
|
|
7730
|
+
authorityMatch = true;
|
|
7731
|
+
if (!detectedWords.includes(word))
|
|
7732
|
+
detectedWords.push(word);
|
|
7733
|
+
}
|
|
7590
7734
|
}
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
detectedPowerWords.push(w);
|
|
7598
|
-
return true;
|
|
7735
|
+
for (const word of bank.urgency) {
|
|
7736
|
+
if (raw.includes(word.toLowerCase())) {
|
|
7737
|
+
urgencyMatch = true;
|
|
7738
|
+
if (!detectedWords.includes(word))
|
|
7739
|
+
detectedWords.push(word);
|
|
7740
|
+
}
|
|
7599
7741
|
}
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
detectedPowerWords.push(w);
|
|
7607
|
-
return true;
|
|
7742
|
+
for (const word of bank.value) {
|
|
7743
|
+
if (raw.includes(word.toLowerCase())) {
|
|
7744
|
+
valueMatch = true;
|
|
7745
|
+
if (!detectedWords.includes(word))
|
|
7746
|
+
detectedWords.push(word);
|
|
7747
|
+
}
|
|
7608
7748
|
}
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
detectedPowerWords.push(w);
|
|
7616
|
-
return true;
|
|
7749
|
+
for (const word of bank.curiosity) {
|
|
7750
|
+
if (raw.includes(word.toLowerCase())) {
|
|
7751
|
+
curiosityMatch = true;
|
|
7752
|
+
if (!detectedWords.includes(word))
|
|
7753
|
+
detectedWords.push(word);
|
|
7754
|
+
}
|
|
7617
7755
|
}
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7756
|
+
for (const word of bank.sentimentPositive) {
|
|
7757
|
+
if (raw.includes(word.toLowerCase())) {
|
|
7758
|
+
positiveCount++;
|
|
7759
|
+
if (!detectedWords.includes(word))
|
|
7760
|
+
detectedWords.push(word);
|
|
7761
|
+
}
|
|
7762
|
+
}
|
|
7763
|
+
for (const word of bank.sentimentNegative) {
|
|
7764
|
+
if (raw.includes(word.toLowerCase())) {
|
|
7765
|
+
negativeCount++;
|
|
7766
|
+
if (!detectedWords.includes(word))
|
|
7767
|
+
detectedWords.push(word);
|
|
7768
|
+
}
|
|
7769
|
+
}
|
|
7770
|
+
}
|
|
7771
|
+
const hasNumber = /\b\d+\b/.test(raw);
|
|
7772
|
+
const hasYear = /\b(202[4-9]|203[0-9])\b/.test(raw);
|
|
7773
|
+
const hasCurrencyOrDiscount = /[\$€£¥₹%]|د\.إ|﷼|\b(promo|soldes|discount|deal|off)\b/i.test(raw);
|
|
7774
|
+
const hasBracketsOrParentheses = /[\[\]\(\)\{\}【】《》「」]/.test(raw);
|
|
7775
|
+
let score = 30;
|
|
7776
|
+
if (detectedWords.length >= 1)
|
|
7777
|
+
score += 20;
|
|
7778
|
+
if (detectedWords.length >= 2)
|
|
7779
|
+
score += 10;
|
|
7780
|
+
if (detectedWords.length >= 3)
|
|
7621
7781
|
score += 10;
|
|
7622
|
-
const hasNumber = /\d+/.test(title);
|
|
7623
7782
|
if (hasNumber)
|
|
7783
|
+
score += 15;
|
|
7784
|
+
if (hasYear)
|
|
7624
7785
|
score += 10;
|
|
7625
|
-
|
|
7626
|
-
|
|
7786
|
+
if (hasCurrencyOrDiscount)
|
|
7787
|
+
score += 5;
|
|
7788
|
+
if (hasBracketsOrParentheses)
|
|
7789
|
+
score += 5;
|
|
7790
|
+
if (score > 100)
|
|
7791
|
+
score = 100;
|
|
7627
7792
|
let sentiment = "neutre";
|
|
7628
|
-
|
|
7629
|
-
const hasNegative = dict.sentimentNegative.some((w) => cleanTitle.includes(w));
|
|
7630
|
-
if (hasPositive) {
|
|
7793
|
+
if (positiveCount > negativeCount)
|
|
7631
7794
|
sentiment = "positif";
|
|
7632
|
-
|
|
7795
|
+
else if (negativeCount > positiveCount)
|
|
7633
7796
|
sentiment = "negatif";
|
|
7634
|
-
}
|
|
7635
7797
|
const recommendations = [];
|
|
7636
|
-
if (
|
|
7637
|
-
recommendations.push("Ajoutez au moins
|
|
7798
|
+
if (detectedWords.length === 0) {
|
|
7799
|
+
recommendations.push("Ajoutez au moins 1 mot d'impact émotionnel ou d'autorité (ex: 'Guide', 'Ultime', 'Meilleur').");
|
|
7638
7800
|
}
|
|
7639
7801
|
if (!hasNumber) {
|
|
7640
|
-
recommendations.push("Intégrez un chiffre
|
|
7802
|
+
recommendations.push("Intégrez un chiffre (ex: 'Les 7 Meilleurs...') pour augmenter le taux de clic de +36%.");
|
|
7641
7803
|
}
|
|
7642
|
-
if (
|
|
7643
|
-
recommendations.push("
|
|
7804
|
+
if (!hasYear) {
|
|
7805
|
+
recommendations.push("Indiquez l'année courante (2026) pour signaler la fraîcheur du contenu aux internautes.");
|
|
7644
7806
|
}
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
suggestedTitles.push(`${title} : Guide Ultime 2026`);
|
|
7648
|
-
suggestedTitles.push(`Les 5 Meilleurs ${title} (Comparatif & Avis)`);
|
|
7649
|
-
suggestedTitles.push(`${title} — Solution Rapide & Complète`);
|
|
7650
|
-
} else {
|
|
7651
|
-
suggestedTitles.push(`${title}: The Ultimate 2026 Guide`);
|
|
7652
|
-
suggestedTitles.push(`Top 5 Best ${title} (Full Review & Comparison)`);
|
|
7653
|
-
suggestedTitles.push(`${title} — Proven & Fast Method`);
|
|
7807
|
+
if (!hasBracketsOrParentheses) {
|
|
7808
|
+
recommendations.push("Utilisez des crochets ou parenthèses [Guide 2026] pour structurer visuellement l'extrait.");
|
|
7654
7809
|
}
|
|
7810
|
+
const cleanSubject = title.replace(/\(.*?\)|\[.*?\]/g, "").trim();
|
|
7811
|
+
const suggestedTitles = [
|
|
7812
|
+
`Les 7 Meilleurs ${cleanSubject} [Guide Ultime 2026]`,
|
|
7813
|
+
`Comment Maîtriser ${cleanSubject} en 5 Étapes (Méthode 2026)`,
|
|
7814
|
+
`${cleanSubject} : Avis, Comparatif et Pièges à Éviter (2026)`
|
|
7815
|
+
];
|
|
7655
7816
|
return {
|
|
7656
|
-
score
|
|
7657
|
-
powerWordsDetected:
|
|
7817
|
+
score,
|
|
7818
|
+
powerWordsDetected: detectedWords,
|
|
7658
7819
|
sentiment,
|
|
7659
7820
|
hasNumber,
|
|
7660
7821
|
hasYear,
|
|
7661
|
-
hasCuriosityTrigger:
|
|
7662
|
-
hasUrgencyTrigger:
|
|
7663
|
-
hasAuthorityTrigger:
|
|
7822
|
+
hasCuriosityTrigger: curiosityMatch,
|
|
7823
|
+
hasUrgencyTrigger: urgencyMatch,
|
|
7824
|
+
hasAuthorityTrigger: authorityMatch,
|
|
7825
|
+
hasCurrencyOrDiscount,
|
|
7826
|
+
hasBracketsOrParentheses,
|
|
7664
7827
|
recommendations,
|
|
7665
7828
|
suggestedTitles
|
|
7666
7829
|
};
|
|
7667
7830
|
}
|
|
7668
|
-
static enrichProgrammaticTitle(
|
|
7669
|
-
const
|
|
7670
|
-
if (
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7831
|
+
static enrichProgrammaticTitle(baseTitle, lang = "fr") {
|
|
7832
|
+
const analysis = this.analyzeTitle(baseTitle, lang);
|
|
7833
|
+
if (analysis.score >= 80)
|
|
7834
|
+
return baseTitle;
|
|
7835
|
+
let enriched = baseTitle.trim();
|
|
7836
|
+
if (!analysis.hasNumber && !enriched.startsWith("Top ") && !enriched.startsWith("Les ")) {
|
|
7837
|
+
enriched = `Les Meilleurs ${enriched}`;
|
|
7838
|
+
}
|
|
7839
|
+
if (!analysis.hasYear) {
|
|
7840
|
+
enriched = `${enriched} (Guide 2026)`;
|
|
7841
|
+
}
|
|
7842
|
+
return enriched;
|
|
7843
|
+
}
|
|
7844
|
+
}
|
|
7845
|
+
// packages/lynx-seo-engine/src/features-knowledge-harvester.ts
|
|
7846
|
+
class FeaturesKnowledgeHarvester2 {
|
|
7847
|
+
static knowledgeStore = new Map;
|
|
7848
|
+
static extractFromHtml(url, html, slug) {
|
|
7849
|
+
const pageSlug = slug || url.split("/").filter(Boolean).pop() || "feature";
|
|
7850
|
+
const titleMatch = html.match(/<h1[^>]*>([\s\S]*?)<\/h1>/i) || html.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
|
|
7851
|
+
const title = titleMatch ? titleMatch[1].replace(/<[^>]+>/g, "").trim() : "Module " + pageSlug;
|
|
7852
|
+
const paragraphMatches = html.matchAll(/<p[^>]*>([\s\S]*?)<\/p>/gi);
|
|
7853
|
+
const paragraphs = [];
|
|
7854
|
+
for (const match of paragraphMatches) {
|
|
7855
|
+
const clean = match[1].replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
7856
|
+
if (clean.length > 40 && !clean.includes("Cookie") && !clean.includes("Copyright")) {
|
|
7857
|
+
paragraphs.push(clean);
|
|
7858
|
+
if (paragraphs.length >= 15)
|
|
7859
|
+
break;
|
|
7677
7860
|
}
|
|
7678
|
-
}
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7861
|
+
}
|
|
7862
|
+
const liMatches = html.matchAll(/<li[^>]*>([\s\S]*?)<\/li>/gi);
|
|
7863
|
+
const keyBenefits = [];
|
|
7864
|
+
for (const match of liMatches) {
|
|
7865
|
+
const clean = match[1].replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
7866
|
+
if (clean.length > 20 && clean.length < 200) {
|
|
7867
|
+
keyBenefits.push(clean);
|
|
7868
|
+
if (keyBenefits.length >= 8)
|
|
7869
|
+
break;
|
|
7685
7870
|
}
|
|
7686
|
-
}
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7871
|
+
}
|
|
7872
|
+
const faqs = [];
|
|
7873
|
+
const faqMatches = html.matchAll(/<summary[^>]*>([\s\S]*?)<\/summary>[\s\S]*?<p[^>]*>([\s\S]*?)<\/p>/gi);
|
|
7874
|
+
for (const match of faqMatches) {
|
|
7875
|
+
const question = match[1].replace(/<[^>]+>/g, "").trim();
|
|
7876
|
+
const answer = match[2].replace(/<[^>]+>/g, "").trim();
|
|
7877
|
+
if (question && answer) {
|
|
7878
|
+
faqs.push({ question, answer });
|
|
7691
7879
|
}
|
|
7692
|
-
} else if (lang === "de") {
|
|
7693
|
-
return `Beste ${service} in ${locationOrCompetitor}: Kompletter Leitfaden ${year}`;
|
|
7694
|
-
} else {
|
|
7695
|
-
return `${service} in ${locationOrCompetitor} (${year})`;
|
|
7696
7880
|
}
|
|
7881
|
+
const workflowSteps = [
|
|
7882
|
+
{ step: 1, title: "Configuration Automatique", description: `Activation du module ${title} en 1 clic.` },
|
|
7883
|
+
{ step: 2, title: "Résolution en Mémoire Vive", description: "Traitement ultra-rapide sans latence SQL." },
|
|
7884
|
+
{ step: 3, title: "Déploiement Continu", description: "Mise à jour en temps réel sur l'ensemble de vos pages." }
|
|
7885
|
+
];
|
|
7886
|
+
const executiveSummary = paragraphs.slice(0, 2).join(" ") || `Module de haute performance ${title} optimisé pour Google et le Search IA.`;
|
|
7887
|
+
const knowledge = {
|
|
7888
|
+
slug: pageSlug,
|
|
7889
|
+
url,
|
|
7890
|
+
title,
|
|
7891
|
+
category: "Feature Suite",
|
|
7892
|
+
executiveSummary,
|
|
7893
|
+
paragraphs,
|
|
7894
|
+
keyBenefits,
|
|
7895
|
+
workflowSteps,
|
|
7896
|
+
faqs,
|
|
7897
|
+
rawTextLength: paragraphs.join(" ").length
|
|
7898
|
+
};
|
|
7899
|
+
this.knowledgeStore.set(pageSlug, knowledge);
|
|
7900
|
+
return knowledge;
|
|
7901
|
+
}
|
|
7902
|
+
static async ingestPagesFromSitemap(sitemapUrl) {
|
|
7903
|
+
try {
|
|
7904
|
+
const res = await fetch(sitemapUrl);
|
|
7905
|
+
if (!res.ok)
|
|
7906
|
+
return 0;
|
|
7907
|
+
const xml = await res.text();
|
|
7908
|
+
const urls = [...xml.matchAll(/<loc>([\s\S]*?)<\/loc>/gi)].map((m) => m[1].trim());
|
|
7909
|
+
let count = 0;
|
|
7910
|
+
for (const u of urls.slice(0, 50)) {
|
|
7911
|
+
try {
|
|
7912
|
+
const pageRes = await fetch(u);
|
|
7913
|
+
if (pageRes.ok) {
|
|
7914
|
+
const html = await pageRes.text();
|
|
7915
|
+
this.extractFromHtml(u, html);
|
|
7916
|
+
count++;
|
|
7917
|
+
}
|
|
7918
|
+
} catch {}
|
|
7919
|
+
}
|
|
7920
|
+
return count;
|
|
7921
|
+
} catch {
|
|
7922
|
+
return 0;
|
|
7923
|
+
}
|
|
7924
|
+
}
|
|
7925
|
+
static getKnowledge(slug) {
|
|
7926
|
+
return this.knowledgeStore.get(slug);
|
|
7927
|
+
}
|
|
7928
|
+
static getAllKnowledge() {
|
|
7929
|
+
return Array.from(this.knowledgeStore.values());
|
|
7930
|
+
}
|
|
7931
|
+
static buildEnrichedPage(slug, locationOrSector) {
|
|
7932
|
+
const k = this.getKnowledge(slug);
|
|
7933
|
+
if (!k) {
|
|
7934
|
+
return `# Solution ${slug} à ${locationOrSector}
|
|
7935
|
+
|
|
7936
|
+
Explications complètes et déploiement immédiat.`;
|
|
7937
|
+
}
|
|
7938
|
+
return `
|
|
7939
|
+
# ${k.title} à ${locationOrSector} (Guide Complet & Déploiement 2026)
|
|
7940
|
+
|
|
7941
|
+
> **Résumé Exécutif :** ${k.executiveSummary}
|
|
7942
|
+
|
|
7943
|
+
---
|
|
7944
|
+
|
|
7945
|
+
## \uD83D\uDCD6 Analyse Approfondie & Fonctionnement
|
|
7946
|
+
|
|
7947
|
+
${k.paragraphs.slice(0, 6).join(`
|
|
7948
|
+
|
|
7949
|
+
`)}
|
|
7950
|
+
|
|
7951
|
+
---
|
|
7952
|
+
|
|
7953
|
+
## \uD83D\uDC8E Fonctionnalités Clés & Avantages Concrets :
|
|
7954
|
+
|
|
7955
|
+
${k.keyBenefits.map((b) => `* **${b}**`).join(`
|
|
7956
|
+
`)}
|
|
7957
|
+
|
|
7958
|
+
---
|
|
7959
|
+
|
|
7960
|
+
## \uD83D\uDEE0️ Guide de Mise en Œuvre en 3 Étapes :
|
|
7961
|
+
|
|
7962
|
+
${k.workflowSteps.map((s) => `${s.step}. **${s.title}** : ${s.description}`).join(`
|
|
7963
|
+
`)}
|
|
7964
|
+
|
|
7965
|
+
---
|
|
7966
|
+
|
|
7967
|
+
${k.paragraphs.slice(6, 12).join(`
|
|
7968
|
+
|
|
7969
|
+
`)}
|
|
7970
|
+
|
|
7971
|
+
---
|
|
7972
|
+
|
|
7973
|
+
## ❓ Questions Fréquentes & Réponses Officielles :
|
|
7974
|
+
|
|
7975
|
+
${k.faqs.length > 0 ? k.faqs.map((f) => `### ${f.question}
|
|
7976
|
+
${f.answer}`).join(`
|
|
7977
|
+
|
|
7978
|
+
`) : `### Comment activer ${k.title} à ${locationOrSector} ?
|
|
7979
|
+
L'activation est instantanée en 1 clic sans compétences techniques.`}
|
|
7980
|
+
`.trim();
|
|
7697
7981
|
}
|
|
7698
7982
|
}
|
|
7699
|
-
|
|
7983
|
+
|
|
7984
|
+
// packages/lynx-seo-engine/src/index.ts
|
|
7700
7985
|
function createLynxSeoEngine(config) {
|
|
7701
7986
|
return new LynxSeoEngine(config);
|
|
7702
7987
|
}
|
|
@@ -7736,8 +8021,83 @@ var LynxSeo = {
|
|
|
7736
8021
|
adIntelligence: AdIntelligenceCroEngine,
|
|
7737
8022
|
rankMathScore: RankMathParityEngine,
|
|
7738
8023
|
yoastReadability: YoastParityEngine,
|
|
7739
|
-
socialGrowth: SocialGrowthSuite,
|
|
7740
8024
|
rbac: TeamRbacEngine,
|
|
7741
|
-
realReviews: RealReviewsSyncEngine
|
|
8025
|
+
realReviews: RealReviewsSyncEngine,
|
|
8026
|
+
knowledgeHarvester: FeaturesKnowledgeHarvester
|
|
7742
8027
|
};
|
|
7743
8028
|
var src_default = LynxSeo;
|
|
8029
|
+
export {
|
|
8030
|
+
validateSeoSlug,
|
|
8031
|
+
resolveFeatureIcon,
|
|
8032
|
+
resolveBuiltInLocations,
|
|
8033
|
+
resolveBrandIcon,
|
|
8034
|
+
renderUiIconSvg,
|
|
8035
|
+
renderBrandIconSvg,
|
|
8036
|
+
getSeoAgentPrompt,
|
|
8037
|
+
src_default as default,
|
|
8038
|
+
createLynxSeoEngine,
|
|
8039
|
+
cleanSeoSlug,
|
|
8040
|
+
YoastParityEngine,
|
|
8041
|
+
VideoYouTubeAnalyzer,
|
|
8042
|
+
UrlyticsEngine,
|
|
8043
|
+
UI_ICONS,
|
|
8044
|
+
TokenQuotaManager,
|
|
8045
|
+
TechnicalRulesAuditor,
|
|
8046
|
+
TeamRbacEngine,
|
|
8047
|
+
SocialVideoSeoAnalyticsEngine,
|
|
8048
|
+
SocialTrendSeoGenerator,
|
|
8049
|
+
SocialGrowthSuite,
|
|
8050
|
+
SocialAdsSocialSeoEngine,
|
|
8051
|
+
SiteAuditor,
|
|
8052
|
+
SerpRankHistoryEngine,
|
|
8053
|
+
SerpClient,
|
|
8054
|
+
SeoOpportunitiesDecayDetector,
|
|
8055
|
+
SchemaGraphBuilder,
|
|
8056
|
+
SUPPORTED_CANONICAL_LOCALES,
|
|
8057
|
+
SCHEMA_LOCAL_BUSINESS_MAP,
|
|
8058
|
+
RssSyndicationFeedGenerator,
|
|
8059
|
+
RealReviewsSyncEngine,
|
|
8060
|
+
RankMathParityEngine,
|
|
8061
|
+
PseoMatrixEngine,
|
|
8062
|
+
PowerWordsPsychologyEngine,
|
|
8063
|
+
PSEO_AGENT_SYSTEM_PROMPT,
|
|
8064
|
+
OgImageGenerator,
|
|
8065
|
+
NGramDensityAnalyzer,
|
|
8066
|
+
McpSeoServerHub,
|
|
8067
|
+
MasterMarketingEngine,
|
|
8068
|
+
MULTILINGUAL_STOP_WORDS,
|
|
8069
|
+
MULTILINGUAL_POWER_WORDS,
|
|
8070
|
+
MULTILINGUAL_DISCLAIMERS,
|
|
8071
|
+
MULTILINGUAL_BANNED_DISPARAGING_WORDS,
|
|
8072
|
+
LynxSeoEngine,
|
|
8073
|
+
LynxSeo,
|
|
8074
|
+
LynxAnalyticsClient,
|
|
8075
|
+
LlmContentCleaner,
|
|
8076
|
+
LegalDisclaimerEngine,
|
|
8077
|
+
LagoTokenMeter,
|
|
8078
|
+
KnowledgeGraphLinker,
|
|
8079
|
+
KeywordPermutatorEngine,
|
|
8080
|
+
IsrCacheManager,
|
|
8081
|
+
InstantMatrixSearchEngine,
|
|
8082
|
+
IndexNowClient,
|
|
8083
|
+
I18nDetector,
|
|
8084
|
+
HyperswitchGateway,
|
|
8085
|
+
GoogleBusinessProfileEngine,
|
|
8086
|
+
GeoMeshLinkingEngine,
|
|
8087
|
+
FreePublicToolsEngine,
|
|
8088
|
+
FeaturesKnowledgeHarvester2 as FeaturesKnowledgeHarvester,
|
|
8089
|
+
ExtendedSchemaGraphBuilder,
|
|
8090
|
+
EmbeddableSeoWidgetGenerator,
|
|
8091
|
+
DeepCrawlerAuditor,
|
|
8092
|
+
CrosslinkScorerEngine,
|
|
8093
|
+
CroCopywritingEngine,
|
|
8094
|
+
CopywritingFrameworksMaster,
|
|
8095
|
+
BrandDnaCalendarEngine,
|
|
8096
|
+
BacklinksClient,
|
|
8097
|
+
BUILT_IN_LOCATIONS_DATABASE,
|
|
8098
|
+
BRAND_ICONS,
|
|
8099
|
+
ApiKeyGuardian,
|
|
8100
|
+
AiCopilotClient,
|
|
8101
|
+
AiBotsLogAnalyzer,
|
|
8102
|
+
AdIntelligenceCroEngine
|
|
8103
|
+
};
|