@contentstorage/i18next-plugin 2.0.20 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +60 -185
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +59 -189
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +0 -7
- package/dist/plugin.d.ts.map +1 -1
- package/dist/post-processor.d.ts +1 -6
- package/dist/post-processor.d.ts.map +1 -1
- package/dist/utils.d.ts +8 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,12 +32,19 @@ function detectLiveEditorMode(liveEditorParam = 'contentstorage_live_editor', fo
|
|
|
32
32
|
const win = getContentstorageWindow();
|
|
33
33
|
if (!win)
|
|
34
34
|
return false;
|
|
35
|
-
// Check 1: Running in an iframe
|
|
36
|
-
const inIframe = win.self !== win.top;
|
|
37
|
-
// Check 2: URL has the live editor marker
|
|
38
35
|
const urlParams = new URLSearchParams(win.location.search);
|
|
39
36
|
const hasMarker = urlParams.has(liveEditorParam);
|
|
40
|
-
|
|
37
|
+
if (!hasMarker)
|
|
38
|
+
return false;
|
|
39
|
+
// Check 1: Running in an iframe (standard live editor)
|
|
40
|
+
const inIframe = win.self !== win.top;
|
|
41
|
+
if (inIframe)
|
|
42
|
+
return true;
|
|
43
|
+
// Check 2: PiP mode (popup with opener)
|
|
44
|
+
const isPipMode = urlParams.get('pip_mode') === 'true' && !!win.opener;
|
|
45
|
+
if (isPipMode)
|
|
46
|
+
return true;
|
|
47
|
+
return false;
|
|
41
48
|
}
|
|
42
49
|
catch (e) {
|
|
43
50
|
// Cross-origin restrictions might block window.top access
|
|
@@ -45,6 +52,32 @@ function detectLiveEditorMode(liveEditorParam = 'contentstorage_live_editor', fo
|
|
|
45
52
|
return false;
|
|
46
53
|
}
|
|
47
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Detects if the application is running in PiP (Picture-in-Picture) mode
|
|
57
|
+
* PiP mode requires pip_mode=true URL param and window.opener
|
|
58
|
+
*
|
|
59
|
+
* @returns true if in PiP mode
|
|
60
|
+
*/
|
|
61
|
+
function detectPipMode() {
|
|
62
|
+
if (!isBrowser())
|
|
63
|
+
return false;
|
|
64
|
+
const win = getContentstorageWindow();
|
|
65
|
+
if (!win)
|
|
66
|
+
return false;
|
|
67
|
+
try {
|
|
68
|
+
const urlParams = new URLSearchParams(win.location.search);
|
|
69
|
+
if (urlParams.get('pip_mode') !== 'true')
|
|
70
|
+
return false;
|
|
71
|
+
if (!win.opener) {
|
|
72
|
+
console.warn('[Contentstorage] PiP mode requires opener window');
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
48
81
|
/**
|
|
49
82
|
* Initializes the global memory map if it doesn't exist
|
|
50
83
|
*/
|
|
@@ -62,7 +95,7 @@ function initializeMemoryMap() {
|
|
|
62
95
|
* This script enables the click-to-edit functionality in the live editor
|
|
63
96
|
*/
|
|
64
97
|
let liveEditorReadyPromise = null;
|
|
65
|
-
function loadLiveEditorScript(retries = 2, delay = 3000, debug = false, customScriptUrl) {
|
|
98
|
+
function loadLiveEditorScript(retries = 2, delay = 3000, debug = false, customScriptUrl, mode) {
|
|
66
99
|
// Return existing promise if already loading
|
|
67
100
|
if (liveEditorReadyPromise) {
|
|
68
101
|
return liveEditorReadyPromise;
|
|
@@ -73,7 +106,12 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false, customSc
|
|
|
73
106
|
resolve(false);
|
|
74
107
|
return;
|
|
75
108
|
}
|
|
76
|
-
|
|
109
|
+
let cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';
|
|
110
|
+
// Add pip_mode URL parameter if in pip mode
|
|
111
|
+
if (mode === 'pip') {
|
|
112
|
+
const separator = cdnScriptUrl.includes('?') ? '&' : '?';
|
|
113
|
+
cdnScriptUrl += `${separator}pip_mode=true`;
|
|
114
|
+
}
|
|
77
115
|
const loadScript = (attempt = 1) => {
|
|
78
116
|
if (debug) {
|
|
79
117
|
console.log(`[Contentstorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);
|
|
@@ -349,113 +387,6 @@ function debugMemoryMap() {
|
|
|
349
387
|
}
|
|
350
388
|
}
|
|
351
389
|
|
|
352
|
-
/**
|
|
353
|
-
* Decodes and validates the contentstorage key
|
|
354
|
-
* Just decodes URL encoding and checks non-empty (backend validates format)
|
|
355
|
-
*
|
|
356
|
-
* @param key - The raw key from URL params
|
|
357
|
-
* @returns Decoded key if valid, null if empty/invalid
|
|
358
|
-
*/
|
|
359
|
-
function decodeContentstorageKey(key) {
|
|
360
|
-
if (!key)
|
|
361
|
-
return null;
|
|
362
|
-
try {
|
|
363
|
-
const decoded = decodeURIComponent(key);
|
|
364
|
-
return decoded.trim() || null;
|
|
365
|
-
}
|
|
366
|
-
catch {
|
|
367
|
-
return null;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* Detects if screenshot mode should be activated
|
|
372
|
-
* Requires: contentstorage_live_editor=true AND screenshot_mode=true AND valid contentstorage_key
|
|
373
|
-
*
|
|
374
|
-
* NOTE: Unlike live editor mode, screenshot mode does NOT require iframe
|
|
375
|
-
*
|
|
376
|
-
* @returns Object with contentstorageKey if active, null otherwise
|
|
377
|
-
*/
|
|
378
|
-
function detectScreenshotMode() {
|
|
379
|
-
if (!isBrowser())
|
|
380
|
-
return null;
|
|
381
|
-
const win = getContentstorageWindow();
|
|
382
|
-
if (!win)
|
|
383
|
-
return null;
|
|
384
|
-
try {
|
|
385
|
-
const urlParams = new URLSearchParams(win.location.search);
|
|
386
|
-
// Check required params
|
|
387
|
-
const liveEditorParam = urlParams.get('contentstorage_live_editor');
|
|
388
|
-
const screenshotModeParam = urlParams.get('screenshot_mode');
|
|
389
|
-
const contentstorageKey = urlParams.get('contentstorage_key');
|
|
390
|
-
// All three must be present and valid
|
|
391
|
-
if (liveEditorParam !== 'true')
|
|
392
|
-
return null;
|
|
393
|
-
if (screenshotModeParam !== 'true')
|
|
394
|
-
return null;
|
|
395
|
-
const decodedKey = decodeContentstorageKey(contentstorageKey);
|
|
396
|
-
if (!decodedKey)
|
|
397
|
-
return null;
|
|
398
|
-
return {
|
|
399
|
-
contentstorageKey: decodedKey,
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
catch {
|
|
403
|
-
return null;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Removes screenshot-related params from URL without page reload
|
|
408
|
-
* Uses History API to update URL bar
|
|
409
|
-
*/
|
|
410
|
-
function cleanScreenshotUrlParams() {
|
|
411
|
-
if (!isBrowser())
|
|
412
|
-
return;
|
|
413
|
-
const win = getContentstorageWindow();
|
|
414
|
-
if (!win)
|
|
415
|
-
return;
|
|
416
|
-
try {
|
|
417
|
-
const url = new URL(win.location.href);
|
|
418
|
-
const paramsToRemove = [
|
|
419
|
-
'contentstorage_live_editor',
|
|
420
|
-
'screenshot_mode',
|
|
421
|
-
'contentstorage_key',
|
|
422
|
-
];
|
|
423
|
-
paramsToRemove.forEach((param) => {
|
|
424
|
-
url.searchParams.delete(param);
|
|
425
|
-
});
|
|
426
|
-
// Use replaceState to update URL without reload
|
|
427
|
-
win.history.replaceState({}, '', url.toString());
|
|
428
|
-
}
|
|
429
|
-
catch (e) {
|
|
430
|
-
console.warn('[Contentstorage] Failed to clean URL params:', e);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Exposes the API key on window for live-editor.js to use
|
|
435
|
-
* Uses a non-enumerable property for security
|
|
436
|
-
*
|
|
437
|
-
* @param key - The validated contentstorage API key
|
|
438
|
-
*/
|
|
439
|
-
function exposeApiKey(key) {
|
|
440
|
-
const win = getContentstorageWindow();
|
|
441
|
-
if (!win)
|
|
442
|
-
return;
|
|
443
|
-
// Store as non-enumerable property for security
|
|
444
|
-
Object.defineProperty(win, '__contentstorageApiKey', {
|
|
445
|
-
value: key,
|
|
446
|
-
writable: false,
|
|
447
|
-
enumerable: false,
|
|
448
|
-
configurable: true, // Allow cleanup later
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
/**
|
|
452
|
-
* Gets the exposed API key (if any)
|
|
453
|
-
*/
|
|
454
|
-
function getApiKey() {
|
|
455
|
-
const win = getContentstorageWindow();
|
|
456
|
-
return (win === null || win === void 0 ? void 0 : win.__contentstorageApiKey) || null;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
390
|
/**
|
|
460
391
|
* Contentstorage Live Editor Post-Processor
|
|
461
392
|
*
|
|
@@ -501,53 +432,23 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
501
432
|
? navigator.language.split('-')[0]
|
|
502
433
|
: 'en';
|
|
503
434
|
setCurrentLanguageCode(browserLanguage);
|
|
435
|
+
// Detect pip mode to pass to script loading
|
|
436
|
+
const isPipMode = detectPipMode();
|
|
437
|
+
const scriptMode = isPipMode ? 'pip' : undefined;
|
|
504
438
|
// Load the live editor script
|
|
505
|
-
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
439
|
+
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl, scriptMode);
|
|
506
440
|
if (this.options.debug) {
|
|
507
441
|
console.log('[Contentstorage] Post-processor initialized in live mode');
|
|
442
|
+
if (isPipMode) {
|
|
443
|
+
console.log('[Contentstorage] PiP mode detected');
|
|
444
|
+
}
|
|
508
445
|
console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);
|
|
509
446
|
}
|
|
510
447
|
}
|
|
511
|
-
// Check for screenshot mode (works without iframe)
|
|
512
|
-
this.initializeScreenshotMode();
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Initialize screenshot mode if URL params indicate it
|
|
516
|
-
* Works without iframe, unlike live editor mode
|
|
517
|
-
*/
|
|
518
|
-
initializeScreenshotMode() {
|
|
519
|
-
// Skip if already in live mode (already initialized)
|
|
520
|
-
if (this.isLiveMode)
|
|
521
|
-
return;
|
|
522
|
-
const screenshotConfig = detectScreenshotMode();
|
|
523
|
-
if (!screenshotConfig)
|
|
524
|
-
return;
|
|
525
|
-
if (this.options.debug) {
|
|
526
|
-
console.log('[Contentstorage] Screenshot mode detected');
|
|
527
|
-
}
|
|
528
|
-
// Initialize memory map for translation tracking
|
|
529
|
-
initializeMemoryMap();
|
|
530
|
-
// Initialize current language code
|
|
531
|
-
const browserLanguage = typeof navigator !== 'undefined' && navigator.language
|
|
532
|
-
? navigator.language.split('-')[0]
|
|
533
|
-
: 'en';
|
|
534
|
-
setCurrentLanguageCode(browserLanguage);
|
|
535
|
-
// Expose API key for live-editor.js to use
|
|
536
|
-
exposeApiKey(screenshotConfig.contentstorageKey);
|
|
537
|
-
// Clean URL params for security
|
|
538
|
-
cleanScreenshotUrlParams();
|
|
539
|
-
// Enable tracking (reuse existing flag so process() tracks translations)
|
|
540
|
-
this.isLiveMode = true;
|
|
541
|
-
// Load live-editor.js script
|
|
542
|
-
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
543
|
-
if (this.options.debug) {
|
|
544
|
-
console.log('[Contentstorage] Screenshot mode initialized');
|
|
545
|
-
console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);
|
|
546
|
-
}
|
|
547
448
|
}
|
|
548
449
|
/**
|
|
549
450
|
* Expose refresh function on window for live-editor.js to call
|
|
550
|
-
* Only exposed in live mode (live editor or
|
|
451
|
+
* Only exposed in live mode (live editor or pip mode)
|
|
551
452
|
*/
|
|
552
453
|
exposeRefreshFunction() {
|
|
553
454
|
if (!this.isLiveMode)
|
|
@@ -684,9 +585,6 @@ class ContentstorageBackend {
|
|
|
684
585
|
* Called by i18next during initialization
|
|
685
586
|
*/
|
|
686
587
|
init(services, backendOptions = {}, i18nextOptions = {}) {
|
|
687
|
-
// Store for use in initializeScreenshotMode
|
|
688
|
-
this.services = services;
|
|
689
|
-
this.i18nextOptions = i18nextOptions;
|
|
690
588
|
this.options = {
|
|
691
589
|
debug: false,
|
|
692
590
|
maxMemoryMapSize: 10000,
|
|
@@ -699,8 +597,11 @@ class ContentstorageBackend {
|
|
|
699
597
|
if (this.isLiveMode) {
|
|
700
598
|
// Initialize memory map
|
|
701
599
|
initializeMemoryMap();
|
|
600
|
+
// Detect pip mode to pass to script loading
|
|
601
|
+
const isPipMode = detectPipMode();
|
|
602
|
+
const scriptMode = isPipMode ? 'pip' : undefined;
|
|
702
603
|
// Load the live editor script
|
|
703
|
-
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {
|
|
604
|
+
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl, scriptMode).then((loaded) => {
|
|
704
605
|
if (loaded) {
|
|
705
606
|
if (this.options.debug) {
|
|
706
607
|
console.log('[Contentstorage] Live editor ready');
|
|
@@ -714,6 +615,9 @@ class ContentstorageBackend {
|
|
|
714
615
|
this.registerPostProcessor(services, i18nextOptions);
|
|
715
616
|
if (this.options.debug) {
|
|
716
617
|
console.log('[Contentstorage] Live editor mode enabled');
|
|
618
|
+
if (isPipMode) {
|
|
619
|
+
console.log('[Contentstorage] PiP mode detected');
|
|
620
|
+
}
|
|
717
621
|
console.log('[Contentstorage] Post-processor auto-registered');
|
|
718
622
|
console.log('[Contentstorage] Plugin initialized with options:', this.options);
|
|
719
623
|
}
|
|
@@ -721,35 +625,6 @@ class ContentstorageBackend {
|
|
|
721
625
|
else if (this.options.debug) {
|
|
722
626
|
console.log('[Contentstorage] Running in normal mode (not live editor)');
|
|
723
627
|
}
|
|
724
|
-
// Check for screenshot mode (works in local dev without iframe)
|
|
725
|
-
this.initializeScreenshotMode();
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Initialize screenshot mode if URL params indicate it
|
|
729
|
-
* Exposes the API key for live-editor.js to use
|
|
730
|
-
*/
|
|
731
|
-
initializeScreenshotMode() {
|
|
732
|
-
const screenshotConfig = detectScreenshotMode();
|
|
733
|
-
if (!screenshotConfig)
|
|
734
|
-
return;
|
|
735
|
-
if (this.options.debug) {
|
|
736
|
-
console.log('[Contentstorage] Screenshot mode detected');
|
|
737
|
-
}
|
|
738
|
-
// Initialize memory map for translation tracking
|
|
739
|
-
initializeMemoryMap();
|
|
740
|
-
// Expose API key for live-editor.js to use
|
|
741
|
-
exposeApiKey(screenshotConfig.contentstorageKey);
|
|
742
|
-
// Clean URL params for security
|
|
743
|
-
cleanScreenshotUrlParams();
|
|
744
|
-
// Register post-processor for translation tracking
|
|
745
|
-
if (this.services && this.i18nextOptions) {
|
|
746
|
-
this.registerPostProcessor(this.services, this.i18nextOptions);
|
|
747
|
-
}
|
|
748
|
-
// Load live-editor.js script (handles screenshot UI)
|
|
749
|
-
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
750
|
-
if (this.options.debug) {
|
|
751
|
-
console.log('[Contentstorage] Screenshot mode initialized: memory map, post-processor, API key exposed');
|
|
752
|
-
}
|
|
753
628
|
}
|
|
754
629
|
/**
|
|
755
630
|
* Auto-register the live editor post-processor
|
|
@@ -902,15 +777,10 @@ function createContentstorageBackend(options) {
|
|
|
902
777
|
|
|
903
778
|
exports.ContentstorageBackend = ContentstorageBackend;
|
|
904
779
|
exports.ContentstorageLiveEditorPostProcessor = ContentstorageLiveEditorPostProcessor;
|
|
905
|
-
exports.cleanScreenshotUrlParams = cleanScreenshotUrlParams;
|
|
906
780
|
exports.createContentstorageBackend = createContentstorageBackend;
|
|
907
781
|
exports.createContentstorageLiveEditorPostProcessor = createContentstorageLiveEditorPostProcessor;
|
|
908
782
|
exports.debugMemoryMap = debugMemoryMap;
|
|
909
|
-
exports.decodeContentstorageKey = decodeContentstorageKey;
|
|
910
783
|
exports.default = ContentstorageBackend;
|
|
911
|
-
exports.detectScreenshotMode = detectScreenshotMode;
|
|
912
|
-
exports.exposeApiKey = exposeApiKey;
|
|
913
|
-
exports.getApiKey = getApiKey;
|
|
914
784
|
exports.getCurrentLanguageCode = getCurrentLanguageCode;
|
|
915
785
|
exports.loadLiveEditorScript = loadLiveEditorScript;
|
|
916
786
|
exports.setCurrentLanguageCode = setCurrentLanguageCode;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/utils.ts","../src/screenshot.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[Contentstorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[Contentstorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[Contentstorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[Contentstorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Clears all entries from the memory map\n * Used by live editor to refresh tracking\n */\nexport function clearMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (memoryMap) {\n memoryMap.clear();\n }\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[Contentstorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[Contentstorage] Memory map not initialized');\n return;\n }\n\n console.log('[Contentstorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import { isBrowser, getContentstorageWindow } from './utils';\n\n/**\n * Decodes and validates the contentstorage key\n * Just decodes URL encoding and checks non-empty (backend validates format)\n *\n * @param key - The raw key from URL params\n * @returns Decoded key if valid, null if empty/invalid\n */\nexport function decodeContentstorageKey(key: string | null): string | null {\n if (!key) return null;\n\n try {\n const decoded = decodeURIComponent(key);\n return decoded.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Detects if screenshot mode should be activated\n * Requires: contentstorage_live_editor=true AND screenshot_mode=true AND valid contentstorage_key\n *\n * NOTE: Unlike live editor mode, screenshot mode does NOT require iframe\n *\n * @returns Object with contentstorageKey if active, null otherwise\n */\nexport function detectScreenshotMode(): { contentstorageKey: string } | null {\n if (!isBrowser()) return null;\n\n const win = getContentstorageWindow();\n if (!win) return null;\n\n try {\n const urlParams = new URLSearchParams(win.location.search);\n\n // Check required params\n const liveEditorParam = urlParams.get('contentstorage_live_editor');\n const screenshotModeParam = urlParams.get('screenshot_mode');\n const contentstorageKey = urlParams.get('contentstorage_key');\n\n // All three must be present and valid\n if (liveEditorParam !== 'true') return null;\n if (screenshotModeParam !== 'true') return null;\n\n const decodedKey = decodeContentstorageKey(contentstorageKey);\n if (!decodedKey) return null;\n\n return {\n contentstorageKey: decodedKey,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Removes screenshot-related params from URL without page reload\n * Uses History API to update URL bar\n */\nexport function cleanScreenshotUrlParams(): void {\n if (!isBrowser()) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n try {\n const url = new URL(win.location.href);\n const paramsToRemove = [\n 'contentstorage_live_editor',\n 'screenshot_mode',\n 'contentstorage_key',\n ];\n\n paramsToRemove.forEach((param) => {\n url.searchParams.delete(param);\n });\n\n // Use replaceState to update URL without reload\n win.history.replaceState({}, '', url.toString());\n } catch (e) {\n console.warn('[Contentstorage] Failed to clean URL params:', e);\n }\n}\n\n/**\n * Exposes the API key on window for live-editor.js to use\n * Uses a non-enumerable property for security\n *\n * @param key - The validated contentstorage API key\n */\nexport function exposeApiKey(key: string): void {\n const win = getContentstorageWindow();\n if (!win) return;\n\n // Store as non-enumerable property for security\n Object.defineProperty(win, '__contentstorageApiKey', {\n value: key,\n writable: false,\n enumerable: false,\n configurable: true, // Allow cleanup later\n });\n}\n\n/**\n * Gets the exposed API key (if any)\n */\nexport function getApiKey(): string | null {\n const win = getContentstorageWindow();\n return win?.__contentstorageApiKey || null;\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode, clearMemoryMap, getContentstorageWindow } from './utils';\nimport { detectScreenshotMode, cleanScreenshotUrlParams, exposeApiKey } from './screenshot';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private i18nextInstance: any = null;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Post-processor initialized in live mode');\n console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n // Check for screenshot mode (works without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Works without iframe, unlike live editor mode\n */\n private initializeScreenshotMode(): void {\n // Skip if already in live mode (already initialized)\n if (this.isLiveMode) return;\n\n const screenshotConfig = detectScreenshotMode();\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Initialize current language code\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Enable tracking (reuse existing flag so process() tracks translations)\n this.isLiveMode = true;\n\n // Load live-editor.js script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode initialized');\n console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n /**\n * Expose refresh function on window for live-editor.js to call\n * Only exposed in live mode (live editor or screenshot mode)\n */\n private exposeRefreshFunction(): void {\n if (!this.isLiveMode) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n win.__contentstorageRefresh = () => {\n // Clear memoryMap\n clearMemoryMap();\n\n // Trigger re-render by emitting languageChanged event\n // This causes useTranslation hooks to re-render\n if (this.i18nextInstance?.emit) {\n this.i18nextInstance.emit('languageChanged', this.i18nextInstance.language);\n }\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh triggered: memoryMap cleared, languageChanged emitted');\n }\n };\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh function exposed on window.__contentstorageRefresh');\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Store i18next reference on first call and expose refresh function\n if (!this.i18nextInstance && translator) {\n this.i18nextInstance = translator;\n this.exposeRefreshFunction();\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport {\n detectScreenshotMode,\n cleanScreenshotUrlParams,\n exposeApiKey,\n} from './screenshot';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n private services?: Services;\n private i18nextOptions?: InitOptions;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n // Store for use in initializeScreenshotMode\n this.services = services;\n this.i18nextOptions = i18nextOptions;\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor ready');\n }\n } else {\n console.warn('[Contentstorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor mode enabled');\n console.log('[Contentstorage] Post-processor auto-registered');\n console.log('[Contentstorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[Contentstorage] Running in normal mode (not live editor)');\n }\n\n // Check for screenshot mode (works in local dev without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Exposes the API key for live-editor.js to use\n */\n private initializeScreenshotMode(): void {\n const screenshotConfig = detectScreenshotMode();\n\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Register post-processor for translation tracking\n if (this.services && this.i18nextOptions) {\n this.registerPostProcessor(this.services, this.i18nextOptions);\n }\n\n // Load live-editor.js script (handles screenshot UI)\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode initialized: memory map, post-processor, API key exposed');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[Contentstorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[Contentstorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[Contentstorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[Contentstorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[Contentstorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[Contentstorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":";;;;AAEA;;AAEG;SACa,SAAS,GAAA;IACvB,OAAO,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW;AACzE;AAEA;;AAEG;SACa,uBAAuB,GAAA;IACrC,IAAI,CAAC,SAAS,EAAE;AAAE,QAAA,OAAO,IAAI;AAC7B,IAAA,OAAO,MAA8B;AACvC;AAEA;;;;;;AAMG;SACa,oBAAoB,CAClC,kBAA0B,4BAA4B,EACtD,gBAAyB,KAAK,EAAA;AAE9B,IAAA,IAAI,aAAa;AAAE,QAAA,OAAO,IAAI;IAC9B,IAAI,CAAC,SAAS,EAAE;AAAE,QAAA,OAAO,KAAK;AAE9B,IAAA,IAAI;AACF,QAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;AACrC,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,KAAK;;QAGtB,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG;;QAGrC,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1D,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;AAEhD,QAAA,OAAO,CAAC,EAAE,QAAQ,IAAI,SAAS,CAAC;IAClC;IAAE,OAAO,CAAC,EAAE;;;AAGV,QAAA,OAAO,KAAK;IACd;AACF;AAEA;;AAEG;SACa,mBAAmB,GAAA;AACjC,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;AACrC,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,IAAI;AAErB,IAAA,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE;AAClB,QAAA,GAAG,CAAC,SAAS,GAAG,IAAI,GAAG,EAA0B;IACnD;IAEA,OAAO,GAAG,CAAC,SAAS;AACtB;AAEA;;;AAGG;AACH,IAAI,sBAAsB,GAA4B,IAAI;AAEpD,SAAU,oBAAoB,CAClC,OAAA,GAAkB,CAAC,EACnB,KAAA,GAAgB,IAAI,EACpB,KAAA,GAAiB,KAAK,EACtB,eAAwB,EAAA;;IAGxB,IAAI,sBAAsB,EAAE;AAC1B,QAAA,OAAO,sBAAsB;IAC/B;AAEA,IAAA,sBAAsB,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,KAAI;AACxD,QAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;QACrC,IAAI,CAAC,GAAG,EAAE;YACR,OAAO,CAAC,KAAK,CAAC;YACd;QACF;AAEA,QAAA,MAAM,YAAY,GAAG,eAAe,IAAI,+EAA+E;AAEvH,QAAA,MAAM,UAAU,GAAG,CAAC,OAAA,GAAkB,CAAC,KAAI;YACzC,IAAI,KAAK,EAAE;gBACT,OAAO,CAAC,GAAG,CAAC,CAAA,gEAAA,EAAmE,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAG,CAAC;YACvG;YAEA,MAAM,aAAa,GAAG,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;AAC1D,YAAA,aAAa,CAAC,IAAI,GAAG,iBAAiB;AACtC,YAAA,aAAa,CAAC,GAAG,GAAG,YAAY;AAEhC,YAAA,aAAa,CAAC,MAAM,GAAG,MAAK;gBAC1B,IAAI,KAAK,EAAE;AACT,oBAAA,OAAO,CAAC,GAAG,CAAC,CAAA,uDAAA,CAAyD,CAAC;gBACxE;gBACA,OAAO,CAAC,IAAI,CAAC;AACf,YAAA,CAAC;AAED,YAAA,aAAa,CAAC,OAAO,GAAG,CAAC,KAAK,KAAI;;gBAEhC,aAAa,CAAC,MAAM,EAAE;gBAEtB,IAAI,KAAK,EAAE;oBACT,OAAO,CAAC,KAAK,CAAC,CAAA,4DAAA,EAA+D,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAG,EAAE,KAAK,CAAC;gBAC5G;AAEA,gBAAA,IAAI,OAAO,GAAG,OAAO,EAAE;AACrB,oBAAA,UAAU,CAAC,MAAM,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC;gBAClD;qBAAO;AACL,oBAAA,OAAO,CAAC,KAAK,CAAC,wBAAwB,OAAO,CAAA,2CAAA,CAA6C,CAAC;oBAC3F,OAAO,CAAC,KAAK,CAAC;gBAChB;AACF,YAAA,CAAC;YAED,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;AAC9C,QAAA,CAAC;AAED,QAAA,UAAU,EAAE;AACd,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,sBAAsB;AAC/B;AAEA;;AAEG;SACa,YAAY,GAAA;AAC1B,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;IACrC,OAAO,CAAA,GAAG,KAAA,IAAA,IAAH,GAAG,KAAA,MAAA,GAAA,MAAA,GAAH,GAAG,CAAE,SAAS,KAAI,IAAI;AAC/B;AAEA;;;AAGG;SACa,cAAc,GAAA;AAC5B,IAAA,MAAM,SAAS,GAAG,YAAY,EAAE;IAChC,IAAI,SAAS,EAAE;QACb,SAAS,CAAC,KAAK,EAAE;IACnB;AACF;AAEA;;;;;AAKG;AACG,SAAU,sBAAsB,CAAC,YAAoB,EAAA;AACzD,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;IACrC,IAAI,GAAG,EAAE;AACP,QAAA,GAAG,CAAC,mBAAmB,GAAG,YAAY;IACxC;AACF;AAEA;;;;AAIG;SACa,sBAAsB,GAAA;AACpC,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;IACrC,OAAO,CAAA,GAAG,KAAA,IAAA,IAAH,GAAG,KAAA,MAAA,GAAA,MAAA,GAAH,GAAG,CAAE,mBAAmB,KAAI,IAAI;AACzC;AAEA;;;;;;;;AAQG;AACG,SAAU,YAAY,CAAC,GAAW,EAAE,SAAkB,EAAA;IAI1D,IAAI,aAAa,GAAG,GAAG;;AAGvB,IAAA,IAAI,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QAC/B,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;IACjD;;;AAKA,IAAA,OAAO,aAAa;AACtB;AAiDA;;;AAGG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,cAAc;IACd,SAAS;IACT,KAAK;IACL,MAAM;IACN,aAAa;IACb,IAAI;IACJ,cAAc;IACd,aAAa;IACb,eAAe;IACf,eAAe;IACf,uBAAuB;IACvB,YAAY;IACZ,aAAa;IACb,eAAe;IACf,mBAAmB;IACnB,6BAA6B;IAC7B,mBAAmB;IACnB,wBAAwB;IACxB,kCAAkC;IAClC,aAAa;IACb,eAAe;IACf,gCAAgC;IAChC,6BAA6B;IAC7B,iBAAiB;IACjB,qBAAqB;AACtB,CAAA,CAAC;AAEF;;;;;;AAMG;AACG,SAAU,oBAAoB,CAAC,OAAa,EAAA;IAChD,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;AAC3C,QAAA,OAAO,SAAS;IAClB;IAEA,MAAM,SAAS,GAAwB,EAAE;IACzC,IAAI,YAAY,GAAG,KAAK;AAExB,IAAA,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC;YAAE;;AAGzD,QAAA,IAAI,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE;;AAGpC,QAAA,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE;;AAGzB,QAAA,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE;;QAGhC,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;QAC7B,YAAY,GAAG,IAAI;IACrB;IAEA,OAAO,YAAY,GAAG,SAAS,GAAG,SAAS;AAC7C;AAEA;;;;;;;;;AASG;AACG,SAAU,gBAAgB,CAC9B,gBAAwB,EACxB,cAAsB,EACtB,SAAkB,EAClB,QAAiB,EACjB,KAAA,GAAiB,KAAK,EACtB,SAA+B,EAAA;AAE/B,IAAA,MAAM,SAAS,GAAG,YAAY,EAAE;AAChC,IAAA,IAAI,CAAC,SAAS;QAAE;;IAGhB,MAAM,aAAa,GAAG,YAAY,CAAC,cAAyB,CAAC;;IAG7D,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC;AACrD,IAAA,MAAM,KAAK,GAAG,aAAa,GAAG,aAAa,CAAC,GAAG,GAAG,IAAI,GAAG,EAAU;AACnE,IAAA,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;;;AAIxB,IAAA,MAAM,eAAe,GAAG,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG;AACnE,UAAE;UACA,aAAa,KAAA,IAAA,IAAb,aAAa,uBAAb,aAAa,CAAE,SAAS;AAE5B,IAAA,MAAM,KAAK,GAAmB;AAC5B,QAAA,GAAG,EAAE,KAAK;AACV,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;AACjG,QAAA,QAAQ,EAAE;YACR,SAAS;YACT,QAAQ;AACR,YAAA,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;AACtB,SAAA;KACF;AAED,IAAA,SAAS,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC;IAEtC,IAAI,KAAK,EAAE;AACT,QAAA,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE;AACnD,YAAA,KAAK,EAAE,gBAAgB;AACvB,YAAA,GAAG,EAAE,aAAa;YAClB,SAAS;YACT,QAAQ;YACR,SAAS;AACV,SAAA,CAAC;IACJ;AACF;AAEA;;;;;AAKG;AACG,SAAU,gBAAgB,CAAC,OAAe,EAAA;AAC9C,IAAA,MAAM,SAAS,GAAG,YAAY,EAAE;AAChC,IAAA,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO;QAAE;;IAG7C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;;AAAC,QAAA,QAAC;YACrE,GAAG;YACH,KAAK;YACL,SAAS,EAAE,CAAA,CAAA,EAAA,GAAA,KAAK,CAAC,QAAQ,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,SAAS,KAAI,CAAC;AAC1C,SAAA;AAAC,IAAA,CAAA,CAAC;;AAGH,IAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;;AAGjD,IAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,GAAG,OAAO;;AAGzC,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE;QACjC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClC;AACF;AAEA;;;;;;AAMG;SACa,mBAAmB,CACjC,GAAQ,EACR,SAAiB,EAAE,EAAA;IAEnB,MAAM,OAAO,GAA4B,EAAE;AAE3C,IAAA,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE;AACrB,QAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC;YAAE;AAErD,QAAA,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;AACtB,QAAA,MAAM,OAAO,GAAG,MAAM,GAAG,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,GAAG,GAAG;AAEjD,QAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChC;AAAO,aAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;;YAE/E,OAAO,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtD;IACF;AAEA,IAAA,OAAO,OAAO;AAChB;AAEA;;AAEG;SACa,cAAc,GAAA;AAC5B,IAAA,MAAM,SAAS,GAAG,YAAY,EAAE;IAChC,IAAI,CAAC,SAAS,EAAE;AACd,QAAA,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC;QAC1D;IACF;AAEA,IAAA,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,CAAA,eAAA,EAAkB,SAAS,CAAC,IAAI,CAAA,CAAE,CAAC;AAE/C,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;AAC5D,IAAA,OAAO,CAAC,KAAK,CACX,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,KAAI;;AAAC,QAAA,QAAC;YAC/B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;AAC7B,YAAA,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACtC,SAAS,EAAE,CAAA,CAAA,EAAA,GAAA,KAAK,CAAC,QAAQ,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,SAAS,KAAI,KAAK;AAC9C,SAAA;AAAC,IAAA,CAAA,CAAC,CACJ;AAED,IAAA,IAAI,SAAS,CAAC,IAAI,GAAG,EAAE,EAAE;QACvB,OAAO,CAAC,GAAG,CAAC,CAAA,QAAA,EAAW,SAAS,CAAC,IAAI,GAAG,EAAE,CAAA,aAAA,CAAe,CAAC;IAC5D;AACF;;ACtcA;;;;;;AAMG;AACG,SAAU,uBAAuB,CAAC,GAAkB,EAAA;AACxD,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,IAAI;AAErB,IAAA,IAAI;AACF,QAAA,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC;AACvC,QAAA,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,IAAI;IAC/B;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;;;;;;;AAOG;SACa,oBAAoB,GAAA;IAClC,IAAI,CAAC,SAAS,EAAE;AAAE,QAAA,OAAO,IAAI;AAE7B,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;AACrC,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,IAAI;AAErB,IAAA,IAAI;QACF,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;;QAG1D,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,4BAA4B,CAAC;QACnE,MAAM,mBAAmB,GAAG,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC5D,MAAM,iBAAiB,GAAG,SAAS,CAAC,GAAG,CAAC,oBAAoB,CAAC;;QAG7D,IAAI,eAAe,KAAK,MAAM;AAAE,YAAA,OAAO,IAAI;QAC3C,IAAI,mBAAmB,KAAK,MAAM;AAAE,YAAA,OAAO,IAAI;AAE/C,QAAA,MAAM,UAAU,GAAG,uBAAuB,CAAC,iBAAiB,CAAC;AAC7D,QAAA,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,IAAI;QAE5B,OAAO;AACL,YAAA,iBAAiB,EAAE,UAAU;SAC9B;IACH;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;;;AAGG;SACa,wBAAwB,GAAA;IACtC,IAAI,CAAC,SAAS,EAAE;QAAE;AAElB,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;AACrC,IAAA,IAAI,CAAC,GAAG;QAAE;AAEV,IAAA,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtC,QAAA,MAAM,cAAc,GAAG;YACrB,4BAA4B;YAC5B,iBAAiB;YACjB,oBAAoB;SACrB;AAED,QAAA,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AAC/B,YAAA,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;AAChC,QAAA,CAAC,CAAC;;AAGF,QAAA,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;IAClD;IAAE,OAAO,CAAC,EAAE;AACV,QAAA,OAAO,CAAC,IAAI,CAAC,8CAA8C,EAAE,CAAC,CAAC;IACjE;AACF;AAEA;;;;;AAKG;AACG,SAAU,YAAY,CAAC,GAAW,EAAA;AACtC,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;AACrC,IAAA,IAAI,CAAC,GAAG;QAAE;;AAGV,IAAA,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE;AACnD,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,IAAI;AACnB,KAAA,CAAC;AACJ;AAEA;;AAEG;SACa,SAAS,GAAA;AACvB,IAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;IACrC,OAAO,CAAA,GAAG,KAAA,IAAA,IAAH,GAAG,KAAA,MAAA,GAAA,MAAA,GAAH,GAAG,CAAE,sBAAsB,KAAI,IAAI;AAC5C;;AC1GA;;;;;;;;;;;;;;;;;;;;;;AAsBG;MACU,qCAAqC,CAAA;AAShD,IAAA,WAAA,CAAY,UAAuC,EAAE,EAAA;QAPrD,IAAA,CAAA,IAAI,GAAoB,eAAe;QACvC,IAAA,CAAA,IAAI,GAAW,gBAAgB;QAGvB,IAAA,CAAA,UAAU,GAAY,KAAK;QAC3B,IAAA,CAAA,eAAe,GAAQ,IAAI;QAGjC,IAAI,CAAC,OAAO,GAAG;AACb,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,eAAe,EAAE,4BAA4B;AAC7C,YAAA,aAAa,EAAE,KAAK;AACpB,YAAA,GAAG,OAAO;SACX;;AAGD,QAAA,IAAI,CAAC,UAAU,GAAG,oBAAoB,CACpC,IAAI,CAAC,OAAO,CAAC,eAAe,EAC5B,IAAI,CAAC,OAAO,CAAC,aAAa,CAC3B;AAED,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE;AACnB,YAAA,mBAAmB,EAAE;;;YAIrB,MAAM,eAAe,GAAG,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC;kBAClE,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;kBAC/B,IAAI;YACR,sBAAsB,CAAC,eAAe,CAAC;;AAGvC,YAAA,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC;AAEzF,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,gBAAA,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC;AACvE,gBAAA,OAAO,CAAC,GAAG,CAAC,kDAAkD,eAAe,CAAA,CAAE,CAAC;YAClF;QACF;;QAGA,IAAI,CAAC,wBAAwB,EAAE;IACjC;AAEA;;;AAGG;IACK,wBAAwB,GAAA;;QAE9B,IAAI,IAAI,CAAC,UAAU;YAAE;AAErB,QAAA,MAAM,gBAAgB,GAAG,oBAAoB,EAAE;AAC/C,QAAA,IAAI,CAAC,gBAAgB;YAAE;AAEvB,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,YAAA,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC;QAC1D;;AAGA,QAAA,mBAAmB,EAAE;;QAGrB,MAAM,eAAe,GAAG,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC;cAClE,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;cAC/B,IAAI;QACR,sBAAsB,CAAC,eAAe,CAAC;;AAGvC,QAAA,YAAY,CAAC,gBAAgB,CAAC,iBAAiB,CAAC;;AAGhD,QAAA,wBAAwB,EAAE;;AAG1B,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;;AAGtB,QAAA,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC;AAEzF,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,YAAA,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC;AAC3D,YAAA,OAAO,CAAC,GAAG,CAAC,kDAAkD,eAAe,CAAA,CAAE,CAAC;QAClF;IACF;AAEA;;;AAGG;IACK,qBAAqB,GAAA;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE;AAEtB,QAAA,MAAM,GAAG,GAAG,uBAAuB,EAAE;AACrC,QAAA,IAAI,CAAC,GAAG;YAAE;AAEV,QAAA,GAAG,CAAC,uBAAuB,GAAG,MAAK;;;AAEjC,YAAA,cAAc,EAAE;;;AAIhB,YAAA,IAAI,MAAA,IAAI,CAAC,eAAe,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,IAAI,EAAE;AAC9B,gBAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;YAC7E;AAEA,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,gBAAA,OAAO,CAAC,GAAG,CAAC,gFAAgF,CAAC;YAC/F;AACF,QAAA,CAAC;AAED,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,YAAA,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC;QAC5F;IACF;AAEA;;;AAGG;AACH,IAAA,OAAO,CACL,KAAa,EACb,GAAsB,EACtB,OAAY,EACZ,UAAe,EAAA;;;AAGf,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;AACpB,YAAA,OAAO,KAAK;QACd;;AAGA,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,UAAU,EAAE;AACvC,YAAA,IAAI,CAAC,eAAe,GAAG,UAAU;YACjC,IAAI,CAAC,qBAAqB,EAAE;QAC9B;;AAGA,QAAA,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG;;;AAIxD,QAAA,IAAI,SAA6B;AACjC,QAAA,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YAChC,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;QACzC;AACA,QAAA,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE;YACtC,OAAO;YACP;AACD,SAAA,CAAC;;AAEF,QAAA,MAAM,QAAQ,GAAG,CAAA,OAAO,KAAA,IAAA,IAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,MAAI,UAAU,aAAV,UAAU,KAAA,MAAA,GAAA,MAAA,GAAV,UAAU,CAAE,QAAQ,CAAA;;QAGrD,IAAI,QAAQ,EAAE;YACZ,sBAAsB,CAAC,QAAQ,CAAC;QAClC;;AAGA,QAAA,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC;;;QAI/C,IAAI,QAAQ,GAAG,KAAK;AACpB,QAAA,IAAI;YACF,IAAI,UAAU,aAAV,UAAU,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAV,UAAU,CAAE,aAAa,EAAE;gBAC7B,MAAM,EAAE,GAAG,SAAS,KAAI,OAAO,KAAA,IAAA,IAAP,OAAO,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAP,OAAO,CAAE,EAAE,CAAA,KAAI,CAAA,EAAA,GAAA,UAAU,CAAC,OAAO,0CAAE,SAAS,CAAA,IAAI,aAAa;AACrF,gBAAA,MAAM,GAAG,GAAG,QAAQ,IAAI,UAAU,CAAC,QAAQ;;AAG3C,gBAAA,MAAM,cAAc,GAAG,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,EAAE,cAAc,CAAC;AACpF,gBAAA,IAAI,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE;oBACxD,QAAQ,GAAG,cAAc;gBAC3B;YACF;QACF;QAAE,OAAO,CAAC,EAAE;;AAEV,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;gBACtB,OAAO,CAAC,IAAI,CAAC,0DAA0D,EAAE,cAAc,EAAE,CAAC,CAAC;YAC7F;QACF;;AAGA,QAAA,gBAAgB,CACd,QAAQ,EACR,cAAc,EACd,SAAS,EACT,QAAQ,EACR,IAAI,CAAC,OAAO,CAAC,KAAK,EAClB,SAAS,CACV;AAED,QAAA,OAAO,KAAK;IACd;;AAlMO,qCAAA,CAAA,IAAI,GAAoB,eAApB;AAqMb;;AAEG;AACG,SAAU,2CAA2C,CACzD,OAAqC,EAAA;AAErC,IAAA,OAAO,IAAI,qCAAqC,CAAC,OAAO,CAAC;AAC3D;;AC/MA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;MACU,qBAAqB,CAAA;AAUhC,IAAA,WAAA,CAAY,SAAoB,EAAE,OAAqC,EAAE,eAA6B,EAAA;QARtG,IAAA,CAAA,IAAI,GAAc,SAAS;QAGnB,IAAA,CAAA,UAAU,GAAY,KAAK;AAMjC,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE;;;AAI5B,QAAA,IAAI,SAAS,IAAI,eAAe,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC;QAChD;IACF;AAEA;;;AAGG;AACH,IAAA,IAAI,CACF,QAAkB,EAClB,iBAA8C,EAAE,EAChD,iBAA8B,EAAE,EAAA;;AAGhC,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;AACxB,QAAA,IAAI,CAAC,cAAc,GAAG,cAAc;QAEpC,IAAI,CAAC,OAAO,GAAG;AACb,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,gBAAgB,EAAE,KAAK;AACvB,YAAA,eAAe,EAAE,4BAA4B;AAC7C,YAAA,aAAa,EAAE,KAAK;AACpB,YAAA,GAAG,cAAc;SAClB;;AAGD,QAAA,IAAI,CAAC,UAAU,GAAG,oBAAoB,CACpC,IAAI,CAAC,OAAO,CAAC,eAAe,EAC5B,IAAI,CAAC,OAAO,CAAC,aAAa,CAC3B;AAED,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE;;AAEnB,YAAA,mBAAmB,EAAE;;YAGrB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAI;gBACxG,IAAI,MAAM,EAAE;AACV,oBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,wBAAA,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC;oBACnD;gBACF;qBAAO;AACL,oBAAA,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC;gBACpE;AACF,YAAA,CAAC,CAAC;;AAGF,YAAA,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,cAAc,CAAC;AAEpD,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,gBAAA,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC;AACxD,gBAAA,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC;gBAC9D,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,IAAI,CAAC,OAAO,CAAC;YAChF;QACF;AAAO,aAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AAC7B,YAAA,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC;QAC1E;;QAGA,IAAI,CAAC,wBAAwB,EAAE;IACjC;AAEA;;;AAGG;IACK,wBAAwB,GAAA;AAC9B,QAAA,MAAM,gBAAgB,GAAG,oBAAoB,EAAE;AAE/C,QAAA,IAAI,CAAC,gBAAgB;YAAE;AAEvB,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,YAAA,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC;QAC1D;;AAGA,QAAA,mBAAmB,EAAE;;AAGrB,QAAA,YAAY,CAAC,gBAAgB,CAAC,iBAAiB,CAAC;;AAGhD,QAAA,wBAAwB,EAAE;;QAG1B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,EAAE;YACxC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC;QAChE;;AAGA,QAAA,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC;AAEzF,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,YAAA,OAAO,CAAC,GAAG,CAAC,2FAA2F,CAAC;QAC1G;IACF;AAEA;;;AAGG;IACK,qBAAqB,CAAC,QAAkB,EAAE,cAA2B,EAAA;;;QAE3E,IAAI,CAAC,aAAa,GAAG,IAAI,qCAAqC,CAAC,IAAI,CAAC,OAAO,CAAC;;QAG5E,CAAA,EAAA,GAAA,QAAQ,CAAC,aAAa,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC;;QAG5D,MAAM,WAAW,GAAG,cAAqB;AACzC,QAAA,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE;AAC5B,YAAA,WAAW,CAAC,WAAW,GAAG,EAAE;QAC9B;;QAGA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE;YAC3C,WAAW,CAAC,WAAW,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC;QACrD;;QAGA,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;AACvD,YAAA,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC;QAChD;IACF;AAEA;;;AAGG;AACH,IAAA,IAAI,CACF,QAAgB,EAChB,SAAiB,EACjB,QAAsB,EAAA;AAEtB,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;YACtB,OAAO,CAAC,GAAG,CAAC,CAAA,uCAAA,EAA0C,QAAQ,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE,CAAC;QAChF;AAEA,QAAA,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,SAAS;AACtC,aAAA,IAAI,CAAC,CAAC,YAAY,KAAI;;YAErB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAAE;gBAC3D,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;;AAGzD,gBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;AACjC,oBAAA,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;gBACjD;YACF;AAEA,YAAA,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;AAC9B,QAAA,CAAC;AACA,aAAA,KAAK,CAAC,CAAC,KAAK,KAAI;AACf,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,gBAAA,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC;YACvE;AACA,YAAA,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;AACxB,QAAA,CAAC,CAAC;IACN;AAEA;;AAEG;AACK,IAAA,MAAM,gBAAgB,CAC5B,QAAgB,EAChB,SAAiB,EAAA;QAEjB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC;AAEjD,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,YAAA,OAAO,CAAC,GAAG,CAAC,mCAAmC,GAAG,CAAA,CAAE,CAAC;QACvD;AAEA,QAAA,IAAI;AACF,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AACpE,YAAA,OAAO,MAAM,OAAO,CAAC,GAAG,EAAE;AACxB,gBAAA,MAAM,EAAE,KAAK;AACb,gBAAA,OAAO,EAAE;AACP,oBAAA,QAAQ,EAAE,kBAAkB;AAC7B,iBAAA;AACF,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,gBAAA,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC;YACvD;AACA,YAAA,MAAM,KAAK;QACb;IACF;AAEA;;AAEG;AACK,IAAA,MAAM,YAAY,CAAC,GAAW,EAAE,OAAoB,EAAA;QAC1D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC;AAE1C,QAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;AAChB,YAAA,MAAM,IAAI,KAAK,CACb,CAAA,6BAAA,EAAgC,QAAQ,CAAC,MAAM,CAAA,CAAA,EAAI,QAAQ,CAAC,UAAU,CAAA,CAAE,CACzE;QACH;AAEA,QAAA,OAAO,QAAQ,CAAC,IAAI,EAAE;IACxB;AAEA;;AAEG;IACK,WAAW,CAAC,QAAgB,EAAE,SAAiB,EAAA;QACrD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO;;AAG7C,QAAA,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;AAClC,YAAA,OAAO,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;QACtC;;AAGA,QAAA,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;AAChC,YAAA,OAAO;AACJ,iBAAA,OAAO,CAAC,SAAS,EAAE,QAAQ;AAC3B,iBAAA,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC;QACjC;;QAGA,IAAI,CAAC,UAAU,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CACb,qEAAqE,CACtE;QACH;;AAGA,QAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE;;AAGlC,QAAA,OAAO,CAAA,+BAAA,EAAkC,UAAU,CAAA,SAAA,EAAY,GAAG,OAAO;IAC3E;AAEA;;AAEG;AACK,IAAA,oBAAoB,CAAC,SAAiB,EAAA;AAC5C,QAAA,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,OAAO;;QAGxC,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;AACpD,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,OAAO,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC5C;AAEA;;AAEG;AACK,IAAA,iBAAiB,CACvB,YAA6B,EAC7B,SAAiB,EACjB,QAAgB,EAAA;QAEhB,IAAI,CAAC,SAAS,EAAE;YAAE;AAElB,QAAA,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,YAAY,CAAC;QAE1D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,gBAAgB,EAAE;;AAE3C,YAAA,IAAI,CAAC,KAAK;gBAAE;;;AAIZ,YAAA,gBAAgB,CACd,KAAK,EACL,GAAG,EACH,SAAS;AACT,YAAA,QAAQ,EACR,IAAI,CAAC,OAAO,CAAC,KAAK,CACnB;QACH;AAEA,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;YACtB,OAAO,CAAC,GAAG,CACT,CAAA,yBAAA,EAA4B,gBAAgB,CAAC,MAAM,CAAA,kBAAA,EAAqB,SAAS,CAAA,CAAE,CACpF;QACH;IACF;;AAzSO,qBAAA,CAAA,IAAI,GAAc,SAAd;AA4Sb;;AAEG;AACG,SAAU,2BAA2B,CACzC,OAAqC,EAAA;AAErC,IAAA,OAAO,IAAI,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC;AACtD;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/utils.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n if (!hasMarker) return false;\n\n // Check 1: Running in an iframe (standard live editor)\n const inIframe = win.self !== win.top;\n if (inIframe) return true;\n\n // Check 2: PiP mode (popup with opener)\n const isPipMode = urlParams.get('pip_mode') === 'true' && !!win.opener;\n if (isPipMode) return true;\n\n return false;\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Detects if the application is running in PiP (Picture-in-Picture) mode\n * PiP mode requires pip_mode=true URL param and window.opener\n *\n * @returns true if in PiP mode\n */\nexport function detectPipMode(): boolean {\n if (!isBrowser()) return false;\n\n const win = getContentstorageWindow();\n if (!win) return false;\n\n try {\n const urlParams = new URLSearchParams(win.location.search);\n\n if (urlParams.get('pip_mode') !== 'true') return false;\n\n if (!win.opener) {\n console.warn('[Contentstorage] PiP mode requires opener window');\n return false;\n }\n\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string,\n mode?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n let cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n // Add pip_mode URL parameter if in pip mode\n if (mode === 'pip') {\n const separator = cdnScriptUrl.includes('?') ? '&' : '?';\n cdnScriptUrl += `${separator}pip_mode=true`;\n }\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[Contentstorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[Contentstorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[Contentstorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[Contentstorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Clears all entries from the memory map\n * Used by live editor to refresh tracking\n */\nexport function clearMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (memoryMap) {\n memoryMap.clear();\n }\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[Contentstorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[Contentstorage] Memory map not initialized');\n return;\n }\n\n console.log('[Contentstorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, detectPipMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode, clearMemoryMap, getContentstorageWindow } from './utils';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private i18nextInstance: any = null;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Detect pip mode to pass to script loading\n const isPipMode = detectPipMode();\n const scriptMode = isPipMode ? 'pip' : undefined;\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl, scriptMode);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Post-processor initialized in live mode');\n if (isPipMode) {\n console.log('[Contentstorage] PiP mode detected');\n }\n console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n }\n\n /**\n * Expose refresh function on window for live-editor.js to call\n * Only exposed in live mode (live editor or pip mode)\n */\n private exposeRefreshFunction(): void {\n if (!this.isLiveMode) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n win.__contentstorageRefresh = () => {\n // Clear memoryMap\n clearMemoryMap();\n\n // Trigger re-render by emitting languageChanged event\n // This causes useTranslation hooks to re-render\n if (this.i18nextInstance?.emit) {\n this.i18nextInstance.emit('languageChanged', this.i18nextInstance.language);\n }\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh triggered: memoryMap cleared, languageChanged emitted');\n }\n };\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh function exposed on window.__contentstorageRefresh');\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Store i18next reference on first call and expose refresh function\n if (!this.i18nextInstance && translator) {\n this.i18nextInstance = translator;\n this.exposeRefreshFunction();\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n detectPipMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Detect pip mode to pass to script loading\n const isPipMode = detectPipMode();\n const scriptMode = isPipMode ? 'pip' : undefined;\n\n // Load the live editor script\n loadLiveEditorScript(\n 2,\n 3000,\n this.options.debug,\n this.options.customLiveEditorScriptUrl,\n scriptMode\n ).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor ready');\n }\n } else {\n console.warn('[Contentstorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor mode enabled');\n if (isPipMode) {\n console.log('[Contentstorage] PiP mode detected');\n }\n console.log('[Contentstorage] Post-processor auto-registered');\n console.log('[Contentstorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[Contentstorage] Running in normal mode (not live editor)');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[Contentstorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[Contentstorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[Contentstorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[Contentstorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[Contentstorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[Contentstorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -34,19 +34,12 @@ export declare class ContentstorageBackend implements BackendModule<Contentstora
|
|
|
34
34
|
private options;
|
|
35
35
|
private isLiveMode;
|
|
36
36
|
private postProcessor?;
|
|
37
|
-
private services?;
|
|
38
|
-
private i18nextOptions?;
|
|
39
37
|
constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions);
|
|
40
38
|
/**
|
|
41
39
|
* Initialize the plugin
|
|
42
40
|
* Called by i18next during initialization
|
|
43
41
|
*/
|
|
44
42
|
init(services: Services, backendOptions?: ContentstoragePluginOptions, i18nextOptions?: InitOptions): void;
|
|
45
|
-
/**
|
|
46
|
-
* Initialize screenshot mode if URL params indicate it
|
|
47
|
-
* Exposes the API key for live-editor.js to use
|
|
48
|
-
*/
|
|
49
|
-
private initializeScreenshotMode;
|
|
50
43
|
/**
|
|
51
44
|
* Auto-register the live editor post-processor
|
|
52
45
|
* This allows dynamic translation tracking without requiring explicit postProcess config
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,WAAW,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EACV,2BAA2B,EAE5B,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,WAAW,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EACV,2BAA2B,EAE5B,MAAM,SAAS,CAAC;AAajB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,qBAAsB,YAAW,aAAa,CAAC,2BAA2B,CAAC;IACtF,MAAM,CAAC,IAAI,EAAE,SAAS,CAAa;IACnC,IAAI,EAAE,SAAS,CAAa;IAE5B,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,aAAa,CAAC,CAAwC;gBAElD,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,2BAA2B,EAAE,eAAe,CAAC,EAAE,WAAW;IAUtG;;;OAGG;IACH,IAAI,CACF,QAAQ,EAAE,QAAQ,EAClB,cAAc,GAAE,2BAAgC,EAChD,cAAc,GAAE,WAAgB,GAC/B,IAAI;IAwDP;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAwB7B;;;OAGG;IACH,IAAI,CACF,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,YAAY,GACrB,IAAI;IA2BP;;OAEG;YACW,gBAAgB;IA0B9B;;OAEG;YACW,YAAY;IAY1B;;OAEG;IACH,OAAO,CAAC,WAAW;IA6BnB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CA8B1B;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,CAAC,EAAE,2BAA2B,GACpC,qBAAqB,CAEvB;AAGD,eAAe,qBAAqB,CAAC"}
|
package/dist/post-processor.d.ts
CHANGED
|
@@ -31,14 +31,9 @@ export declare class ContentstorageLiveEditorPostProcessor implements PostProces
|
|
|
31
31
|
private isLiveMode;
|
|
32
32
|
private i18nextInstance;
|
|
33
33
|
constructor(options?: ContentstoragePluginOptions);
|
|
34
|
-
/**
|
|
35
|
-
* Initialize screenshot mode if URL params indicate it
|
|
36
|
-
* Works without iframe, unlike live editor mode
|
|
37
|
-
*/
|
|
38
|
-
private initializeScreenshotMode;
|
|
39
34
|
/**
|
|
40
35
|
* Expose refresh function on window for live-editor.js to call
|
|
41
|
-
* Only exposed in live mode (live editor or
|
|
36
|
+
* Only exposed in live mode (live editor or pip mode)
|
|
42
37
|
*/
|
|
43
38
|
private exposeRefreshFunction;
|
|
44
39
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-processor.d.ts","sourceRoot":"","sources":["../src/post-processor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"post-processor.d.ts","sourceRoot":"","sources":["../src/post-processor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAG3D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,qCAAsC,YAAW,mBAAmB;IAC/E,MAAM,CAAC,IAAI,EAAE,eAAe,CAAmB;IAC/C,IAAI,EAAE,eAAe,CAAmB;IACxC,IAAI,EAAE,MAAM,CAAoB;IAEhC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,eAAe,CAAa;gBAExB,OAAO,GAAE,2BAAgC;IAyCrD;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IA0B7B;;;OAGG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,EACtB,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,GAAG,GACd,MAAM;CAqEV;AAED;;GAEG;AACH,wBAAgB,2CAA2C,CACzD,OAAO,CAAC,EAAE,2BAA2B,GACpC,qCAAqC,CAEvC"}
|