parse-server 9.5.2-alpha.1 → 9.5.2-alpha.2
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/lib/Config.js +28 -2
- package/lib/GraphQL/ParseGraphQLServer.js +3 -2
- package/lib/GraphQL/helpers/queryComplexity.js +105 -0
- package/lib/Options/Definitions.js +40 -1
- package/lib/Options/docs.js +11 -1
- package/lib/Options/index.js +1 -1
- package/lib/RestQuery.js +63 -5
- package/lib/Security/CheckGroups/CheckGroupServerConfig.js +15 -1
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.calculateQueryComplexity = calculateQueryComplexity;
|
|
7
|
+
exports.createComplexityValidationPlugin = createComplexityValidationPlugin;
|
|
8
|
+
var _graphql = require("graphql");
|
|
9
|
+
var _logger = _interopRequireDefault(require("../../logger"));
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
function calculateQueryComplexity(operation, fragments) {
|
|
12
|
+
let maxDepth = 0;
|
|
13
|
+
let totalFields = 0;
|
|
14
|
+
function visitSelectionSet(selectionSet, depth, visitedFragments) {
|
|
15
|
+
if (!selectionSet) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
for (const selection of selectionSet.selections) {
|
|
19
|
+
if (selection.kind === 'Field') {
|
|
20
|
+
totalFields++;
|
|
21
|
+
const newDepth = depth + 1;
|
|
22
|
+
if (newDepth > maxDepth) {
|
|
23
|
+
maxDepth = newDepth;
|
|
24
|
+
}
|
|
25
|
+
if (selection.selectionSet) {
|
|
26
|
+
visitSelectionSet(selection.selectionSet, newDepth, visitedFragments);
|
|
27
|
+
}
|
|
28
|
+
} else if (selection.kind === 'InlineFragment') {
|
|
29
|
+
visitSelectionSet(selection.selectionSet, depth, visitedFragments);
|
|
30
|
+
} else if (selection.kind === 'FragmentSpread') {
|
|
31
|
+
const name = selection.name.value;
|
|
32
|
+
if (visitedFragments.has(name)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const fragment = fragments[name];
|
|
36
|
+
if (fragment) {
|
|
37
|
+
const branchVisited = new Set(visitedFragments);
|
|
38
|
+
branchVisited.add(name);
|
|
39
|
+
visitSelectionSet(fragment.selectionSet, depth, branchVisited);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
visitSelectionSet(operation.selectionSet, 0, new Set());
|
|
45
|
+
return {
|
|
46
|
+
depth: maxDepth,
|
|
47
|
+
fields: totalFields
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function createComplexityValidationPlugin(getConfig) {
|
|
51
|
+
return {
|
|
52
|
+
requestDidStart: requestContext => ({
|
|
53
|
+
didResolveOperation: async () => {
|
|
54
|
+
const auth = requestContext.contextValue?.auth;
|
|
55
|
+
if (auth?.isMaster || auth?.isMaintenance) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const config = getConfig();
|
|
59
|
+
if (!config) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const {
|
|
63
|
+
graphQLDepth,
|
|
64
|
+
graphQLFields
|
|
65
|
+
} = config;
|
|
66
|
+
if (graphQLDepth === -1 && graphQLFields === -1) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const fragments = {};
|
|
70
|
+
for (const definition of requestContext.document.definitions) {
|
|
71
|
+
if (definition.kind === 'FragmentDefinition') {
|
|
72
|
+
fragments[definition.name.value] = definition;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const {
|
|
76
|
+
depth,
|
|
77
|
+
fields
|
|
78
|
+
} = calculateQueryComplexity(requestContext.operation, fragments);
|
|
79
|
+
if (graphQLDepth !== -1 && depth > graphQLDepth) {
|
|
80
|
+
const message = `GraphQL query depth of ${depth} exceeds maximum allowed depth of ${graphQLDepth}`;
|
|
81
|
+
_logger.default.warn(message);
|
|
82
|
+
throw new _graphql.GraphQLError(message, {
|
|
83
|
+
extensions: {
|
|
84
|
+
http: {
|
|
85
|
+
status: 400
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (graphQLFields !== -1 && fields > graphQLFields) {
|
|
91
|
+
const message = `Number of GraphQL fields (${fields}) exceeds maximum allowed (${graphQLFields})`;
|
|
92
|
+
_logger.default.warn(message);
|
|
93
|
+
throw new _graphql.GraphQLError(message, {
|
|
94
|
+
extensions: {
|
|
95
|
+
http: {
|
|
96
|
+
status: 400
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZ3JhcGhxbCIsInJlcXVpcmUiLCJfbG9nZ2VyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImNhbGN1bGF0ZVF1ZXJ5Q29tcGxleGl0eSIsIm9wZXJhdGlvbiIsImZyYWdtZW50cyIsIm1heERlcHRoIiwidG90YWxGaWVsZHMiLCJ2aXNpdFNlbGVjdGlvblNldCIsInNlbGVjdGlvblNldCIsImRlcHRoIiwidmlzaXRlZEZyYWdtZW50cyIsInNlbGVjdGlvbiIsInNlbGVjdGlvbnMiLCJraW5kIiwibmV3RGVwdGgiLCJuYW1lIiwidmFsdWUiLCJoYXMiLCJmcmFnbWVudCIsImJyYW5jaFZpc2l0ZWQiLCJTZXQiLCJhZGQiLCJmaWVsZHMiLCJjcmVhdGVDb21wbGV4aXR5VmFsaWRhdGlvblBsdWdpbiIsImdldENvbmZpZyIsInJlcXVlc3REaWRTdGFydCIsInJlcXVlc3RDb250ZXh0IiwiZGlkUmVzb2x2ZU9wZXJhdGlvbiIsImF1dGgiLCJjb250ZXh0VmFsdWUiLCJpc01hc3RlciIsImlzTWFpbnRlbmFuY2UiLCJjb25maWciLCJncmFwaFFMRGVwdGgiLCJncmFwaFFMRmllbGRzIiwiZGVmaW5pdGlvbiIsImRvY3VtZW50IiwiZGVmaW5pdGlvbnMiLCJtZXNzYWdlIiwibG9nZ2VyIiwid2FybiIsIkdyYXBoUUxFcnJvciIsImV4dGVuc2lvbnMiLCJodHRwIiwic3RhdHVzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0dyYXBoUUwvaGVscGVycy9xdWVyeUNvbXBsZXhpdHkuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTEVycm9yIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uLy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZVF1ZXJ5Q29tcGxleGl0eShvcGVyYXRpb24sIGZyYWdtZW50cykge1xuICBsZXQgbWF4RGVwdGggPSAwO1xuICBsZXQgdG90YWxGaWVsZHMgPSAwO1xuXG4gIGZ1bmN0aW9uIHZpc2l0U2VsZWN0aW9uU2V0KHNlbGVjdGlvblNldCwgZGVwdGgsIHZpc2l0ZWRGcmFnbWVudHMpIHtcbiAgICBpZiAoIXNlbGVjdGlvblNldCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHNlbGVjdGlvbiBvZiBzZWxlY3Rpb25TZXQuc2VsZWN0aW9ucykge1xuICAgICAgaWYgKHNlbGVjdGlvbi5raW5kID09PSAnRmllbGQnKSB7XG4gICAgICAgIHRvdGFsRmllbGRzKys7XG4gICAgICAgIGNvbnN0IG5ld0RlcHRoID0gZGVwdGggKyAxO1xuICAgICAgICBpZiAobmV3RGVwdGggPiBtYXhEZXB0aCkge1xuICAgICAgICAgIG1heERlcHRoID0gbmV3RGVwdGg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbGVjdGlvbi5zZWxlY3Rpb25TZXQpIHtcbiAgICAgICAgICB2aXNpdFNlbGVjdGlvblNldChzZWxlY3Rpb24uc2VsZWN0aW9uU2V0LCBuZXdEZXB0aCwgdmlzaXRlZEZyYWdtZW50cyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc2VsZWN0aW9uLmtpbmQgPT09ICdJbmxpbmVGcmFnbWVudCcpIHtcbiAgICAgICAgdmlzaXRTZWxlY3Rpb25TZXQoc2VsZWN0aW9uLnNlbGVjdGlvblNldCwgZGVwdGgsIHZpc2l0ZWRGcmFnbWVudHMpO1xuICAgICAgfSBlbHNlIGlmIChzZWxlY3Rpb24ua2luZCA9PT0gJ0ZyYWdtZW50U3ByZWFkJykge1xuICAgICAgICBjb25zdCBuYW1lID0gc2VsZWN0aW9uLm5hbWUudmFsdWU7XG4gICAgICAgIGlmICh2aXNpdGVkRnJhZ21lbnRzLmhhcyhuYW1lKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZyYWdtZW50ID0gZnJhZ21lbnRzW25hbWVdO1xuICAgICAgICBpZiAoZnJhZ21lbnQpIHtcbiAgICAgICAgICBjb25zdCBicmFuY2hWaXNpdGVkID0gbmV3IFNldCh2aXNpdGVkRnJhZ21lbnRzKTtcbiAgICAgICAgICBicmFuY2hWaXNpdGVkLmFkZChuYW1lKTtcbiAgICAgICAgICB2aXNpdFNlbGVjdGlvblNldChmcmFnbWVudC5zZWxlY3Rpb25TZXQsIGRlcHRoLCBicmFuY2hWaXNpdGVkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZpc2l0U2VsZWN0aW9uU2V0KG9wZXJhdGlvbi5zZWxlY3Rpb25TZXQsIDAsIG5ldyBTZXQoKSk7XG5cbiAgcmV0dXJuIHsgZGVwdGg6IG1heERlcHRoLCBmaWVsZHM6IHRvdGFsRmllbGRzIH07XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbXBsZXhpdHlWYWxpZGF0aW9uUGx1Z2luKGdldENvbmZpZykge1xuICByZXR1cm4ge1xuICAgIHJlcXVlc3REaWRTdGFydDogKHJlcXVlc3RDb250ZXh0KSA9PiAoe1xuICAgICAgZGlkUmVzb2x2ZU9wZXJhdGlvbjogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBhdXRoID0gcmVxdWVzdENvbnRleHQuY29udGV4dFZhbHVlPy5hdXRoO1xuICAgICAgICBpZiAoYXV0aD8uaXNNYXN0ZXIgfHwgYXV0aD8uaXNNYWludGVuYW5jZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgICAgICBpZiAoIWNvbmZpZykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgZ3JhcGhRTERlcHRoLCBncmFwaFFMRmllbGRzIH0gPSBjb25maWc7XG4gICAgICAgIGlmIChncmFwaFFMRGVwdGggPT09IC0xICYmIGdyYXBoUUxGaWVsZHMgPT09IC0xKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZnJhZ21lbnRzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgZGVmaW5pdGlvbiBvZiByZXF1ZXN0Q29udGV4dC5kb2N1bWVudC5kZWZpbml0aW9ucykge1xuICAgICAgICAgIGlmIChkZWZpbml0aW9uLmtpbmQgPT09ICdGcmFnbWVudERlZmluaXRpb24nKSB7XG4gICAgICAgICAgICBmcmFnbWVudHNbZGVmaW5pdGlvbi5uYW1lLnZhbHVlXSA9IGRlZmluaXRpb247XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyBkZXB0aCwgZmllbGRzIH0gPSBjYWxjdWxhdGVRdWVyeUNvbXBsZXhpdHkoXG4gICAgICAgICAgcmVxdWVzdENvbnRleHQub3BlcmF0aW9uLFxuICAgICAgICAgIGZyYWdtZW50c1xuICAgICAgICApO1xuXG4gICAgICAgIGlmIChncmFwaFFMRGVwdGggIT09IC0xICYmIGRlcHRoID4gZ3JhcGhRTERlcHRoKSB7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGBHcmFwaFFMIHF1ZXJ5IGRlcHRoIG9mICR7ZGVwdGh9IGV4Y2VlZHMgbWF4aW11bSBhbGxvd2VkIGRlcHRoIG9mICR7Z3JhcGhRTERlcHRofWA7XG4gICAgICAgICAgbG9nZ2VyLndhcm4obWVzc2FnZSk7XG4gICAgICAgICAgdGhyb3cgbmV3IEdyYXBoUUxFcnJvcihtZXNzYWdlLCB7XG4gICAgICAgICAgICBleHRlbnNpb25zOiB7XG4gICAgICAgICAgICAgIGh0dHA6IHsgc3RhdHVzOiA0MDAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZ3JhcGhRTEZpZWxkcyAhPT0gLTEgJiYgZmllbGRzID4gZ3JhcGhRTEZpZWxkcykge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBgTnVtYmVyIG9mIEdyYXBoUUwgZmllbGRzICgke2ZpZWxkc30pIGV4Y2VlZHMgbWF4aW11bSBhbGxvd2VkICgke2dyYXBoUUxGaWVsZHN9KWA7XG4gICAgICAgICAgbG9nZ2VyLndhcm4obWVzc2FnZSk7XG4gICAgICAgICAgdGhyb3cgbmV3IEdyYXBoUUxFcnJvcihtZXNzYWdlLCB7XG4gICAgICAgICAgICBleHRlbnNpb25zOiB7XG4gICAgICAgICAgICAgIGh0dHA6IHsgc3RhdHVzOiA0MDAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSksXG4gIH07XG59XG5cbmV4cG9ydCB7IGNhbGN1bGF0ZVF1ZXJ5Q29tcGxleGl0eSwgY3JlYXRlQ29tcGxleGl0eVZhbGlkYXRpb25QbHVnaW4gfTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLElBQUFBLFFBQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUFrQyxTQUFBRSx1QkFBQUMsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQUVsQyxTQUFTRyx3QkFBd0JBLENBQUNDLFNBQVMsRUFBRUMsU0FBUyxFQUFFO0VBQ3RELElBQUlDLFFBQVEsR0FBRyxDQUFDO0VBQ2hCLElBQUlDLFdBQVcsR0FBRyxDQUFDO0VBRW5CLFNBQVNDLGlCQUFpQkEsQ0FBQ0MsWUFBWSxFQUFFQyxLQUFLLEVBQUVDLGdCQUFnQixFQUFFO0lBQ2hFLElBQUksQ0FBQ0YsWUFBWSxFQUFFO01BQ2pCO0lBQ0Y7SUFDQSxLQUFLLE1BQU1HLFNBQVMsSUFBSUgsWUFBWSxDQUFDSSxVQUFVLEVBQUU7TUFDL0MsSUFBSUQsU0FBUyxDQUFDRSxJQUFJLEtBQUssT0FBTyxFQUFFO1FBQzlCUCxXQUFXLEVBQUU7UUFDYixNQUFNUSxRQUFRLEdBQUdMLEtBQUssR0FBRyxDQUFDO1FBQzFCLElBQUlLLFFBQVEsR0FBR1QsUUFBUSxFQUFFO1VBQ3ZCQSxRQUFRLEdBQUdTLFFBQVE7UUFDckI7UUFDQSxJQUFJSCxTQUFTLENBQUNILFlBQVksRUFBRTtVQUMxQkQsaUJBQWlCLENBQUNJLFNBQVMsQ0FBQ0gsWUFBWSxFQUFFTSxRQUFRLEVBQUVKLGdCQUFnQixDQUFDO1FBQ3ZFO01BQ0YsQ0FBQyxNQUFNLElBQUlDLFNBQVMsQ0FBQ0UsSUFBSSxLQUFLLGdCQUFnQixFQUFFO1FBQzlDTixpQkFBaUIsQ0FBQ0ksU0FBUyxDQUFDSCxZQUFZLEVBQUVDLEtBQUssRUFBRUMsZ0JBQWdCLENBQUM7TUFDcEUsQ0FBQyxNQUFNLElBQUlDLFNBQVMsQ0FBQ0UsSUFBSSxLQUFLLGdCQUFnQixFQUFFO1FBQzlDLE1BQU1FLElBQUksR0FBR0osU0FBUyxDQUFDSSxJQUFJLENBQUNDLEtBQUs7UUFDakMsSUFBSU4sZ0JBQWdCLENBQUNPLEdBQUcsQ0FBQ0YsSUFBSSxDQUFDLEVBQUU7VUFDOUI7UUFDRjtRQUNBLE1BQU1HLFFBQVEsR0FBR2QsU0FBUyxDQUFDVyxJQUFJLENBQUM7UUFDaEMsSUFBSUcsUUFBUSxFQUFFO1VBQ1osTUFBTUMsYUFBYSxHQUFHLElBQUlDLEdBQUcsQ0FBQ1YsZ0JBQWdCLENBQUM7VUFDL0NTLGFBQWEsQ0FBQ0UsR0FBRyxDQUFDTixJQUFJLENBQUM7VUFDdkJSLGlCQUFpQixDQUFDVyxRQUFRLENBQUNWLFlBQVksRUFBRUMsS0FBSyxFQUFFVSxhQUFhLENBQUM7UUFDaEU7TUFDRjtJQUNGO0VBQ0Y7RUFFQVosaUJBQWlCLENBQUNKLFNBQVMsQ0FBQ0ssWUFBWSxFQUFFLENBQUMsRUFBRSxJQUFJWSxHQUFHLENBQUMsQ0FBQyxDQUFDO0VBRXZELE9BQU87SUFBRVgsS0FBSyxFQUFFSixRQUFRO0lBQUVpQixNQUFNLEVBQUVoQjtFQUFZLENBQUM7QUFDakQ7QUFFQSxTQUFTaUIsZ0NBQWdDQSxDQUFDQyxTQUFTLEVBQUU7RUFDbkQsT0FBTztJQUNMQyxlQUFlLEVBQUdDLGNBQWMsS0FBTTtNQUNwQ0MsbUJBQW1CLEVBQUUsTUFBQUEsQ0FBQSxLQUFZO1FBQy9CLE1BQU1DLElBQUksR0FBR0YsY0FBYyxDQUFDRyxZQUFZLEVBQUVELElBQUk7UUFDOUMsSUFBSUEsSUFBSSxFQUFFRSxRQUFRLElBQUlGLElBQUksRUFBRUcsYUFBYSxFQUFFO1VBQ3pDO1FBQ0Y7UUFFQSxNQUFNQyxNQUFNLEdBQUdSLFNBQVMsQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQ1EsTUFBTSxFQUFFO1VBQ1g7UUFDRjtRQUVBLE1BQU07VUFBRUMsWUFBWTtVQUFFQztRQUFjLENBQUMsR0FBR0YsTUFBTTtRQUM5QyxJQUFJQyxZQUFZLEtBQUssQ0FBQyxDQUFDLElBQUlDLGFBQWEsS0FBSyxDQUFDLENBQUMsRUFBRTtVQUMvQztRQUNGO1FBRUEsTUFBTTlCLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFDcEIsS0FBSyxNQUFNK0IsVUFBVSxJQUFJVCxjQUFjLENBQUNVLFFBQVEsQ0FBQ0MsV0FBVyxFQUFFO1VBQzVELElBQUlGLFVBQVUsQ0FBQ3RCLElBQUksS0FBSyxvQkFBb0IsRUFBRTtZQUM1Q1QsU0FBUyxDQUFDK0IsVUFBVSxDQUFDcEIsSUFBSSxDQUFDQyxLQUFLLENBQUMsR0FBR21CLFVBQVU7VUFDL0M7UUFDRjtRQUVBLE1BQU07VUFBRTFCLEtBQUs7VUFBRWE7UUFBTyxDQUFDLEdBQUdwQix3QkFBd0IsQ0FDaER3QixjQUFjLENBQUN2QixTQUFTLEVBQ3hCQyxTQUNGLENBQUM7UUFFRCxJQUFJNkIsWUFBWSxLQUFLLENBQUMsQ0FBQyxJQUFJeEIsS0FBSyxHQUFHd0IsWUFBWSxFQUFFO1VBQy9DLE1BQU1LLE9BQU8sR0FBRywwQkFBMEI3QixLQUFLLHFDQUFxQ3dCLFlBQVksRUFBRTtVQUNsR00sZUFBTSxDQUFDQyxJQUFJLENBQUNGLE9BQU8sQ0FBQztVQUNwQixNQUFNLElBQUlHLHFCQUFZLENBQUNILE9BQU8sRUFBRTtZQUM5QkksVUFBVSxFQUFFO2NBQ1ZDLElBQUksRUFBRTtnQkFBRUMsTUFBTSxFQUFFO2NBQUk7WUFDdEI7VUFDRixDQUFDLENBQUM7UUFDSjtRQUVBLElBQUlWLGFBQWEsS0FBSyxDQUFDLENBQUMsSUFBSVosTUFBTSxHQUFHWSxhQUFhLEVBQUU7VUFDbEQsTUFBTUksT0FBTyxHQUFHLDZCQUE2QmhCLE1BQU0sOEJBQThCWSxhQUFhLEdBQUc7VUFDakdLLGVBQU0sQ0FBQ0MsSUFBSSxDQUFDRixPQUFPLENBQUM7VUFDcEIsTUFBTSxJQUFJRyxxQkFBWSxDQUFDSCxPQUFPLEVBQUU7WUFDOUJJLFVBQVUsRUFBRTtjQUNWQyxJQUFJLEVBQUU7Z0JBQUVDLE1BQU0sRUFBRTtjQUFJO1lBQ3RCO1VBQ0YsQ0FBQyxDQUFDO1FBQ0o7TUFDRjtJQUNGLENBQUM7RUFDSCxDQUFDO0FBQ0giLCJpZ25vcmVMaXN0IjpbXX0=
|