@cldmv/slothlet 2.4.2 → 2.4.3
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/lib/modes/slothlet_eager.mjs +45 -13
- package/dist/lib/modes/slothlet_lazy.mjs +75 -7
- package/dist/slothlet.mjs +70 -8
- package/package.json +3 -3
- package/types/dist/lib/modes/slothlet_eager.d.mts.map +1 -1
- package/types/dist/lib/modes/slothlet_lazy.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts.map +1 -1
|
@@ -53,9 +53,18 @@ export async function create(dir, rootLevel = true, maxDepth = Infinity, current
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (mod && "default" in mod) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
|
|
57
|
+
const isSelfReferential = Object.entries(mod).some(([key, value]) => key !== "default" && value === mod.default);
|
|
58
|
+
|
|
59
|
+
if (!isSelfReferential) {
|
|
60
|
+
defaultExportFiles.push({ entry, fileName, mod });
|
|
61
|
+
if (this.config.debug) {
|
|
62
|
+
console.log(`[DEBUG] Added ${fileName} to defaultExportFiles (non-self-referential)`);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
if (this.config.debug) {
|
|
66
|
+
console.log(`[DEBUG] Skipped ${fileName} - self-referential default export`);
|
|
67
|
+
}
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
70
|
}
|
|
@@ -78,8 +87,12 @@ export async function create(dir, rootLevel = true, maxDepth = Infinity, current
|
|
|
78
87
|
const apiKey = this._toApiKey(fileName);
|
|
79
88
|
const mod = await this._loadSingleModule(path.join(dir, entry.name), true);
|
|
80
89
|
|
|
90
|
+
|
|
91
|
+
const isSelfReferential =
|
|
92
|
+
mod && "default" in mod && Object.entries(mod).some(([key, value]) => key !== "default" && value === mod.default);
|
|
93
|
+
|
|
81
94
|
if (mod && typeof mod.default === "function") {
|
|
82
|
-
if (hasMultipleDefaultExports) {
|
|
95
|
+
if (hasMultipleDefaultExports && !isSelfReferential) {
|
|
83
96
|
|
|
84
97
|
api[apiKey] = mod.default;
|
|
85
98
|
|
|
@@ -95,13 +108,12 @@ export async function create(dir, rootLevel = true, maxDepth = Infinity, current
|
|
|
95
108
|
}
|
|
96
109
|
} else {
|
|
97
110
|
|
|
98
|
-
|
|
99
111
|
if (this.config.debug) {
|
|
100
112
|
console.log(
|
|
101
|
-
`[DEBUG] Processing traditional default: hasMultipleDefaultExports=${hasMultipleDefaultExports}, rootDefaultFunction=${!!rootDefaultFunction}`
|
|
113
|
+
`[DEBUG] Processing traditional default: hasMultipleDefaultExports=${hasMultipleDefaultExports}, isSelfReferential=${isSelfReferential}, rootDefaultFunction=${!!rootDefaultFunction}`
|
|
102
114
|
);
|
|
103
115
|
}
|
|
104
|
-
if (!hasMultipleDefaultExports && !rootDefaultFunction) {
|
|
116
|
+
if ((!hasMultipleDefaultExports || isSelfReferential) && !rootDefaultFunction) {
|
|
105
117
|
rootDefaultFunction = mod.default;
|
|
106
118
|
if (this.config.debug) {
|
|
107
119
|
console.log(`[DEBUG] Set rootDefaultFunction to:`, mod.default.name);
|
|
@@ -117,19 +129,39 @@ export async function create(dir, rootLevel = true, maxDepth = Infinity, current
|
|
|
117
129
|
}
|
|
118
130
|
} else {
|
|
119
131
|
|
|
120
|
-
|
|
121
132
|
if (this.config.debug) {
|
|
122
|
-
console.log(`[DEBUG] Processing non-
|
|
133
|
+
console.log(`[DEBUG] Processing non-function or named-only exports for ${fileName}`);
|
|
123
134
|
}
|
|
124
135
|
|
|
125
|
-
if (
|
|
136
|
+
if (isSelfReferential) {
|
|
137
|
+
|
|
138
|
+
if (this.config.debug) {
|
|
139
|
+
console.log(`[DEBUG] Self-referential ${fileName}: preserving as namespace`);
|
|
140
|
+
}
|
|
141
|
+
api[apiKey] = mod.default;
|
|
142
|
+
} else if (hasMultipleDefaultExports) {
|
|
126
143
|
|
|
127
144
|
if (this.config.debug) {
|
|
128
145
|
console.log(`[DEBUG] Multi-default context: flattening ${fileName} exports to root`);
|
|
129
146
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
147
|
+
|
|
148
|
+
const eager_addNamedExportsToApi = (exports, api, rootNamedExports) => {
|
|
149
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
150
|
+
if (key !== "default") {
|
|
151
|
+
api[key] = value;
|
|
152
|
+
rootNamedExports[key] = value;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
if (mod && "default" in mod) {
|
|
158
|
+
|
|
159
|
+
api[apiKey] = mod.default;
|
|
160
|
+
|
|
161
|
+
eager_addNamedExportsToApi(mod, api, rootNamedExports);
|
|
162
|
+
} else {
|
|
163
|
+
|
|
164
|
+
eager_addNamedExportsToApi(mod, api, rootNamedExports);
|
|
133
165
|
}
|
|
134
166
|
} else {
|
|
135
167
|
|
|
@@ -35,27 +35,80 @@ export async function create(dir, rootLevel = true, maxDepth = Infinity, current
|
|
|
35
35
|
const defaultExportFiles = [];
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
const selfReferentialFiles = new Set();
|
|
39
|
+
const rawModuleCache = new Map();
|
|
40
|
+
|
|
38
41
|
for (const entry of moduleFiles) {
|
|
39
42
|
const ext = path.extname(entry.name);
|
|
40
43
|
const fileName = path.basename(entry.name, ext);
|
|
41
|
-
const mod = await instance._loadSingleModule(path.join(dir, entry.name), true);
|
|
42
44
|
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
+
if (instance.config.debug) {
|
|
46
|
+
console.log(`[DEBUG] First pass processing: ${fileName}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
const modulePath = path.resolve(dir, entry.name);
|
|
51
|
+
const rawMod = await import(`file://${modulePath.replace(/\\/g, "/")}`);
|
|
52
|
+
rawModuleCache.set(entry.name, rawMod);
|
|
53
|
+
|
|
54
|
+
if (instance.config.debug && fileName === "config") {
|
|
55
|
+
console.log(`[DEBUG] First pass - raw config keys:`, Object.keys(rawMod || {}));
|
|
56
|
+
console.log(`[DEBUG] First pass - raw config has default:`, rawMod && "default" in rawMod);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (rawMod && "default" in rawMod) {
|
|
60
|
+
|
|
61
|
+
const isSelfReferential = Object.entries(rawMod).some(([key, value]) => key !== "default" && value === rawMod.default);
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if (instance.config.debug && fileName === "config") {
|
|
65
|
+
console.log(`[DEBUG] First pass - ${fileName} self-referential check:`);
|
|
66
|
+
console.log(`[DEBUG] - rawMod.default === rawMod.config: ${rawMod.default === rawMod.config}`);
|
|
67
|
+
console.log(`[DEBUG] - isSelfReferential result: ${isSelfReferential}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!isSelfReferential) {
|
|
71
|
+
|
|
72
|
+
const mod = await instance._loadSingleModule(path.join(dir, entry.name), true);
|
|
73
|
+
defaultExportFiles.push({ entry, fileName, mod });
|
|
74
|
+
if (instance.config.debug) {
|
|
75
|
+
console.log(`[DEBUG] Added ${fileName} to defaultExportFiles (non-self-referential)`);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
selfReferentialFiles.add(fileName);
|
|
79
|
+
if (instance.config.debug) {
|
|
80
|
+
console.log(`[DEBUG] Skipped ${fileName} - self-referential default export`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
45
83
|
}
|
|
46
84
|
}
|
|
47
85
|
|
|
48
86
|
const hasMultipleDefaultExports = defaultExportFiles.length > 1;
|
|
49
87
|
|
|
50
88
|
|
|
89
|
+
const processedModuleCache = new Map();
|
|
90
|
+
|
|
51
91
|
for (const entry of moduleFiles) {
|
|
52
92
|
const ext = path.extname(entry.name);
|
|
53
93
|
const fileName = path.basename(entry.name, ext);
|
|
54
94
|
const apiKey = instance._toApiKey(fileName);
|
|
55
|
-
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
let mod = null;
|
|
98
|
+
const existingDefault = defaultExportFiles.find((def) => def.fileName === fileName);
|
|
99
|
+
if (existingDefault) {
|
|
100
|
+
mod = existingDefault.mod;
|
|
101
|
+
} else {
|
|
102
|
+
|
|
103
|
+
mod = await instance._loadSingleModule(path.join(dir, entry.name), true);
|
|
104
|
+
processedModuleCache.set(entry.name, mod);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
const isSelfReferential = selfReferentialFiles.has(fileName);
|
|
56
109
|
|
|
57
110
|
if (mod && typeof mod.default === "function") {
|
|
58
|
-
if (hasMultipleDefaultExports) {
|
|
111
|
+
if (hasMultipleDefaultExports && !isSelfReferential) {
|
|
59
112
|
|
|
60
113
|
api[apiKey] = mod.default;
|
|
61
114
|
|
|
@@ -69,6 +122,12 @@ export async function create(dir, rootLevel = true, maxDepth = Infinity, current
|
|
|
69
122
|
if (instance.config.debug) {
|
|
70
123
|
console.log(`[DEBUG] Multi-default in lazy mode: using filename '${apiKey}' for default export`);
|
|
71
124
|
}
|
|
125
|
+
} else if (isSelfReferential) {
|
|
126
|
+
|
|
127
|
+
if (instance.config.debug) {
|
|
128
|
+
console.log(`[DEBUG] Self-referential default export: preserving ${fileName} as namespace`);
|
|
129
|
+
}
|
|
130
|
+
api[apiKey] = mod;
|
|
72
131
|
} else {
|
|
73
132
|
|
|
74
133
|
|
|
@@ -86,13 +145,22 @@ export async function create(dir, rootLevel = true, maxDepth = Infinity, current
|
|
|
86
145
|
console.log(`[DEBUG] Processing non-default exports for ${fileName}`);
|
|
87
146
|
}
|
|
88
147
|
|
|
89
|
-
if (
|
|
148
|
+
if (isSelfReferential) {
|
|
149
|
+
|
|
150
|
+
if (instance.config.debug) {
|
|
151
|
+
console.log(`[DEBUG] Self-referential: preserving ${fileName} as namespace`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
api[apiKey] = mod[apiKey] || mod;
|
|
155
|
+
} else if (hasMultipleDefaultExports) {
|
|
90
156
|
|
|
91
157
|
if (instance.config.debug) {
|
|
92
158
|
console.log(`[DEBUG] Multi-default context: flattening ${fileName} exports to root`);
|
|
93
159
|
}
|
|
94
160
|
for (const [k, v] of Object.entries(mod)) {
|
|
95
|
-
|
|
161
|
+
if (k !== "default") {
|
|
162
|
+
api[k] = v;
|
|
163
|
+
}
|
|
96
164
|
}
|
|
97
165
|
} else {
|
|
98
166
|
|
package/dist/slothlet.mjs
CHANGED
|
@@ -423,33 +423,78 @@ const slothletObject = {
|
|
|
423
423
|
|
|
424
424
|
|
|
425
425
|
const defaultExportFiles = [];
|
|
426
|
+
const selfReferentialFiles = new Set();
|
|
427
|
+
const rawModuleCache = new Map();
|
|
428
|
+
|
|
429
|
+
|
|
426
430
|
for (const file of moduleFiles) {
|
|
427
431
|
const moduleExt = path.extname(file.name);
|
|
428
432
|
const moduleName = this._toApiKey(path.basename(file.name, moduleExt));
|
|
429
|
-
const
|
|
433
|
+
const moduleFilePath = path.resolve(categoryPath, file.name);
|
|
430
434
|
|
|
431
435
|
|
|
436
|
+
const rawMod = await import(`file://${moduleFilePath.replace(/\\/g, "/")}`);
|
|
437
|
+
rawModuleCache.set(file.name, rawMod);
|
|
438
|
+
|
|
432
439
|
|
|
433
|
-
if (
|
|
434
|
-
|
|
440
|
+
if (rawMod && "default" in rawMod) {
|
|
441
|
+
|
|
442
|
+
const isSelfReferential = Object.entries(rawMod).some(([key, value]) => key !== "default" && value === rawMod.default);
|
|
443
|
+
|
|
435
444
|
if (this.config.debug) {
|
|
436
|
-
console.log(`[DEBUG]
|
|
445
|
+
console.log(`[DEBUG] _buildCategory: Checking ${file.name} in ${categoryPath}`);
|
|
446
|
+
console.log(`[DEBUG] - moduleName: ${moduleName}`);
|
|
447
|
+
console.log(`[DEBUG] - has default: ${rawMod && "default" in rawMod}`);
|
|
448
|
+
console.log(`[DEBUG] - isSelfReferential: ${isSelfReferential}`);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (!isSelfReferential) {
|
|
452
|
+
|
|
453
|
+
const processedMod = await this._loadSingleModule(path.join(categoryPath, file.name));
|
|
454
|
+
defaultExportFiles.push({ file, moduleName, mod: processedMod });
|
|
455
|
+
if (this.config.debug) {
|
|
456
|
+
console.log(`[DEBUG] Found default export in ${file.name} (non-self-referential)`);
|
|
457
|
+
}
|
|
458
|
+
} else {
|
|
459
|
+
selfReferentialFiles.add(moduleName);
|
|
460
|
+
if (this.config.debug) {
|
|
461
|
+
console.log(`[DEBUG] Skipped ${file.name} - self-referential default export`);
|
|
462
|
+
}
|
|
437
463
|
}
|
|
438
464
|
}
|
|
439
465
|
}
|
|
440
466
|
|
|
441
467
|
const hasMultipleDefaultExports = defaultExportFiles.length > 1;
|
|
442
468
|
|
|
469
|
+
if (this.config.debug) {
|
|
470
|
+
console.log(`[DEBUG] selfReferentialFiles Set:`, Array.from(selfReferentialFiles));
|
|
471
|
+
console.log(`[DEBUG] hasMultipleDefaultExports:`, hasMultipleDefaultExports);
|
|
472
|
+
}
|
|
473
|
+
|
|
443
474
|
for (const file of moduleFiles) {
|
|
444
475
|
const moduleExt = path.extname(file.name);
|
|
445
476
|
const moduleName = this._toApiKey(path.basename(file.name, moduleExt));
|
|
446
477
|
|
|
447
478
|
|
|
479
|
+
if (this.config.debug && moduleName === "config") {
|
|
480
|
+
console.log("[DEBUG] Processing config file:", file.name, "moduleName:", moduleName);
|
|
481
|
+
console.log("[DEBUG] selfReferentialFiles has config?", selfReferentialFiles.has(moduleName));
|
|
482
|
+
}
|
|
483
|
+
|
|
448
484
|
|
|
449
|
-
|
|
450
|
-
|
|
485
|
+
let mod = null;
|
|
486
|
+
const existingDefault = defaultExportFiles.find(def => def.moduleName === moduleName);
|
|
487
|
+
if (existingDefault) {
|
|
488
|
+
mod = existingDefault.mod;
|
|
489
|
+
} else {
|
|
490
|
+
|
|
491
|
+
mod = await this._loadSingleModule(path.join(categoryPath, file.name));
|
|
492
|
+
}
|
|
451
493
|
|
|
452
|
-
|
|
494
|
+
if (this.config.debug && moduleName === "config") {
|
|
495
|
+
console.log("[DEBUG] Config mod type:", typeof mod);
|
|
496
|
+
console.log("[DEBUG] Config mod keys:", Object.keys(mod));
|
|
497
|
+
}
|
|
453
498
|
if (moduleName === categoryName && mod && typeof mod === "object") {
|
|
454
499
|
if (
|
|
455
500
|
Object.prototype.hasOwnProperty.call(mod, categoryName) &&
|
|
@@ -465,8 +510,11 @@ const slothletObject = {
|
|
|
465
510
|
}
|
|
466
511
|
} else if (typeof mod === "function") {
|
|
467
512
|
|
|
513
|
+
const isSelfReferential = selfReferentialFiles.has(moduleName);
|
|
514
|
+
|
|
515
|
+
|
|
468
516
|
let apiKey;
|
|
469
|
-
if (hasMultipleDefaultExports && mod.__slothletDefault === true) {
|
|
517
|
+
if (hasMultipleDefaultExports && mod.__slothletDefault === true && !isSelfReferential) {
|
|
470
518
|
|
|
471
519
|
apiKey = moduleName;
|
|
472
520
|
try {
|
|
@@ -477,6 +525,14 @@ const slothletObject = {
|
|
|
477
525
|
if (this.config.debug) {
|
|
478
526
|
console.log(`[DEBUG] Multi-default detected: using filename '${moduleName}' for default export`);
|
|
479
527
|
}
|
|
528
|
+
} else if (selfReferentialFiles.has(moduleName)) {
|
|
529
|
+
|
|
530
|
+
if (this.config.debug) {
|
|
531
|
+
console.log(`[DEBUG] Self-referential default export: treating ${moduleName} as namespace`);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
categoryModules[moduleName] = mod[moduleName] || mod;
|
|
535
|
+
continue;
|
|
480
536
|
} else {
|
|
481
537
|
|
|
482
538
|
const fnName = mod.name && mod.name !== "default" ? mod.name : moduleName;
|
|
@@ -553,6 +609,12 @@ const slothletObject = {
|
|
|
553
609
|
if (hasPreferredName) {
|
|
554
610
|
Object.assign(categoryModules, modWithPreferredNames);
|
|
555
611
|
|
|
612
|
+
} else if (selfReferentialFiles.has(moduleName)) {
|
|
613
|
+
|
|
614
|
+
if (this.config.debug) {
|
|
615
|
+
console.log(`[DEBUG] Self-referential object: treating ${moduleName} as namespace`);
|
|
616
|
+
}
|
|
617
|
+
categoryModules[moduleName] = mod[moduleName] || mod;
|
|
556
618
|
} else {
|
|
557
619
|
categoryModules[this._toApiKey(moduleName)] = mod;
|
|
558
620
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cldmv/slothlet",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.3",
|
|
4
4
|
"moduleVersions": {
|
|
5
|
-
"lazy": "1.
|
|
6
|
-
"eager": "1.
|
|
5
|
+
"lazy": "1.3.0",
|
|
6
|
+
"eager": "1.3.0"
|
|
7
7
|
},
|
|
8
8
|
"description": "Slothlet: Modular API Loader for Node.js. Lazy mode dynamically loads API modules and submodules only when accessed, supporting both lazy and eager loading.",
|
|
9
9
|
"main": "./index.cjs",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slothlet_eager.d.mts","sourceRoot":"","sources":["../../../../dist/lib/modes/slothlet_eager.mjs"],"names":[],"mappings":"AA2IA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAsDH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,4BAtBW,MAAM,cACN,OAAO,aACP,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"slothlet_eager.d.mts","sourceRoot":"","sources":["../../../../dist/lib/modes/slothlet_eager.mjs"],"names":[],"mappings":"AA2IA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAsDH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,4BAtBW,MAAM,cACN,OAAO,aACP,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,MAAM,CAAC,CAqM3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slothlet_lazy.d.mts","sourceRoot":"","sources":["../../../../dist/lib/modes/slothlet_lazy.mjs"],"names":[],"mappings":"AA6JA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,4BAvBW,MAAM,cACN,OAAO,aACP,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,WAAS,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"slothlet_lazy.d.mts","sourceRoot":"","sources":["../../../../dist/lib/modes/slothlet_lazy.mjs"],"names":[],"mappings":"AA6JA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,4BAvBW,MAAM,cACN,OAAO,aACP,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,WAAS,MAAM,CAAC,CAqMpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slothlet.d.mts","sourceRoot":"","sources":["../../dist/slothlet.mjs"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slothlet.d.mts","sourceRoot":"","sources":["../../dist/slothlet.mjs"],"names":[],"mappings":"AA4+CA;;;;;;;;;GASG;AACH,kDARW,WAAS,MAAM,UACf,WAAS,MAAM,QAwCzB;AAv4CD;;;;;;;GAOG;AACH,mBAJU,MAAM,CAIO;AAEvB;;;;;GAKG;AACH,sBAJU,MAAM,CAIU;AAE1B;;;;;GAKG;AACH,wBAJU,MAAM,CAIY;;;;;;;;;UA03Cd,MAAM;;;;;;WAIN,OAAO;;;;;;;eAGP,MAAM;;;;;;;;YAIN,OAAO;;;;;;;;WAKP,MAAM;;;;;;;eAKN,MAAM;;;;;;cAIN,MAAM;;;;;;gBAGN,MAAM;;;;;;eAMjB;QAA8B,UAAU,GAA7B,OAAO;QACY,gBAAgB,GAAnC,OAAO;QACY,gBAAgB,GAAnC,OAAO;QACW,KAAK,GAClC;YAAqC,KAAK,GAA/B,MAAM,EAAE;YACkB,gBAAgB,GAA1C,MAAM,EAAE;YACkB,KAAK,GAA/B,MAAM,EAAE;YACkB,KAAK,GAA/B,MAAM,EAAE;SACrB;KAAA;;AAl6CD;;;;;;;;GAQG;AACH,mCAJW,eAAe,GACb,OAAO,CAAC,WAAS,MAAM,CAAC,CAiCpC"}
|