@darraghor/eslint-plugin-nestjs-typed 6.9.18 → 6.10.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 +1 -0
- package/dist/configs/recommended.js +2 -1
- package/dist/rules/index.d.ts +1 -0
- package/dist/rules/index.js +3 -1
- package/dist/rules/sortModuleMetadataArrays/sortModuleMetadataArrays.d.ts +6 -0
- package/dist/rules/sortModuleMetadataArrays/sortModuleMetadataArrays.js +41 -2
- package/dist/rules/useInjectableProvidedToken/useInjectableProvidedToken.d.ts +2 -0
- package/dist/rules/useInjectableProvidedToken/useInjectableProvidedToken.js +90 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,6 +62,7 @@ Awesome! [Click here](https://github.com/darraghoriordan/eslint-plugin-nestjs-ty
|
|
|
62
62
|
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- |
|
|
63
63
|
| Nest Modules and Dependency Injection | [`provided-injected-should-match-factory-parameters`](./src/docs/rules/provided-injected-should-match-factory-parameters.md) | ✅ |
|
|
64
64
|
| | [`injectable-should-be-provided`](./src/docs/rules/injectable-should-be-provided.md) | ✅ |
|
|
65
|
+
| | [`use-injectable-provided-token`](./src/docs/rules/use-injectable-provided-token.md) | ✅ |
|
|
65
66
|
| | | |
|
|
66
67
|
| Nest Swagger | [`api-property-matches-property-optionality`](./src/docs/rules/api-property-matches-property-optionality.md) | ✅ |
|
|
67
68
|
| | [`controllers-should-supply-api-tags`](./src/docs/rules/controllers-should-supply-api-tags.md) | ✅ |
|
|
@@ -22,9 +22,10 @@ export const rules = {
|
|
|
22
22
|
"@darraghor/nestjs-typed/api-method-should-specify-api-operation": "off",
|
|
23
23
|
"@darraghor/nestjs-typed/sort-module-metadata-arrays": "off",
|
|
24
24
|
"@darraghor/nestjs-typed/no-duplicate-decorators": "error",
|
|
25
|
+
"@darraghor/nestjs-typed/use-injectable-provided-token": "error",
|
|
25
26
|
};
|
|
26
27
|
export default {
|
|
27
28
|
extends: ["./configs/base"],
|
|
28
29
|
rules,
|
|
29
30
|
};
|
|
30
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlncy9yZWNvbW1lbmRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQWdDO0lBQzlDLDJFQUEyRSxFQUN2RSxPQUFPO0lBQ1gsdURBQXVELEVBQUU7UUFDckQsT0FBTztRQUNQO1lBQ0ksR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDO1lBQ3BCLGVBQWUsRUFBRSxDQUFDLGNBQWMsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDO1NBQ3hEO0tBQ0o7SUFDRCxtRUFBbUUsRUFDL0QsT0FBTztJQUNYLGdFQUFnRSxFQUFFLE9BQU87SUFDekUsNERBQTRELEVBQUUsT0FBTztJQUNyRSwwREFBMEQsRUFBRSxPQUFPO0lBQ25FLHVFQUF1RSxFQUNuRSxPQUFPO0lBQ1gsOERBQThELEVBQUUsT0FBTztJQUN2RSxrRUFBa0UsRUFBRSxPQUFPO0lBQzNFLCtFQUErRSxFQUMzRSxPQUFPO0lBQ1gsa0VBQWtFLEVBQUUsT0FBTztJQUMzRSx3REFBd0QsRUFBRSxPQUFPO0lBQ2pFLDhEQUE4RCxFQUFFLE9BQU87SUFDdkUsdURBQXVELEVBQUUsS0FBSztJQUM5RCxpRUFBaUUsRUFBRSxLQUFLO0lBQ3hFLHFEQUFxRCxFQUFFLEtBQUs7SUFDNUQsaURBQWlELEVBQUUsT0FBTztJQUMxRCx1REFBdUQsRUFBRSxPQUFPO0NBQ25FLENBQUM7QUFDRixlQUFlO0lBQ1gsT0FBTyxFQUFFLENBQUMsZ0JBQWdCLENBQUM7SUFDM0IsS0FBSztDQUNSLENBQUMifQ==
|
package/dist/rules/index.d.ts
CHANGED
|
@@ -21,5 +21,6 @@ declare const allRules: {
|
|
|
21
21
|
"all-properties-are-whitelisted": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing-property-decorator", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
22
22
|
"api-methods-should-be-guarded": import("@typescript-eslint/utils/ts-eslint").RuleModule<"apiMethodsShouldBeGuarded", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
23
23
|
"sort-module-metadata-arrays": import("@typescript-eslint/utils/ts-eslint").RuleModule<"moduleMetadataArraysAreSorted", import("./sortModuleMetadataArrays/sortModuleMetadataArrays.js").RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
24
|
+
"use-injectable-provided-token": import("@typescript-eslint/utils/ts-eslint").RuleModule<"useInjectableProvidedToken", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
24
25
|
};
|
|
25
26
|
export default allRules;
|
package/dist/rules/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import apiMethodsShouldBeGuarded from "./apiMethodsShouldBeGuarded/apiMethodsSho
|
|
|
15
15
|
import apiMethodsShouldSpecifyApiOperation from "./apiMethodsShouldSpecifyApiOperation/apiMethodsShouldSpecifyApiOperation.js";
|
|
16
16
|
import sortModuleMetadataArrays from "./sortModuleMetadataArrays/sortModuleMetadataArrays.js";
|
|
17
17
|
import noDuplicateDecorators from "./noDuplicateDecorators/noDuplicateDecorators.js";
|
|
18
|
+
import useInjectableProvidedToken from "./useInjectableProvidedToken/useInjectableProvidedToken.js";
|
|
18
19
|
const allRules = {
|
|
19
20
|
"all-properties-have-explicit-defined": allPropertiesHaveExplicitDefined,
|
|
20
21
|
"api-property-matches-property-optionality": apiPropertyMatchesPropertyOptionality,
|
|
@@ -33,6 +34,7 @@ const allRules = {
|
|
|
33
34
|
"all-properties-are-whitelisted": allPropertiesAreWhitelisted,
|
|
34
35
|
"api-methods-should-be-guarded": apiMethodsShouldBeGuarded,
|
|
35
36
|
"sort-module-metadata-arrays": sortModuleMetadataArrays,
|
|
37
|
+
"use-injectable-provided-token": useInjectableProvidedToken,
|
|
36
38
|
};
|
|
37
39
|
export default allRules;
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTywwQkFBMEIsTUFBTSw2REFBNkQsQ0FBQztBQUNyRyxPQUFPLDRDQUE0QyxNQUFNLDRFQUE0RSxDQUFDO0FBQ3RJLE9BQU8scUNBQXFDLE1BQU0sa0ZBQWtGLENBQUM7QUFDckksT0FBTyw2QkFBNkIsTUFBTSxrRUFBa0UsQ0FBQztBQUM3RyxPQUFPLGtDQUFrQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzVILE9BQU8sNEJBQTRCLE1BQU0sZ0VBQWdFLENBQUM7QUFDMUcsT0FBTyx1Q0FBdUMsTUFBTSxzRkFBc0YsQ0FBQztBQUMzSSxPQUFPLGdDQUFnQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzFILE9BQU8sdUNBQXVDLE1BQU0sOEVBQThFLENBQUM7QUFDbkksT0FBTyxtQ0FBbUMsTUFBTSxpRkFBaUYsQ0FBQztBQUNsSSxPQUFPLGtDQUFrQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzVILE9BQU8sMkJBQTJCLE1BQU0sOERBQThELENBQUM7QUFDdkcsT0FBTyxnQ0FBZ0MsTUFBTSx3RUFBd0UsQ0FBQztBQUN0SCxPQUFPLHlCQUF5QixNQUFNLDBEQUEwRCxDQUFDO0FBQ2pHLE9BQU8sbUNBQW1DLE1BQU0sOEVBQThFLENBQUM7QUFDL0gsT0FBTyx3QkFBd0IsTUFBTSx3REFBd0QsQ0FBQztBQUM5RixPQUFPLHFCQUFxQixNQUFNLGtEQUFrRCxDQUFDO0FBQ3JGLE9BQU8sMEJBQTBCLE1BQU0sNERBQTRELENBQUM7QUFDcEcsTUFBTSxRQUFRLEdBQUc7SUFDYixzQ0FBc0MsRUFBRSxnQ0FBZ0M7SUFDeEUsMkNBQTJDLEVBQ3ZDLHFDQUFxQztJQUN6QywrQkFBK0IsRUFBRSwwQkFBMEI7SUFDM0QseUJBQXlCLEVBQUUscUJBQXFCO0lBQ2hELG1EQUFtRCxFQUMvQyw0Q0FBNEM7SUFDaEQsb0NBQW9DLEVBQUUsNkJBQTZCO0lBQ25FLHdDQUF3QyxFQUNwQyxrQ0FBa0M7SUFDdEMseUNBQXlDLEVBQ3JDLG1DQUFtQztJQUN2QyxrQ0FBa0MsRUFBRSw0QkFBNEI7SUFDaEUsK0NBQStDLEVBQzNDLHVDQUF1QztJQUMzQyxzQ0FBc0MsRUFBRSxnQ0FBZ0M7SUFDeEUsMENBQTBDLEVBQ3RDLHVDQUF1QztJQUMzQyx1REFBdUQsRUFDbkQsbUNBQW1DO0lBQ3ZDLDBDQUEwQyxFQUN0QyxrQ0FBa0M7SUFDdEMsZ0NBQWdDLEVBQUUsMkJBQTJCO0lBQzdELCtCQUErQixFQUFFLHlCQUF5QjtJQUMxRCw2QkFBNkIsRUFBRSx3QkFBd0I7SUFDdkQsK0JBQStCLEVBQUUsMEJBQTBCO0NBQzlELENBQUM7QUFFRixlQUFlLFFBQVEsQ0FBQyJ9
|
|
@@ -7,5 +7,11 @@ export type RuleOptions = [
|
|
|
7
7
|
export type ValidModuleNodeTypes = TSESTree.Identifier | TSESTree.CallExpression;
|
|
8
8
|
export declare const isValidModuleMetaPropertyType: (node: TSESTree.Expression | TSESTree.SpreadElement | null) => node is ValidModuleNodeTypes;
|
|
9
9
|
export declare const getRelevantNodeName: (node: TSESTree.Node) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Checks if an ArrayExpression is the `inject` array of a factory provider.
|
|
12
|
+
* Factory providers have both `useFactory` and `inject` properties,
|
|
13
|
+
* and the order of `inject` must match the factory function parameters.
|
|
14
|
+
*/
|
|
15
|
+
export declare const isFactoryProviderInjectArray: (node: TSESTree.ArrayExpression) => boolean;
|
|
10
16
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"moduleMetadataArraysAreSorted", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
11
17
|
export default _default;
|
|
@@ -25,6 +25,39 @@ export const getRelevantNodeName = (node) => {
|
|
|
25
25
|
}
|
|
26
26
|
return currentName;
|
|
27
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Checks if an ArrayExpression is the `inject` array of a factory provider.
|
|
30
|
+
* Factory providers have both `useFactory` and `inject` properties,
|
|
31
|
+
* and the order of `inject` must match the factory function parameters.
|
|
32
|
+
*/
|
|
33
|
+
export const isFactoryProviderInjectArray = (node) => {
|
|
34
|
+
// Check if this array is a direct child of a Property
|
|
35
|
+
if (!node.parent || node.parent.type !== TSESTree.AST_NODE_TYPES.Property) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const property = node.parent;
|
|
39
|
+
// Check if this Property has the key "inject"
|
|
40
|
+
if (property.key.type !== TSESTree.AST_NODE_TYPES.Identifier ||
|
|
41
|
+
property.key.name !== "inject") {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
// Check if the parent of this Property is an ObjectExpression
|
|
45
|
+
if (!property.parent ||
|
|
46
|
+
property.parent.type !== TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const objectExpression = property.parent;
|
|
50
|
+
// Check if this ObjectExpression has a `useFactory` property
|
|
51
|
+
// If it does, this is a factory provider and the inject array should NOT be sorted
|
|
52
|
+
// Note: In NestJS, `useFactory` and `inject` are always identifier properties,
|
|
53
|
+
// not computed properties or method definitions, so we only check for identifiers
|
|
54
|
+
const hasUseFactory = objectExpression.properties.some((property) => {
|
|
55
|
+
return (property.type === TSESTree.AST_NODE_TYPES.Property &&
|
|
56
|
+
property.key.type === TSESTree.AST_NODE_TYPES.Identifier &&
|
|
57
|
+
property.key.name === "useFactory");
|
|
58
|
+
});
|
|
59
|
+
return hasUseFactory;
|
|
60
|
+
};
|
|
28
61
|
const defaultLocaleOptions = [
|
|
29
62
|
{
|
|
30
63
|
locale: DEFAULT_LOCALE,
|
|
@@ -67,7 +100,13 @@ export default createRule({
|
|
|
67
100
|
const { locale } = context.options[0];
|
|
68
101
|
const sourceCode = context.sourceCode;
|
|
69
102
|
return {
|
|
70
|
-
[`${MODULE_CLASS_DECORATOR} Property > ArrayExpression`](
|
|
103
|
+
[`${MODULE_CLASS_DECORATOR} Property > ArrayExpression`](node) {
|
|
104
|
+
// Skip sorting if this is a factory provider's inject array
|
|
105
|
+
// The order must match the useFactory function parameters
|
|
106
|
+
if (isFactoryProviderInjectArray(node)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const { elements } = node;
|
|
71
110
|
const unorderedNodes = elements
|
|
72
111
|
// nestjs modules use identifiers and call expressions
|
|
73
112
|
// can modify this later
|
|
@@ -93,4 +132,4 @@ export default createRule({
|
|
|
93
132
|
};
|
|
94
133
|
},
|
|
95
134
|
});
|
|
96
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
135
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ydE1vZHVsZU1ldGFkYXRhQXJyYXlzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3J1bGVzL3NvcnRNb2R1bGVNZXRhZGF0YUFycmF5cy9zb3J0TW9kdWxlTWV0YWRhdGFBcnJheXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUN6RSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFFbEQsMklBQTJJO0FBRTNJLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQztBQVkvQixNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxDQUN6QyxJQUF5RCxFQUM3QixFQUFFO0lBQzlCLCtEQUErRDtJQUMvRCxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUk7UUFDVixRQUFRLENBQUMsYUFBYSxDQUFDO1lBQ25CLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVTtZQUNsQyxRQUFRLENBQUMsY0FBYyxDQUFDLGNBQWM7WUFDdEMsOERBQThEO1NBQ2pFLENBQUMsQ0FBUSxDQUFDLENBQUMseUJBQXlCO0FBQzdDLENBQUMsQ0FBQztBQUNGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsSUFBbUIsRUFBRSxFQUFFO0lBQ3ZELElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQztJQUVyQixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNuRCxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztJQUM1QixDQUFDO0lBQ0QsSUFDSSxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxjQUFjLENBQUMsY0FBYztRQUNwRCxJ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
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
import { createRule } from "../../utils/createRule.js";
|
|
3
|
+
// These are special NestJS tokens that cannot be used with app.get() or @Inject()
|
|
4
|
+
// because they are applied globally and don't work like regular providers
|
|
5
|
+
const FORBIDDEN_APP_TOKENS = new Set([
|
|
6
|
+
"APP_GUARD",
|
|
7
|
+
"APP_PIPE",
|
|
8
|
+
"APP_FILTER",
|
|
9
|
+
"APP_INTERCEPTOR",
|
|
10
|
+
]);
|
|
11
|
+
/**
|
|
12
|
+
* Checks if a node is an identifier with one of the forbidden APP_* token names
|
|
13
|
+
*/
|
|
14
|
+
const isForbiddenAppToken = (node) => {
|
|
15
|
+
if (!node) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (node.type === TSESTree.AST_NODE_TYPES.Identifier) {
|
|
19
|
+
return FORBIDDEN_APP_TOKENS.has(node.name);
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
23
|
+
const rule = createRule({
|
|
24
|
+
name: "use-injectable-provided-token",
|
|
25
|
+
meta: {
|
|
26
|
+
docs: {
|
|
27
|
+
description: "Prevents using APP_GUARD, APP_PIPE, APP_FILTER, or APP_INTERCEPTOR tokens with app.get() or @Inject() as these are global providers that cannot be retrieved this way.",
|
|
28
|
+
},
|
|
29
|
+
messages: {
|
|
30
|
+
useInjectableProvidedToken: "Cannot use {{tokenName}} with {{method}}. These tokens are for global providers and cannot be retrieved or injected directly. Use them only in module provider arrays.",
|
|
31
|
+
},
|
|
32
|
+
schema: [],
|
|
33
|
+
hasSuggestions: false,
|
|
34
|
+
type: "problem",
|
|
35
|
+
},
|
|
36
|
+
defaultOptions: [],
|
|
37
|
+
create(context) {
|
|
38
|
+
return {
|
|
39
|
+
// Check for app.get(APP_*) calls
|
|
40
|
+
CallExpression(node) {
|
|
41
|
+
// Check if this is a member expression like app.get()
|
|
42
|
+
if (node.callee.type ===
|
|
43
|
+
TSESTree.AST_NODE_TYPES.MemberExpression) {
|
|
44
|
+
const memberExpression = node.callee;
|
|
45
|
+
// Check if the method is 'get'
|
|
46
|
+
if (memberExpression.property.type ===
|
|
47
|
+
TSESTree.AST_NODE_TYPES.Identifier &&
|
|
48
|
+
memberExpression.property.name === "get") {
|
|
49
|
+
// Check if the first argument is one of the forbidden tokens
|
|
50
|
+
const firstArgument = node.arguments[0];
|
|
51
|
+
if (isForbiddenAppToken(firstArgument)) {
|
|
52
|
+
context.report({
|
|
53
|
+
node: firstArgument,
|
|
54
|
+
messageId: "useInjectableProvidedToken",
|
|
55
|
+
data: {
|
|
56
|
+
tokenName: firstArgument.name,
|
|
57
|
+
method: "app.get()",
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
// Check for @Inject(APP_*) decorators
|
|
65
|
+
Decorator(node) {
|
|
66
|
+
// Check if this is an @Inject decorator
|
|
67
|
+
if (node.expression.type ===
|
|
68
|
+
TSESTree.AST_NODE_TYPES.CallExpression &&
|
|
69
|
+
node.expression.callee.type ===
|
|
70
|
+
TSESTree.AST_NODE_TYPES.Identifier &&
|
|
71
|
+
node.expression.callee.name === "Inject") {
|
|
72
|
+
// Check if the first argument is one of the forbidden tokens
|
|
73
|
+
const firstArgument = node.expression.arguments[0];
|
|
74
|
+
if (isForbiddenAppToken(firstArgument)) {
|
|
75
|
+
context.report({
|
|
76
|
+
node: firstArgument,
|
|
77
|
+
messageId: "useInjectableProvidedToken",
|
|
78
|
+
data: {
|
|
79
|
+
tokenName: firstArgument.name,
|
|
80
|
+
method: "@Inject()",
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
export default rule;
|
|
90
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlSW5qZWN0YWJsZVByb3ZpZGVkVG9rZW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvdXNlSW5qZWN0YWJsZVByb3ZpZGVkVG9rZW4vdXNlSW5qZWN0YWJsZVByb3ZpZGVkVG9rZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUVyRCxrRkFBa0Y7QUFDbEYsMEVBQTBFO0FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDakMsV0FBVztJQUNYLFVBQVU7SUFDVixZQUFZO0lBQ1osaUJBQWlCO0NBQ3BCLENBQUMsQ0FBQztBQUVIOztHQUVHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLElBQStCLEVBQVcsRUFBRTtJQUNyRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbkQsT0FBTyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDLENBQUM7QUFFRixNQUFNLElBQUksR0FBRyxVQUFVLENBQW1DO0lBQ3RELElBQUksRUFBRSwrQkFBK0I7SUFDckMsSUFBSSxFQUFFO1FBQ0YsSUFBSSxFQUFFO1lBQ0YsV0FBVyxFQUNQLHdLQUF3SztTQUMvSztRQUNELFFBQVEsRUFBRTtZQUNOLDBCQUEwQixFQUN0Qix3S0FBd0s7U0FDL0s7UUFDRCxNQUFNLEVBQUUsRUFBRTtRQUNWLGNBQWMsRUFBRSxLQUFLO1FBQ3JCLElBQUksRUFBRSxTQUFTO0tBQ2xCO0lBQ0QsY0FBYyxFQUFFLEVBQUU7SUFDbEIsTUFBTSxDQUFDLE9BQU87UUFDVixPQUFPO1lBQ0gsaUNBQWlDO1lBQ2pDLGNBQWMsQ0FBQyxJQUE2QjtnQkFDeEMsc0RBQXNEO2dCQUN0RCxJQUNJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDaEIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFDMUMsQ0FBQztvQkFDQyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7b0JBRXJDLCtCQUErQjtvQkFDL0IsSUFDSSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsSUFBSTt3QkFDMUIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxVQUFVO3dCQUN0QyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLEtBQUssRUFDMUMsQ0FBQzt3QkFDQyw2REFBNkQ7d0JBQzdELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3hDLElBQUksbUJBQW1CLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQzs0QkFDckMsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQ0FDWCxJQUFJLEVBQUUsYUFBYTtnQ0FDbkIsU0FBUyxFQUFFLDRCQUE0QjtnQ0FDdkMsSUFBSSxFQUFFO29DQUNGLFNBQVMsRUFDTCxhQUNILENBQUMsSUFBSTtvQ0FDTixNQUFNLEVBQUUsV0FBVztpQ0FDdEI7NkJBQ0osQ0FBQyxDQUFDO3dCQUNQLENBQUM7b0JBQ0wsQ0FBQztnQkFDTCxDQUFDO1lBQ0wsQ0FBQztZQUVELHNDQUFzQztZQUN0QyxTQUFTLENBQUMsSUFBd0I7Z0JBQzlCLHdDQUF3QztnQkFDeEMsSUFDSSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUk7b0JBQ2hCLFFBQVEsQ0FBQyxjQUFjLENBQUMsY0FBYztvQkFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSTt3QkFDdkIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxVQUFVO29CQUN0QyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUMxQyxDQUFDO29CQUNDLDZEQUE2RDtvQkFDN0QsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ25ELElBQUksbUJBQW1CLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQzt3QkFDckMsT0FBTyxDQUFDLE1BQU0sQ0FBQzs0QkFDWCxJQUFJLEVBQUUsYUFBYTs0QkFDbkIsU0FBUyxFQUFFLDRCQUE0Qjs0QkFDdkMsSUFBSSxFQUFFO2dDQUNGLFNBQVMsRUFDTCxhQUNILENBQUMsSUFBSTtnQ0FDTixNQUFNLEVBQUUsV0FBVzs2QkFDdEI7eUJBQ0osQ0FBQyxDQUFDO29CQUNQLENBQUM7Z0JBQ0wsQ0FBQztZQUNMLENBQUM7U0FDSixDQUFDO0lBQ04sQ0FBQztDQUNKLENBQUMsQ0FBQztBQUVILGVBQWUsSUFBSSxDQUFDIn0=
|