semantic-release-openapi 1.5.1 → 2.0.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/@types/pluginConfig.js +2 -1
- package/README.md +4 -2
- package/index.d.ts +2 -2
- package/index.js +10 -2
- package/index.js.map +1 -1
- package/package.json +11 -9
- package/prepare.d.ts +4 -2
- package/prepare.js +26 -24
- package/prepare.js.map +1 -1
- package/verifyConditions.d.ts +3 -2
- package/verifyConditions.js +13 -9
- package/verifyConditions.js.map +1 -1
- package/getReplaceInFile.d.ts +0 -10
- package/getReplaceInFile.js +0 -13
- package/getReplaceInFile.js.map +0 -1
package/@types/pluginConfig.js
CHANGED
package/README.md
CHANGED
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
[][npm]
|
|
4
4
|
[][npm]
|
|
5
5
|
[](https://github.com/aensley/semantic-release-openapi/blob/main/LICENSE)
|
|
6
|
-
[](https://standardjs.com)
|
|
7
|
+
[](https://prettier.io)
|
|
7
8
|
|
|
8
9
|
[](https://github.com/aensley/semantic-release-openapi/actions/workflows/ci.yml)
|
|
9
10
|
[][qltysh]
|
|
10
11
|
[][qltysh]
|
|
12
|
+
[][npm]
|
|
11
13
|
|
|
12
14
|
A Semantic Release plugin to update versions in OpenAPI / Swagger specification files.
|
|
13
15
|
|
|
@@ -15,7 +17,7 @@ A Semantic Release plugin to update versions in OpenAPI / Swagger specification
|
|
|
15
17
|
|
|
16
18
|
This module is distributed via npm and should be installed as one of your project's `devDependencies`:
|
|
17
19
|
|
|
18
|
-
```
|
|
20
|
+
```bash
|
|
19
21
|
npm install --save-dev semantic-release-openapi
|
|
20
22
|
```
|
|
21
23
|
|
package/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default as verifyConditions } from './verifyConditions
|
|
2
|
-
export { default as prepare } from './prepare
|
|
1
|
+
export { default as verifyConditions } from './verifyConditions';
|
|
2
|
+
export { default as prepare } from './prepare';
|
package/index.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.prepare = exports.verifyConditions = void 0;
|
|
7
|
+
var verifyConditions_1 = require("./verifyConditions");
|
|
8
|
+
Object.defineProperty(exports, "verifyConditions", { enumerable: true, get: function () { return __importDefault(verifyConditions_1).default; } });
|
|
9
|
+
var prepare_1 = require("./prepare");
|
|
10
|
+
Object.defineProperty(exports, "prepare", { enumerable: true, get: function () { return __importDefault(prepare_1).default; } });
|
|
3
11
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAgE;AAAvD,qIAAA,OAAO,OAAoB;AACpC,qCAA8C;AAArC,mHAAA,OAAO,OAAW"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "semantic-release-openapi",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A Semantic Release plugin to update versions in OpenAPI / Swagger specification files",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"https://paypal.me/AndrewEnsley"
|
|
29
29
|
],
|
|
30
30
|
"homepage": "https://github.com/aensley/semantic-release-openapi#readme",
|
|
31
|
-
"type": "module",
|
|
32
31
|
"main": "index.js",
|
|
33
32
|
"module": "index.js",
|
|
34
33
|
"types": "index.d.ts",
|
|
34
|
+
"source": "src/index.ts",
|
|
35
35
|
"files": [
|
|
36
36
|
"**/*"
|
|
37
37
|
],
|
|
@@ -40,13 +40,15 @@
|
|
|
40
40
|
},
|
|
41
41
|
"platform": "node",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@semantic-release/error": "^
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
43
|
+
"@semantic-release/error": "^3.0.0",
|
|
44
|
+
"fs-extra": "^10.1.0",
|
|
45
|
+
"glob": "^8.0.3",
|
|
46
|
+
"replace-in-file": "^6.3.5",
|
|
47
|
+
"semantic-release": "^19.0.5"
|
|
48
48
|
},
|
|
49
|
-
"
|
|
50
|
-
"
|
|
49
|
+
"config": {
|
|
50
|
+
"commitizen": {
|
|
51
|
+
"path": "./node_modules/cz-conventional-changelog"
|
|
52
|
+
}
|
|
51
53
|
}
|
|
52
54
|
}
|
package/prepare.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Context } from 'semantic-release';
|
|
2
|
+
import PluginConfig from './@types/pluginConfig';
|
|
2
3
|
/**
|
|
3
4
|
* prepare hook for semantic release
|
|
4
5
|
*
|
|
5
6
|
* @throws {SemanticReleaseError}
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
declare const _default: ({ apiSpecFiles }: PluginConfig, { nextRelease, logger }: Context) => any;
|
|
9
|
+
export default _default;
|
package/prepare.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const error_1 = __importDefault(require("@semantic-release/error"));
|
|
7
|
+
const fs_extra_1 = require("fs-extra");
|
|
8
|
+
const replace_in_file_1 = __importDefault(require("replace-in-file"));
|
|
9
|
+
const glob_1 = __importDefault(require("glob"));
|
|
5
10
|
/**
|
|
6
11
|
* Prepare the API Spec files
|
|
7
12
|
*
|
|
@@ -11,28 +16,26 @@ const { readJsonSync, writeJsonSync } = fsExtra;
|
|
|
11
16
|
*
|
|
12
17
|
* @throws {SemanticReleaseError}
|
|
13
18
|
*/
|
|
14
|
-
const prepareApiSpecFiles =
|
|
15
|
-
const SemanticReleaseError = (await import('@semantic-release/error')).default;
|
|
19
|
+
const prepareApiSpecFiles = (apiSpecFiles, version, logger) => {
|
|
16
20
|
try {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
for (const fileName of fileNames) {
|
|
21
|
+
apiSpecFiles.forEach((fileNameGlob) => {
|
|
22
|
+
const fileNames = glob_1.default.sync(fileNameGlob);
|
|
23
|
+
fileNames.forEach((fileName) => {
|
|
21
24
|
let results;
|
|
22
25
|
if (fileName.split('.').pop() === 'json') {
|
|
23
26
|
results = prepareApiSpecFileJson(fileName, version);
|
|
24
27
|
}
|
|
25
28
|
else {
|
|
26
|
-
results =
|
|
29
|
+
results = prepareApiSpecFileYml(fileName, version);
|
|
27
30
|
}
|
|
28
31
|
results.forEach((resultFileName) => {
|
|
29
32
|
logger.log('Wrote version %s to %s', version, resultFileName);
|
|
30
33
|
});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
33
36
|
}
|
|
34
37
|
catch (error) {
|
|
35
|
-
throw new
|
|
38
|
+
throw new error_1.default(error);
|
|
36
39
|
}
|
|
37
40
|
};
|
|
38
41
|
/**
|
|
@@ -43,9 +46,8 @@ const prepareApiSpecFiles = async (apiSpecFiles, version, logger) => {
|
|
|
43
46
|
*
|
|
44
47
|
* @returns {string[]} A list of altered files
|
|
45
48
|
*/
|
|
46
|
-
const prepareApiSpecFileYml =
|
|
47
|
-
const
|
|
48
|
-
return replace
|
|
49
|
+
const prepareApiSpecFileYml = (apiSpecFile, version) => {
|
|
50
|
+
const changedFiles = replace_in_file_1.default
|
|
49
51
|
.sync({
|
|
50
52
|
files: apiSpecFile,
|
|
51
53
|
from: /version: ?.+$/im,
|
|
@@ -53,6 +55,7 @@ const prepareApiSpecFileYml = async (apiSpecFile, version) => {
|
|
|
53
55
|
})
|
|
54
56
|
.filter((result) => result.hasChanged)
|
|
55
57
|
.map((result) => result.file);
|
|
58
|
+
return changedFiles;
|
|
56
59
|
};
|
|
57
60
|
/**
|
|
58
61
|
* Prepares a single API spec file in JSON format
|
|
@@ -63,9 +66,9 @@ const prepareApiSpecFileYml = async (apiSpecFile, version) => {
|
|
|
63
66
|
* @returns {string[]} A list of altered files
|
|
64
67
|
*/
|
|
65
68
|
const prepareApiSpecFileJson = (apiSpecFile, version) => {
|
|
66
|
-
const specFile = readJsonSync(apiSpecFile);
|
|
69
|
+
const specFile = (0, fs_extra_1.readJsonSync)(apiSpecFile);
|
|
67
70
|
specFile.info.version = version;
|
|
68
|
-
writeJsonSync(apiSpecFile, specFile, { spaces: 2 });
|
|
71
|
+
(0, fs_extra_1.writeJsonSync)(apiSpecFile, specFile, { spaces: 2 });
|
|
69
72
|
return [apiSpecFile];
|
|
70
73
|
};
|
|
71
74
|
/**
|
|
@@ -73,12 +76,11 @@ const prepareApiSpecFileJson = (apiSpecFile, version) => {
|
|
|
73
76
|
*
|
|
74
77
|
* @throws {SemanticReleaseError}
|
|
75
78
|
*/
|
|
76
|
-
|
|
79
|
+
exports.default = ({ apiSpecFiles }, { nextRelease, logger }) => {
|
|
77
80
|
const version = nextRelease?.version ?? '';
|
|
78
81
|
if (version.length < 1) {
|
|
79
|
-
|
|
80
|
-
throw new SemanticReleaseError('Could not determine the version from semantic release.');
|
|
82
|
+
throw new error_1.default('Could not determine the version from semantic release.');
|
|
81
83
|
}
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
+
prepareApiSpecFiles(apiSpecFiles, version, logger);
|
|
85
|
+
};
|
|
84
86
|
//# sourceMappingURL=prepare.js.map
|
package/prepare.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepare.js","sourceRoot":"","sources":["../src/prepare.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"prepare.js","sourceRoot":"","sources":["../src/prepare.ts"],"names":[],"mappings":";;;;;AAAA,oEAA0D;AAC1D,uCAAsD;AACtD,sEAAqC;AAGrC,gDAAuB;AAEvB;;;;;;;;GAQG;AACH,MAAM,mBAAmB,GAAG,CAAC,YAAsB,EAAE,OAAe,EAAE,MAAyB,EAAO,EAAE;IACtG,IAAI;QACF,YAAY,CAAC,OAAO,CAAC,CAAC,YAAoB,EAAE,EAAE;YAC5C,MAAM,SAAS,GAAa,cAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YACnD,SAAS,CAAC,OAAO,CAAC,CAAC,QAAgB,EAAE,EAAE;gBACrC,IAAI,OAAiB,CAAA;gBACrB,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,MAAM,EAAE;oBACxC,OAAO,GAAG,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;iBACpD;qBAAM;oBACL,OAAO,GAAG,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;iBACnD;gBACD,OAAO,CAAC,OAAO,CAAC,CAAC,cAAsB,EAAE,EAAE;oBACzC,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,OAAO,EAAE,cAAc,CAAC,CAAA;gBAC/D,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;KACH;IAAC,OAAO,KAAU,EAAE;QACnB,MAAM,IAAI,eAAoB,CAAC,KAAK,CAAC,CAAA;KACtC;AACH,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,qBAAqB,GAAG,CAAC,WAAmB,EAAE,OAAe,EAAY,EAAE;IAC/E,MAAM,YAAY,GAAG,yBAAO;SACzB,IAAI,CAAC;QACJ,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,iBAAiB;QACvB,EAAE,EAAE,WAAW,GAAG,OAAO;KAC1B,CAAC;SACD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;SACrC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC/B,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,sBAAsB,GAAG,CAAC,WAAmB,EAAE,OAAe,EAAY,EAAE;IAChF,MAAM,QAAQ,GAAG,IAAA,uBAAY,EAAC,WAAW,CAAC,CAAA;IAC1C,QAAQ,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IAC/B,IAAA,wBAAa,EAAC,WAAW,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;IACnD,OAAO,CAAC,WAAW,CAAC,CAAA;AACtB,CAAC,CAAA;AAED;;;;GAIG;AACH,kBAAe,CAAC,EAAE,YAAY,EAAgB,EAAE,EAAE,WAAW,EAAE,MAAM,EAAW,EAAO,EAAE;IACvF,MAAM,OAAO,GAAG,WAAW,EAAE,OAAO,IAAI,EAAE,CAAA;IAC1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;QACtB,MAAM,IAAI,eAAoB,CAAC,wDAAwD,CAAC,CAAA;KACzF;IAED,mBAAmB,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;AACpD,CAAC,CAAA"}
|
package/verifyConditions.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import PluginConfig from './@types/pluginConfig
|
|
1
|
+
import PluginConfig from './@types/pluginConfig';
|
|
2
2
|
/**
|
|
3
3
|
* verifyConditions hook for semantic release
|
|
4
4
|
*
|
|
5
5
|
* @throws {SemanticReleaseError}
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
declare const _default: ({ apiSpecFiles }: PluginConfig) => Promise<any>;
|
|
8
|
+
export default _default;
|
package/verifyConditions.js
CHANGED
|
@@ -1,30 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const error_1 = __importDefault(require("@semantic-release/error"));
|
|
7
|
+
const glob_1 = __importDefault(require("glob"));
|
|
2
8
|
/**
|
|
3
9
|
* verifyConditions hook for semantic release
|
|
4
10
|
*
|
|
5
11
|
* @throws {SemanticReleaseError}
|
|
6
12
|
*/
|
|
7
|
-
|
|
8
|
-
const SemanticReleaseError = (await import('@semantic-release/error')).default;
|
|
13
|
+
exports.default = async ({ apiSpecFiles }) => {
|
|
9
14
|
if (apiSpecFiles.length < 1) {
|
|
10
|
-
throw new
|
|
15
|
+
throw new error_1.default('Option "apiSpecFiles" was not included in the plugin config. See the README for instructions.', 'ENOAPISPECFILES');
|
|
11
16
|
}
|
|
12
17
|
const expectedExts = ['json', 'yaml', 'yml'];
|
|
13
18
|
let specFilesFound = false;
|
|
14
19
|
apiSpecFiles.forEach((fileNameGlob) => {
|
|
15
|
-
|
|
16
|
-
const fileNames = new fdir().glob(fileNameGlob).withBasePath().crawl('.').sync();
|
|
20
|
+
const fileNames = glob_1.default.sync(fileNameGlob);
|
|
17
21
|
if (fileNames.length > 0) {
|
|
18
22
|
specFilesFound = true;
|
|
19
23
|
fileNames.forEach((fileName) => {
|
|
20
24
|
if (!expectedExts.includes(fileName.split('.').pop() ?? '')) {
|
|
21
|
-
throw new
|
|
25
|
+
throw new error_1.default('File "' + fileName + '" is not valid. Must be a file with .json, .yaml, or .yml extension', 'EINVALIDAPISPECFILETYPE');
|
|
22
26
|
}
|
|
23
27
|
});
|
|
24
28
|
}
|
|
25
29
|
});
|
|
26
30
|
if (!specFilesFound) {
|
|
27
|
-
throw new
|
|
31
|
+
throw new error_1.default('No files match the paths in "apiSpecFiles". Check your plugin config and try again.', 'EINVALIDAPISPECFILES');
|
|
28
32
|
}
|
|
29
|
-
}
|
|
33
|
+
};
|
|
30
34
|
//# sourceMappingURL=verifyConditions.js.map
|
package/verifyConditions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyConditions.js","sourceRoot":"","sources":["../src/verifyConditions.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"verifyConditions.js","sourceRoot":"","sources":["../src/verifyConditions.ts"],"names":[],"mappings":";;;;;AAAA,oEAA0D;AAC1D,gDAAuB;AAGvB;;;;GAIG;AACH,kBAAe,KAAK,EAAE,EAAE,YAAY,EAAgB,EAAgB,EAAE;IACpE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;QAC3B,MAAM,IAAI,eAAoB,CAC5B,+FAA+F,EAC/F,iBAAiB,CAClB,CAAA;KACF;IAED,MAAM,YAAY,GAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;IACtD,IAAI,cAAc,GAAY,KAAK,CAAA;IACnC,YAAY,CAAC,OAAO,CAAC,CAAC,YAAoB,EAAE,EAAE;QAC5C,MAAM,SAAS,GAAa,cAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACnD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACxB,cAAc,GAAG,IAAI,CAAA;YACrB,SAAS,CAAC,OAAO,CAAC,CAAC,QAAgB,EAAE,EAAE;gBACrC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE;oBAC3D,MAAM,IAAI,eAAoB,CAC5B,QAAQ,GAAG,QAAQ,GAAG,qEAAqE,EAC3F,yBAAyB,CAC1B,CAAA;iBACF;YACH,CAAC,CAAC,CAAA;SACH;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,cAAc,EAAE;QACnB,MAAM,IAAI,eAAoB,CAC5B,qFAAqF,EACrF,sBAAsB,CACvB,CAAA;KACF;AACH,CAAC,CAAA"}
|
package/getReplaceInFile.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dynamically imports and returns the default export from the 'replace-in-file' module.
|
|
3
|
-
*
|
|
4
|
-
* This function uses dynamic import to load the 'replace-in-file' package at runtime,
|
|
5
|
-
* which can help reduce initial load time and dependencies if the functionality is only
|
|
6
|
-
* needed conditionally.
|
|
7
|
-
*
|
|
8
|
-
* @returns A promise that resolves to the default export of the 'replace-in-file' module.
|
|
9
|
-
*/
|
|
10
|
-
export default function (): Promise<typeof import('replace-in-file').default>;
|
package/getReplaceInFile.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dynamically imports and returns the default export from the 'replace-in-file' module.
|
|
3
|
-
*
|
|
4
|
-
* This function uses dynamic import to load the 'replace-in-file' package at runtime,
|
|
5
|
-
* which can help reduce initial load time and dependencies if the functionality is only
|
|
6
|
-
* needed conditionally.
|
|
7
|
-
*
|
|
8
|
-
* @returns A promise that resolves to the default export of the 'replace-in-file' module.
|
|
9
|
-
*/
|
|
10
|
-
export default async function () {
|
|
11
|
-
return (await import('replace-in-file')).default;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=getReplaceInFile.js.map
|
package/getReplaceInFile.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getReplaceInFile.js","sourceRoot":"","sources":["../src/getReplaceInFile.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,OAAO,CAAC,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAA;AAClD,CAAC"}
|