@darraghor/eslint-plugin-nestjs-typed 6.17.0 → 6.18.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/README.md +2 -1
- package/dist/configs/recommended.js +2 -1
- package/dist/rules/apiOperationSummaryDescriptionCapitalized/apiOperationSummaryDescriptionCapitalized.d.ts +2 -0
- package/dist/rules/apiOperationSummaryDescriptionCapitalized/apiOperationSummaryDescriptionCapitalized.js +95 -0
- package/dist/rules/index.d.ts +1 -0
- package/dist/rules/index.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,7 @@ Awesome! [Click here](https://github.com/darraghoriordan/eslint-plugin-nestjs-ty
|
|
|
71
71
|
| | [`api-method-should-specify-api-operation`](./src/docs/rules/api-method-should-specify-api-operation.md) | ✅ |
|
|
72
72
|
| | [`api-enum-property-best-practices`](./src/docs/rules/api-enum-property-best-practices.md) | ✅ |
|
|
73
73
|
| | [`api-property-returning-array-should-set-array`](./src/docs/rules/api-property-returning-array-should-set-array.md) | ✅ |
|
|
74
|
+
| | [`api-operation-summary-description-capitalized`](./src/docs/rules/api-operation-summary-description-capitalized.md) | ✅ |
|
|
74
75
|
| | | |
|
|
75
76
|
| Preventing bugs | [`param-decorator-name-matches-route-param`](./src/docs/rules/param-decorator-name-matches-route-param.md) | ✅ |
|
|
76
77
|
| | [`validate-nested-of-array-should-set-each`](./src/docs/rules/validate-nested-of-array-should-set-each.md) | ✅ |
|
|
@@ -78,7 +79,7 @@ Awesome! [Click here](https://github.com/darraghoriordan/eslint-plugin-nestjs-ty
|
|
|
78
79
|
| | [`all-properties-are-whitelisted`](./src/docs/rules/all-properties-are-whitelisted.md) | ✅ |
|
|
79
80
|
| | [`all-properties-have-explicit-defined`](./src/docs/rules/all-properties-have-explicit-defined.md) | ✅ |
|
|
80
81
|
| | [`no-duplicate-decorators`](./src/docs/rules/no-duplicate-decorators.md) | ✅ |
|
|
81
|
-
| | [`should-
|
|
82
|
+
| | [`validation-pipe-should-use-forbid-unknown`](./src/docs/rules/validation-pipe-should-use-forbid-unknown.md) | ✅ |
|
|
82
83
|
| | | |
|
|
83
84
|
| Security | [`api-methods-should-be-guarded`](./src/docs/rules/api-methods-should-be-guarded.md) | ❌ |
|
|
84
85
|
| | | |
|
|
@@ -24,10 +24,11 @@ export const rules = {
|
|
|
24
24
|
"@darraghor/nestjs-typed/no-duplicate-decorators": "error",
|
|
25
25
|
"@darraghor/nestjs-typed/use-injectable-provided-token": "error",
|
|
26
26
|
"@darraghor/nestjs-typed/api-property-should-have-api-extra-models": "error",
|
|
27
|
+
"@darraghor/nestjs-typed/api-operation-summary-description-capitalized": "error",
|
|
27
28
|
"@darraghor/nestjs-typed/use-dependency-injection": "off",
|
|
28
29
|
};
|
|
29
30
|
export default {
|
|
30
31
|
extends: ["./configs/base"],
|
|
31
32
|
rules,
|
|
32
33
|
};
|
|
33
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlncy9yZWNvbW1lbmRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQWdDO0lBQzlDLDJFQUEyRSxFQUN2RSxPQUFPO0lBQ1gsdURBQXVELEVBQUU7UUFDckQsT0FBTztRQUNQO1lBQ0ksR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDO1lBQ3BCLGVBQWUsRUFBRSxDQUFDLGNBQWMsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDO1NBQ3hEO0tBQ0o7SUFDRCxtRUFBbUUsRUFDL0QsT0FBTztJQUNYLGdFQUFnRSxFQUFFLE9BQU87SUFDekUsNERBQTRELEVBQUUsT0FBTztJQUNyRSwwREFBMEQsRUFBRSxPQUFPO0lBQ25FLHVFQUF1RSxFQUNuRSxPQUFPO0lBQ1gsOERBQThELEVBQUUsT0FBTztJQUN2RSxrRUFBa0UsRUFBRSxPQUFPO0lBQzNFLCtFQUErRSxFQUMzRSxPQUFPO0lBQ1gsa0VBQWtFLEVBQUUsT0FBTztJQUMzRSx3REFBd0QsRUFBRSxPQUFPO0lBQ2pFLDhEQUE4RCxFQUFFLE9BQU87SUFDdkUsdURBQXVELEVBQUUsS0FBSztJQUM5RCxpRUFBaUUsRUFBRSxLQUFLO0lBQ3hFLHFEQUFxRCxFQUFFLEtBQUs7SUFDNUQsaURBQWlELEVBQUUsT0FBTztJQUMxRCx1REFBdUQsRUFBRSxPQUFPO0lBQ2hFLG1FQUFtRSxFQUMvRCxPQUFPO0lBQ1gsdUVBQXVFLEVBQ25FLE9BQU87SUFDWCxrREFBa0QsRUFBRSxLQUFLO0NBQzVELENBQUM7QUFDRixlQUFlO0lBQ1gsT0FBTyxFQUFFLENBQUMsZ0JBQWdCLENBQUM7SUFDM0IsS0FBSztDQUNSLENBQUMifQ==
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
import { createRule } from "../../utils/createRule.js";
|
|
3
|
+
import { typedTokenHelpers } from "../../utils/typedTokenHelpers.js";
|
|
4
|
+
const isCapitalized = (text) => {
|
|
5
|
+
if (!text || text.length === 0) {
|
|
6
|
+
return true; // Empty strings pass validation
|
|
7
|
+
}
|
|
8
|
+
const firstChar = text.charAt(0);
|
|
9
|
+
// If the first character is not a letter, consider it valid (e.g., numbers, special chars)
|
|
10
|
+
if (firstChar === firstChar.toUpperCase() &&
|
|
11
|
+
firstChar === firstChar.toLowerCase()) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
// Check if the first letter is uppercase
|
|
15
|
+
return firstChar === firstChar.toUpperCase();
|
|
16
|
+
};
|
|
17
|
+
const getStringPropertyValue = (objectExpression, propertyName) => {
|
|
18
|
+
const property = objectExpression.properties.find((p) => p.type === TSESTree.AST_NODE_TYPES.Property &&
|
|
19
|
+
p.key.type === TSESTree.AST_NODE_TYPES.Identifier &&
|
|
20
|
+
p.key.name === propertyName);
|
|
21
|
+
if (property &&
|
|
22
|
+
property.type === TSESTree.AST_NODE_TYPES.Property &&
|
|
23
|
+
property.value.type === TSESTree.AST_NODE_TYPES.Literal &&
|
|
24
|
+
typeof property.value.value === "string") {
|
|
25
|
+
return property.value.value;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
};
|
|
29
|
+
const checkApiOperationDecorator = (node) => {
|
|
30
|
+
const issues = [];
|
|
31
|
+
const apiOperationDecorators = typedTokenHelpers.getDecoratorsNamed(node, [
|
|
32
|
+
"ApiOperation",
|
|
33
|
+
]);
|
|
34
|
+
for (const decorator of apiOperationDecorators) {
|
|
35
|
+
if (decorator.expression.type === TSESTree.AST_NODE_TYPES.CallExpression) {
|
|
36
|
+
const firstArgument = decorator.expression.arguments[0];
|
|
37
|
+
if (firstArgument &&
|
|
38
|
+
firstArgument.type === TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
39
|
+
// Check summary property
|
|
40
|
+
const summary = getStringPropertyValue(firstArgument, "summary");
|
|
41
|
+
if (summary && !isCapitalized(summary)) {
|
|
42
|
+
issues.push({
|
|
43
|
+
property: "summary",
|
|
44
|
+
value: summary,
|
|
45
|
+
decorator,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Check description property
|
|
49
|
+
const description = getStringPropertyValue(firstArgument, "description");
|
|
50
|
+
if (description && !isCapitalized(description)) {
|
|
51
|
+
issues.push({
|
|
52
|
+
property: "description",
|
|
53
|
+
value: description,
|
|
54
|
+
decorator,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return issues;
|
|
61
|
+
};
|
|
62
|
+
const rule = createRule({
|
|
63
|
+
name: "api-operation-summary-description-capitalized",
|
|
64
|
+
meta: {
|
|
65
|
+
docs: {
|
|
66
|
+
description: "ApiOperation summary and description should start with an uppercase letter.",
|
|
67
|
+
},
|
|
68
|
+
messages: {
|
|
69
|
+
shouldBeCapitalized: `The {{property}} in @ApiOperation should start with an uppercase letter. Found: "{{value}}"`,
|
|
70
|
+
},
|
|
71
|
+
schema: [],
|
|
72
|
+
hasSuggestions: false,
|
|
73
|
+
type: "suggestion",
|
|
74
|
+
},
|
|
75
|
+
defaultOptions: [],
|
|
76
|
+
create(context) {
|
|
77
|
+
return {
|
|
78
|
+
MethodDefinition(node) {
|
|
79
|
+
const issues = checkApiOperationDecorator(node);
|
|
80
|
+
for (const issue of issues) {
|
|
81
|
+
context.report({
|
|
82
|
+
node: issue.decorator,
|
|
83
|
+
messageId: "shouldBeCapitalized",
|
|
84
|
+
data: {
|
|
85
|
+
property: issue.property,
|
|
86
|
+
value: issue.value,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
export default rule;
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpT3BlcmF0aW9uU3VtbWFyeURlc2NyaXB0aW9uQ2FwaXRhbGl6ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvYXBpT3BlcmF0aW9uU3VtbWFyeURlc2NyaXB0aW9uQ2FwaXRhbGl6ZWQvYXBpT3BlcmF0aW9uU3VtbWFyeURlc2NyaXB0aW9uQ2FwaXRhbGl6ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxrQ0FBa0MsQ0FBQztBQUVuRSxNQUFNLGFBQWEsR0FBRyxDQUFDLElBQVksRUFBVyxFQUFFO0lBQzVDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM3QixPQUFPLElBQUksQ0FBQyxDQUFDLGdDQUFnQztJQUNqRCxDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqQywyRkFBMkY7SUFDM0YsSUFDSSxTQUFTLEtBQUssU0FBUyxDQUFDLFdBQVcsRUFBRTtRQUNyQyxTQUFTLEtBQUssU0FBUyxDQUFDLFdBQVcsRUFBRSxFQUN2QyxDQUFDO1FBQ0MsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUNELHlDQUF5QztJQUN6QyxPQUFPLFNBQVMsS0FBSyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDakQsQ0FBQyxDQUFDO0FBRUYsTUFBTSxzQkFBc0IsR0FBRyxDQUMzQixnQkFBMkMsRUFDM0MsWUFBb0IsRUFDUCxFQUFFO0lBQ2YsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FDN0MsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNGLENBQUMsQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLGNBQWMsQ0FBQyxRQUFRO1FBQzNDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVTtRQUNqRCxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxZQUFZLENBQ2xDLENBQUM7SUFFRixJQUNJLFFBQVE7UUFDUixRQUFRLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxjQUFjLENBQUMsUUFBUTtRQUNsRCxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsY0FBYyxDQUFDLE9BQU87UUFDdkQsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxRQUFRLEVBQzFDLENBQUM7UUFDQyxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDLENBQUM7QUFFRixNQUFNLDBCQUEwQixHQUFHLENBQy9CLElBQStCLEVBQ21DLEVBQUU7SUFDcEUsTUFBTSxNQUFNLEdBSU4sRUFBRSxDQUFDO0lBRVQsTUFBTSxzQkFBc0IsR0FBRyxpQkFBaUIsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUU7UUFDdEUsY0FBYztLQUNqQixDQUFDLENBQUM7SUFFSCxLQUFLLE1BQU0sU0FBUyxJQUFJLHNCQUFzQixFQUFFLENBQUM7UUFDN0MsSUFDSSxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFDdEUsQ0FBQztZQUNDLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXhELElBQ0ksYUFBYTtnQkFDYixhQUFhLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLEVBQ2pFLENBQUM7Z0JBQ0MseUJBQXlCO2dCQUN6QixNQUFNLE9BQU8sR0FBRyxzQkFBc0IsQ0FDbEMsYUFBYSxFQUNiLFNBQVMsQ0FDWixDQUFDO2dCQUNGLElBQUksT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ3JDLE1BQU0sQ0FBQyxJQUFJLENBQUM7d0JBQ1IsUUFBUSxFQUFFLFNBQVM7d0JBQ25CLEtBQUssRUFBRSxPQUFPO3dCQUNkLFNBQVM7cUJBQ1osQ0FBQyxDQUFDO2dCQUNQLENBQUM7Z0JBRUQsNkJBQTZCO2dCQUM3QixNQUFNLFdBQVcsR0FBRyxzQkFBc0IsQ0FDdEMsYUFBYSxFQUNiLGFBQWEsQ0FDaEIsQ0FBQztnQkFDRixJQUFJLFdBQVcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO29CQUM3QyxNQUFNLENBQUMsSUFBSSxDQUFDO3dCQUNSLFFBQVEsRUFBRSxhQUFhO3dCQUN2QixLQUFLLEVBQUUsV0FBVzt3QkFDbEIsU0FBUztxQkFDWixDQUFDLENBQUM7Z0JBQ1AsQ0FBQztZQUNMLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUVGLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBNEI7SUFDL0MsSUFBSSxFQUFFLCtDQUErQztJQUNyRCxJQUFJLEVBQUU7UUFDRixJQUFJLEVBQUU7WUFDRixXQUFXLEVBQ1AsNkVBQTZFO1NBQ3BGO1FBQ0QsUUFBUSxFQUFFO1lBQ04sbUJBQW1CLEVBQUUsNkZBQTZGO1NBQ3JIO1FBQ0QsTUFBTSxFQUFFLEVBQUU7UUFDVixjQUFjLEVBQUUsS0FBSztRQUNyQixJQUFJLEVBQUUsWUFBWTtLQUNyQjtJQUNELGNBQWMsRUFBRSxFQUFFO0lBRWxCLE1BQU0sQ0FBQyxPQUFPO1FBQ1YsT0FBTztZQUNILGdCQUFnQixDQUFDLElBQStCO2dCQUM1QyxNQUFNLE1BQU0sR0FBRywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFaEQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztvQkFDekIsT0FBTyxDQUFDLE1BQU0sQ0FBQzt3QkFDWCxJQUFJLEVBQUUsS0FBSyxDQUFDLFNBQVM7d0JBQ3JCLFNBQVMsRUFBRSxxQkFBcUI7d0JBQ2hDLElBQUksRUFBRTs0QkFDRixRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7NEJBQ3hCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSzt5QkFDckI7cUJBQ0osQ0FBQyxDQUFDO2dCQUNQLENBQUM7WUFDTCxDQUFDO1NBQ0osQ0FBQztJQUNOLENBQUM7Q0FDSixDQUFDLENBQUM7QUFFSCxlQUFlLElBQUksQ0FBQyJ9
|
package/dist/rules/index.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ declare const allRules: {
|
|
|
33
33
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
34
34
|
"use-injectable-provided-token": import("@typescript-eslint/utils/ts-eslint").RuleModule<"useInjectableProvidedToken", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
35
35
|
"api-property-should-have-api-extra-models": import("@typescript-eslint/utils/ts-eslint").RuleModule<"shouldUseApiExtraModels", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
36
|
+
"api-operation-summary-description-capitalized": import("@typescript-eslint/utils/ts-eslint").RuleModule<"shouldBeCapitalized", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
36
37
|
"use-dependency-injection": import("@typescript-eslint/utils/ts-eslint").RuleModule<"useDependencyInjection", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
37
38
|
};
|
|
38
39
|
export default allRules;
|
package/dist/rules/index.js
CHANGED
|
@@ -18,6 +18,7 @@ import noDuplicateDecorators from "./noDuplicateDecorators/noDuplicateDecorators
|
|
|
18
18
|
import useCorrectEndpointNamingConvention from "./useCorrectEndpointNamingConvention/useCorrectEndpointNamingConvention.js";
|
|
19
19
|
import useInjectableProvidedToken from "./useInjectableProvidedToken/useInjectableProvidedToken.js";
|
|
20
20
|
import apiPropertyShouldHaveApiExtraModels from "./apiPropertyShouldHaveApiExtraModels/apiPropertyShouldHaveApiExtraModels.js";
|
|
21
|
+
import apiOperationSummaryDescriptionCapitalized from "./apiOperationSummaryDescriptionCapitalized/apiOperationSummaryDescriptionCapitalized.js";
|
|
21
22
|
import useDependencyInjection from "./useDependencyInjection/useDependencyInjection.js";
|
|
22
23
|
const allRules = {
|
|
23
24
|
"all-properties-have-explicit-defined": allPropertiesHaveExplicitDefined,
|
|
@@ -40,7 +41,8 @@ const allRules = {
|
|
|
40
41
|
"use-correct-endpoint-naming-convention": useCorrectEndpointNamingConvention,
|
|
41
42
|
"use-injectable-provided-token": useInjectableProvidedToken,
|
|
42
43
|
"api-property-should-have-api-extra-models": apiPropertyShouldHaveApiExtraModels,
|
|
44
|
+
"api-operation-summary-description-capitalized": apiOperationSummaryDescriptionCapitalized,
|
|
43
45
|
"use-dependency-injection": useDependencyInjection,
|
|
44
46
|
};
|
|
45
47
|
export default allRules;
|
|
46
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTywwQkFBMEIsTUFBTSw2REFBNkQsQ0FBQztBQUNyRyxPQUFPLDRDQUE0QyxNQUFNLDRFQUE0RSxDQUFDO0FBQ3RJLE9BQU8scUNBQXFDLE1BQU0sa0ZBQWtGLENBQUM7QUFDckksT0FBTyw2QkFBNkIsTUFBTSxrRUFBa0UsQ0FBQztBQUM3RyxPQUFPLGtDQUFrQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzVILE9BQU8sNEJBQTRCLE1BQU0sZ0VBQWdFLENBQUM7QUFDMUcsT0FBTyx1Q0FBdUMsTUFBTSxzRkFBc0YsQ0FBQztBQUMzSSxPQUFPLGdDQUFnQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzFILE9BQU8sdUNBQXVDLE1BQU0sOEVBQThFLENBQUM7QUFDbkksT0FBTyxtQ0FBbUMsTUFBTSxpRkFBaUYsQ0FBQztBQUNsSSxPQUFPLGtDQUFrQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzVILE9BQU8sMkJBQTJCLE1BQU0sOERBQThELENBQUM7QUFDdkcsT0FBTyxnQ0FBZ0MsTUFBTSx3RUFBd0UsQ0FBQztBQUN0SCxPQUFPLHlCQUF5QixNQUFNLDBEQUEwRCxDQUFDO0FBQ2pHLE9BQU8sbUNBQW1DLE1BQU0sOEVBQThFLENBQUM7QUFDL0gsT0FBTyx3QkFBd0IsTUFBTSx3REFBd0QsQ0FBQztBQUM5RixPQUFPLHFCQUFxQixNQUFNLGtEQUFrRCxDQUFDO0FBQ3JGLE9BQU8sa0NBQWtDLE1BQU0sNEVBQTRFLENBQUM7QUFDNUgsT0FBTywwQkFBMEIsTUFBTSw0REFBNEQsQ0FBQztBQUNwRyxPQUFPLG1DQUFtQyxNQUFNLDhFQUE4RSxDQUFDO0FBQy9ILE9BQU8seUNBQXlDLE1BQU0sMEZBQTBGLENBQUM7QUFDakosT0FBTyxzQkFBc0IsTUFBTSxvREFBb0QsQ0FBQztBQUN4RixNQUFNLFFBQVEsR0FBRztJQUNiLHNDQUFzQyxFQUFFLGdDQUFnQztJQUN4RSwyQ0FBMkMsRUFDdkMscUNBQXFDO0lBQ3pDLCtCQUErQixFQUFFLDBCQUEwQjtJQUMzRCx5QkFBeUIsRUFBRSxxQkFBcUI7SUFDaEQsbURBQW1ELEVBQy9DLDRDQUE0QztJQUNoRCxvQ0FBb0MsRUFBRSw2QkFBNkI7SUFDbkUsd0NBQXdDLEVBQ3BDLGtDQUFrQztJQUN0Qyx5Q0FBeUMsRUFDckMsbUNBQW1DO0lBQ3ZDLGtDQUFrQyxFQUFFLDRCQUE0QjtJQUNoRSwrQ0FBK0MsRUFDM0MsdUNBQXVDO0lBQzNDLHNDQUFzQyxFQUFFLGdDQUFnQztJQUN4RSwwQ0FBMEMsRUFDdEMsdUNBQXVDO0lBQzNDLHVEQUF1RCxFQUNuRCxtQ0FBbUM7SUFDdkMsMENBQTBDLEVBQ3RDLGtDQUFrQztJQUN0QyxnQ0FBZ0MsRUFBRSwyQkFBMkI7SUFDN0QsK0JBQStCLEVBQUUseUJBQXlCO0lBQzFELDZCQUE2QixFQUFFLHdCQUF3QjtJQUN2RCx3Q0FBd0MsRUFDcEMsa0NBQWtDO0lBQ3RDLCtCQUErQixFQUFFLDBCQUEwQjtJQUMzRCwyQ0FBMkMsRUFDdkMsbUNBQW1DO0lBQ3ZDLCtDQUErQyxFQUMzQyx5Q0FBeUM7SUFDN0MsMEJBQTBCLEVBQUUsc0JBQXNCO0NBQ3JELENBQUM7QUFFRixlQUFlLFFBQVEsQ0FBQyJ9
|