@beiguancyc/parse-server 9.9.0-ruixiang.1
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/LICENSE +176 -0
- package/NOTICE +10 -0
- package/README.md +1311 -0
- package/bin/parse-live-query-server +3 -0
- package/bin/parse-server +3 -0
- package/lib/AccountLockout.js +149 -0
- package/lib/Adapters/AdapterLoader.js +60 -0
- package/lib/Adapters/Analytics/AnalyticsAdapter.js +32 -0
- package/lib/Adapters/Auth/AuthAdapter.js +132 -0
- package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +119 -0
- package/lib/Adapters/Auth/OAuth1Client.js +204 -0
- package/lib/Adapters/Auth/apple.js +125 -0
- package/lib/Adapters/Auth/facebook.js +187 -0
- package/lib/Adapters/Auth/gcenter.js +217 -0
- package/lib/Adapters/Auth/github.js +125 -0
- package/lib/Adapters/Auth/google.js +122 -0
- package/lib/Adapters/Auth/gpgames.js +125 -0
- package/lib/Adapters/Auth/httpsRequest.js +41 -0
- package/lib/Adapters/Auth/index.js +248 -0
- package/lib/Adapters/Auth/instagram.js +118 -0
- package/lib/Adapters/Auth/janraincapture.js +85 -0
- package/lib/Adapters/Auth/janrainengage.js +57 -0
- package/lib/Adapters/Auth/keycloak.js +168 -0
- package/lib/Adapters/Auth/ldap.js +193 -0
- package/lib/Adapters/Auth/line.js +125 -0
- package/lib/Adapters/Auth/linkedin.js +117 -0
- package/lib/Adapters/Auth/meetup.js +44 -0
- package/lib/Adapters/Auth/mfa.js +334 -0
- package/lib/Adapters/Auth/microsoft.js +111 -0
- package/lib/Adapters/Auth/oauth2.js +115 -0
- package/lib/Adapters/Auth/phantauth.js +53 -0
- package/lib/Adapters/Auth/qq.js +113 -0
- package/lib/Adapters/Auth/spotify.js +115 -0
- package/lib/Adapters/Auth/twitter.js +197 -0
- package/lib/Adapters/Auth/utils.js +28 -0
- package/lib/Adapters/Auth/vkontakte.js +55 -0
- package/lib/Adapters/Auth/wechat.js +110 -0
- package/lib/Adapters/Auth/weibo.js +141 -0
- package/lib/Adapters/Cache/CacheAdapter.js +40 -0
- package/lib/Adapters/Cache/InMemoryCache.js +61 -0
- package/lib/Adapters/Cache/InMemoryCacheAdapter.js +34 -0
- package/lib/Adapters/Cache/LRUCache.js +35 -0
- package/lib/Adapters/Cache/NullCacheAdapter.js +26 -0
- package/lib/Adapters/Cache/RedisCacheAdapter.js +109 -0
- package/lib/Adapters/Cache/SchemaCache.js +25 -0
- package/lib/Adapters/Email/MailAdapter.js +32 -0
- package/lib/Adapters/Files/FilesAdapter.js +129 -0
- package/lib/Adapters/Files/GridFSBucketAdapter.js +280 -0
- package/lib/Adapters/Files/GridStoreAdapter.js +5 -0
- package/lib/Adapters/Logger/LoggerAdapter.js +27 -0
- package/lib/Adapters/Logger/WinstonLogger.js +107 -0
- package/lib/Adapters/Logger/WinstonLoggerAdapter.js +63 -0
- package/lib/Adapters/MessageQueue/EventEmitterMQ.js +55 -0
- package/lib/Adapters/PubSub/EventEmitterPubSub.js +53 -0
- package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
- package/lib/Adapters/PubSub/RedisPubSub.js +49 -0
- package/lib/Adapters/Push/PushAdapter.js +40 -0
- package/lib/Adapters/Storage/Mongo/MongoCollection.js +212 -0
- package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +334 -0
- package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +1047 -0
- package/lib/Adapters/Storage/Mongo/MongoTransform.js +1397 -0
- package/lib/Adapters/Storage/Postgres/PostgresClient.js +38 -0
- package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +73 -0
- package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +2409 -0
- package/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/array/add.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql +14 -0
- package/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql +14 -0
- package/lib/Adapters/Storage/Postgres/sql/array/contains.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/array/remove.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/index.js +32 -0
- package/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql +19 -0
- package/lib/Adapters/Storage/StorageAdapter.js +2 -0
- package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
- package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
- package/lib/Auth.js +687 -0
- package/lib/AuthDataLock.js +53 -0
- package/lib/ClientSDK.js +39 -0
- package/lib/Config.js +879 -0
- package/lib/Controllers/AdaptableController.js +72 -0
- package/lib/Controllers/AnalyticsController.js +43 -0
- package/lib/Controllers/CacheController.js +71 -0
- package/lib/Controllers/DatabaseController.js +1685 -0
- package/lib/Controllers/FilesController.js +122 -0
- package/lib/Controllers/HooksController.js +254 -0
- package/lib/Controllers/LiveQueryController.js +72 -0
- package/lib/Controllers/LoggerController.js +222 -0
- package/lib/Controllers/ParseGraphQLController.js +294 -0
- package/lib/Controllers/PushController.js +224 -0
- package/lib/Controllers/SchemaController.js +1563 -0
- package/lib/Controllers/UserController.js +364 -0
- package/lib/Controllers/index.js +251 -0
- package/lib/Controllers/types.js +2 -0
- package/lib/Deprecator/Deprecations.js +100 -0
- package/lib/Deprecator/Deprecator.js +140 -0
- package/lib/Error.js +50 -0
- package/lib/FileUrlValidator.js +69 -0
- package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
- package/lib/GraphQL/ParseGraphQLServer.js +241 -0
- package/lib/GraphQL/helpers/objectsMutations.js +30 -0
- package/lib/GraphQL/helpers/objectsQueries.js +246 -0
- package/lib/GraphQL/helpers/queryComplexity.js +138 -0
- package/lib/GraphQL/loaders/configMutations.js +87 -0
- package/lib/GraphQL/loaders/configQueries.js +79 -0
- package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
- package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
- package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1099 -0
- package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
- package/lib/GraphQL/loaders/filesMutations.js +107 -0
- package/lib/GraphQL/loaders/functionsMutations.js +77 -0
- package/lib/GraphQL/loaders/parseClassMutations.js +267 -0
- package/lib/GraphQL/loaders/parseClassQueries.js +126 -0
- package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
- package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
- package/lib/GraphQL/loaders/schemaMutations.js +161 -0
- package/lib/GraphQL/loaders/schemaQueries.js +80 -0
- package/lib/GraphQL/loaders/schemaTypes.js +341 -0
- package/lib/GraphQL/loaders/usersMutations.js +433 -0
- package/lib/GraphQL/loaders/usersQueries.js +90 -0
- package/lib/GraphQL/parseGraphQLUtils.js +71 -0
- package/lib/GraphQL/transformers/className.js +14 -0
- package/lib/GraphQL/transformers/constraintType.js +53 -0
- package/lib/GraphQL/transformers/inputType.js +51 -0
- package/lib/GraphQL/transformers/mutation.js +280 -0
- package/lib/GraphQL/transformers/outputType.js +51 -0
- package/lib/GraphQL/transformers/query.js +237 -0
- package/lib/GraphQL/transformers/schemaFields.js +99 -0
- package/lib/InstallationDedup.js +178 -0
- package/lib/KeyPromiseQueue.js +48 -0
- package/lib/LiveQuery/Client.js +90 -0
- package/lib/LiveQuery/Id.js +20 -0
- package/lib/LiveQuery/ParseCloudCodePublisher.js +54 -0
- package/lib/LiveQuery/ParseLiveQueryServer.js +1071 -0
- package/lib/LiveQuery/ParsePubSub.js +37 -0
- package/lib/LiveQuery/ParseWebSocketServer.js +66 -0
- package/lib/LiveQuery/QueryTools.js +443 -0
- package/lib/LiveQuery/RequestSchema.js +161 -0
- package/lib/LiveQuery/SessionTokenCache.js +51 -0
- package/lib/LiveQuery/Subscription.js +47 -0
- package/lib/LiveQuery/equalObjects.js +50 -0
- package/lib/Options/Definitions.js +1599 -0
- package/lib/Options/docs.js +389 -0
- package/lib/Options/index.js +12 -0
- package/lib/Options/parsers.js +89 -0
- package/lib/Page.js +44 -0
- package/lib/ParseMessageQueue.js +24 -0
- package/lib/ParseServer.js +632 -0
- package/lib/ParseServerRESTController.js +173 -0
- package/lib/PromiseRouter.js +208 -0
- package/lib/Push/PushQueue.js +67 -0
- package/lib/Push/PushWorker.js +101 -0
- package/lib/Push/utils.js +129 -0
- package/lib/RestQuery.js +1208 -0
- package/lib/RestWrite.js +1671 -0
- package/lib/Routers/AggregateRouter.js +150 -0
- package/lib/Routers/AnalyticsRouter.js +26 -0
- package/lib/Routers/AudiencesRouter.js +54 -0
- package/lib/Routers/ClassesRouter.js +191 -0
- package/lib/Routers/CloudCodeRouter.js +87 -0
- package/lib/Routers/FeaturesRouter.js +72 -0
- package/lib/Routers/FilesRouter.js +772 -0
- package/lib/Routers/FunctionsRouter.js +341 -0
- package/lib/Routers/GlobalConfigRouter.js +123 -0
- package/lib/Routers/GraphQLRouter.js +41 -0
- package/lib/Routers/HooksRouter.js +121 -0
- package/lib/Routers/IAPValidationRouter.js +113 -0
- package/lib/Routers/InstallationsRouter.js +46 -0
- package/lib/Routers/LogsRouter.js +57 -0
- package/lib/Routers/PagesRouter.js +676 -0
- package/lib/Routers/PurgeRouter.js +45 -0
- package/lib/Routers/PushRouter.js +75 -0
- package/lib/Routers/RolesRouter.js +33 -0
- package/lib/Routers/SchemasRouter.js +118 -0
- package/lib/Routers/SecurityRouter.js +34 -0
- package/lib/Routers/SessionsRouter.js +126 -0
- package/lib/Routers/UsersRouter.js +733 -0
- package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
- package/lib/SchemaMigrations/Migrations.js +30 -0
- package/lib/Security/Check.js +109 -0
- package/lib/Security/CheckGroup.js +44 -0
- package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
- package/lib/Security/CheckGroups/CheckGroupServerConfig.js +160 -0
- package/lib/Security/CheckGroups/CheckGroups.js +21 -0
- package/lib/Security/CheckRunner.js +213 -0
- package/lib/SharedRest.js +34 -0
- package/lib/StatusHandler.js +329 -0
- package/lib/TestUtils.js +87 -0
- package/lib/Utils.js +577 -0
- package/lib/batch.js +185 -0
- package/lib/cache.js +12 -0
- package/lib/cli/definitions/parse-live-query-server.js +9 -0
- package/lib/cli/definitions/parse-server.js +9 -0
- package/lib/cli/parse-live-query-server.js +14 -0
- package/lib/cli/parse-server.js +101 -0
- package/lib/cli/utils/commander.js +132 -0
- package/lib/cli/utils/runner.js +53 -0
- package/lib/cloud-code/Parse.Cloud.js +797 -0
- package/lib/cloud-code/Parse.Server.js +21 -0
- package/lib/cryptoUtils.js +54 -0
- package/lib/defaults.js +58 -0
- package/lib/deprecated.js +12 -0
- package/lib/index.js +89 -0
- package/lib/logger.js +40 -0
- package/lib/middlewares.js +810 -0
- package/lib/password.js +40 -0
- package/lib/request.js +175 -0
- package/lib/requiredParameter.js +11 -0
- package/lib/rest.js +264 -0
- package/lib/triggers.js +949 -0
- package/lib/vendor/README.md +8 -0
- package/lib/vendor/mongodbUrl.js +1012 -0
- package/package.json +172 -0
- package/postinstall.js +38 -0
- package/public/custom_json.html +17 -0
- package/public/custom_json.json +23 -0
- package/public/custom_page.html +15 -0
- package/public/de/email_verification_link_expired.html +24 -0
- package/public/de/email_verification_link_invalid.html +21 -0
- package/public/de/email_verification_send_fail.html +21 -0
- package/public/de/email_verification_send_success.html +19 -0
- package/public/de/email_verification_success.html +18 -0
- package/public/de/password_reset.html +65 -0
- package/public/de/password_reset_link_invalid.html +19 -0
- package/public/de/password_reset_success.html +18 -0
- package/public/de-AT/email_verification_link_expired.html +24 -0
- package/public/de-AT/email_verification_link_invalid.html +21 -0
- package/public/de-AT/email_verification_send_fail.html +21 -0
- package/public/de-AT/email_verification_send_success.html +19 -0
- package/public/de-AT/email_verification_success.html +18 -0
- package/public/de-AT/password_reset.html +65 -0
- package/public/de-AT/password_reset_link_invalid.html +19 -0
- package/public/de-AT/password_reset_success.html +18 -0
- package/public/email_verification_link_expired.html +24 -0
- package/public/email_verification_link_invalid.html +21 -0
- package/public/email_verification_send_fail.html +21 -0
- package/public/email_verification_send_success.html +19 -0
- package/public/email_verification_success.html +18 -0
- package/public/password_reset.html +65 -0
- package/public/password_reset_link_invalid.html +19 -0
- package/public/password_reset_success.html +18 -0
- package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
- package/types/@types/deepcopy/index.d.ts +5 -0
- package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
- package/types/Options/index.d.ts +320 -0
- package/types/ParseServer.d.ts +65 -0
- package/types/eslint.config.mjs +30 -0
- package/types/index.d.ts +21 -0
- package/types/logger.d.ts +2 -0
- package/types/tests.ts +44 -0
- package/types/tsconfig.json +24 -0
- package/views/choose_password +215 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ParsePubSub = void 0;
|
|
7
|
+
var _AdapterLoader = require("../Adapters/AdapterLoader");
|
|
8
|
+
var _EventEmitterPubSub = require("../Adapters/PubSub/EventEmitterPubSub");
|
|
9
|
+
var _RedisPubSub = require("../Adapters/PubSub/RedisPubSub");
|
|
10
|
+
const ParsePubSub = exports.ParsePubSub = {};
|
|
11
|
+
function useRedis(config) {
|
|
12
|
+
const redisURL = config.redisURL;
|
|
13
|
+
return typeof redisURL !== 'undefined' && redisURL !== '';
|
|
14
|
+
}
|
|
15
|
+
ParsePubSub.createPublisher = function (config) {
|
|
16
|
+
if (useRedis(config)) {
|
|
17
|
+
return _RedisPubSub.RedisPubSub.createPublisher(config);
|
|
18
|
+
} else {
|
|
19
|
+
const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config);
|
|
20
|
+
if (typeof adapter.createPublisher !== 'function') {
|
|
21
|
+
throw 'pubSubAdapter should have createPublisher()';
|
|
22
|
+
}
|
|
23
|
+
return adapter.createPublisher(config);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
ParsePubSub.createSubscriber = function (config) {
|
|
27
|
+
if (useRedis(config)) {
|
|
28
|
+
return _RedisPubSub.RedisPubSub.createSubscriber(config);
|
|
29
|
+
} else {
|
|
30
|
+
const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config);
|
|
31
|
+
if (typeof adapter.createSubscriber !== 'function') {
|
|
32
|
+
throw 'pubSubAdapter should have createSubscriber()';
|
|
33
|
+
}
|
|
34
|
+
return adapter.createSubscriber(config);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQWRhcHRlckxvYWRlciIsInJlcXVpcmUiLCJfRXZlbnRFbWl0dGVyUHViU3ViIiwiX1JlZGlzUHViU3ViIiwiUGFyc2VQdWJTdWIiLCJleHBvcnRzIiwidXNlUmVkaXMiLCJjb25maWciLCJyZWRpc1VSTCIsImNyZWF0ZVB1Ymxpc2hlciIsIlJlZGlzUHViU3ViIiwiYWRhcHRlciIsImxvYWRBZGFwdGVyIiwicHViU3ViQWRhcHRlciIsIkV2ZW50RW1pdHRlclB1YlN1YiIsImNyZWF0ZVN1YnNjcmliZXIiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvTGl2ZVF1ZXJ5L1BhcnNlUHViU3ViLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGxvYWRBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQWRhcHRlckxvYWRlcic7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXJQdWJTdWIgfSBmcm9tICcuLi9BZGFwdGVycy9QdWJTdWIvRXZlbnRFbWl0dGVyUHViU3ViJztcblxuaW1wb3J0IHsgUmVkaXNQdWJTdWIgfSBmcm9tICcuLi9BZGFwdGVycy9QdWJTdWIvUmVkaXNQdWJTdWInO1xuXG5jb25zdCBQYXJzZVB1YlN1YiA9IHt9O1xuXG5mdW5jdGlvbiB1c2VSZWRpcyhjb25maWc6IGFueSk6IGJvb2xlYW4ge1xuICBjb25zdCByZWRpc1VSTCA9IGNvbmZpZy5yZWRpc1VSTDtcbiAgcmV0dXJuIHR5cGVvZiByZWRpc1VSTCAhPT0gJ3VuZGVmaW5lZCcgJiYgcmVkaXNVUkwgIT09ICcnO1xufVxuXG5QYXJzZVB1YlN1Yi5jcmVhdGVQdWJsaXNoZXIgPSBmdW5jdGlvbiAoY29uZmlnOiBhbnkpOiBhbnkge1xuICBpZiAodXNlUmVkaXMoY29uZmlnKSkge1xuICAgIHJldHVybiBSZWRpc1B1YlN1Yi5jcmVhdGVQdWJsaXNoZXIoY29uZmlnKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBhZGFwdGVyID0gbG9hZEFkYXB0ZXIoY29uZmlnLnB1YlN1YkFkYXB0ZXIsIEV2ZW50RW1pdHRlclB1YlN1YiwgY29uZmlnKTtcbiAgICBpZiAodHlwZW9mIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVQdWJsaXNoZXIoKSc7XG4gICAgfVxuICAgIHJldHVybiBhZGFwdGVyLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9XG59O1xuXG5QYXJzZVB1YlN1Yi5jcmVhdGVTdWJzY3JpYmVyID0gZnVuY3Rpb24gKGNvbmZpZzogYW55KTogdm9pZCB7XG4gIGlmICh1c2VSZWRpcyhjb25maWcpKSB7XG4gICAgcmV0dXJuIFJlZGlzUHViU3ViLmNyZWF0ZVN1YnNjcmliZXIoY29uZmlnKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBhZGFwdGVyID0gbG9hZEFkYXB0ZXIoY29uZmlnLnB1YlN1YkFkYXB0ZXIsIEV2ZW50RW1pdHRlclB1YlN1YiwgY29uZmlnKTtcbiAgICBpZiAodHlwZW9mIGFkYXB0ZXIuY3JlYXRlU3Vic2NyaWJlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgJ3B1YlN1YkFkYXB0ZXIgc2hvdWxkIGhhdmUgY3JlYXRlU3Vic2NyaWJlcigpJztcbiAgICB9XG4gICAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICB9XG59O1xuXG5leHBvcnQgeyBQYXJzZVB1YlN1YiB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxjQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxtQkFBQSxHQUFBRCxPQUFBO0FBRUEsSUFBQUUsWUFBQSxHQUFBRixPQUFBO0FBRUEsTUFBTUcsV0FBVyxHQUFBQyxPQUFBLENBQUFELFdBQUEsR0FBRyxDQUFDLENBQUM7QUFFdEIsU0FBU0UsUUFBUUEsQ0FBQ0MsTUFBVyxFQUFXO0VBQ3RDLE1BQU1DLFFBQVEsR0FBR0QsTUFBTSxDQUFDQyxRQUFRO0VBQ2hDLE9BQU8sT0FBT0EsUUFBUSxLQUFLLFdBQVcsSUFBSUEsUUFBUSxLQUFLLEVBQUU7QUFDM0Q7QUFFQUosV0FBVyxDQUFDSyxlQUFlLEdBQUcsVUFBVUYsTUFBVyxFQUFPO0VBQ3hELElBQUlELFFBQVEsQ0FBQ0MsTUFBTSxDQUFDLEVBQUU7SUFDcEIsT0FBT0csd0JBQVcsQ0FBQ0QsZUFBZSxDQUFDRixNQUFNLENBQUM7RUFDNUMsQ0FBQyxNQUFNO0lBQ0wsTUFBTUksT0FBTyxHQUFHLElBQUFDLDBCQUFXLEVBQUNMLE1BQU0sQ0FBQ00sYUFBYSxFQUFFQyxzQ0FBa0IsRUFBRVAsTUFBTSxDQUFDO0lBQzdFLElBQUksT0FBT0ksT0FBTyxDQUFDRixlQUFlLEtBQUssVUFBVSxFQUFFO01BQ2pELE1BQU0sNkNBQTZDO0lBQ3JEO0lBQ0EsT0FBT0UsT0FBTyxDQUFDRixlQUFlLENBQUNGLE1BQU0sQ0FBQztFQUN4QztBQUNGLENBQUM7QUFFREgsV0FBVyxDQUFDVyxnQkFBZ0IsR0FBRyxVQUFVUixNQUFXLEVBQVE7RUFDMUQsSUFBSUQsUUFBUSxDQUFDQyxNQUFNLENBQUMsRUFBRTtJQUNwQixPQUFPRyx3QkFBVyxDQUFDSyxnQkFBZ0IsQ0FBQ1IsTUFBTSxDQUFDO0VBQzdDLENBQUMsTUFBTTtJQUNMLE1BQU1JLE9BQU8sR0FBRyxJQUFBQywwQkFBVyxFQUFDTCxNQUFNLENBQUNNLGFBQWEsRUFBRUMsc0NBQWtCLEVBQUVQLE1BQU0sQ0FBQztJQUM3RSxJQUFJLE9BQU9JLE9BQU8sQ0FBQ0ksZ0JBQWdCLEtBQUssVUFBVSxFQUFFO01BQ2xELE1BQU0sOENBQThDO0lBQ3REO0lBQ0EsT0FBT0osT0FBTyxDQUFDSSxnQkFBZ0IsQ0FBQ1IsTUFBTSxDQUFDO0VBQ3pDO0FBQ0YsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ParseWebSocketServer = exports.ParseWebSocket = void 0;
|
|
7
|
+
var _AdapterLoader = require("../Adapters/AdapterLoader");
|
|
8
|
+
var _WSAdapter = require("../Adapters/WebSocketServer/WSAdapter");
|
|
9
|
+
var _logger = _interopRequireDefault(require("../logger"));
|
|
10
|
+
var _events = _interopRequireDefault(require("events"));
|
|
11
|
+
var _util = require("util");
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
class ParseWebSocketServer {
|
|
14
|
+
constructor(server, onConnect, config) {
|
|
15
|
+
config.server = server;
|
|
16
|
+
const wss = (0, _AdapterLoader.loadAdapter)(config.wssAdapter, _WSAdapter.WSAdapter, config);
|
|
17
|
+
wss.onListen = () => {
|
|
18
|
+
_logger.default.info('Parse LiveQuery Server started running');
|
|
19
|
+
};
|
|
20
|
+
wss.onConnection = ws => {
|
|
21
|
+
ws.waitingForPong = false;
|
|
22
|
+
ws.on('pong', () => {
|
|
23
|
+
ws.waitingForPong = false;
|
|
24
|
+
});
|
|
25
|
+
ws.on('error', error => {
|
|
26
|
+
_logger.default.error(error.message);
|
|
27
|
+
_logger.default.error((0, _util.inspect)(ws, false));
|
|
28
|
+
});
|
|
29
|
+
onConnect(new ParseWebSocket(ws));
|
|
30
|
+
// Send ping to client periodically
|
|
31
|
+
const pingIntervalId = setInterval(() => {
|
|
32
|
+
if (!ws.waitingForPong) {
|
|
33
|
+
ws.ping();
|
|
34
|
+
ws.waitingForPong = true;
|
|
35
|
+
} else {
|
|
36
|
+
clearInterval(pingIntervalId);
|
|
37
|
+
ws.terminate();
|
|
38
|
+
}
|
|
39
|
+
}, config.websocketTimeout || 10 * 1000);
|
|
40
|
+
};
|
|
41
|
+
wss.onError = error => {
|
|
42
|
+
_logger.default.error(error);
|
|
43
|
+
};
|
|
44
|
+
wss.start();
|
|
45
|
+
this.server = wss;
|
|
46
|
+
}
|
|
47
|
+
close() {
|
|
48
|
+
if (this.server && this.server.close) {
|
|
49
|
+
this.server.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.ParseWebSocketServer = ParseWebSocketServer;
|
|
54
|
+
class ParseWebSocket extends _events.default.EventEmitter {
|
|
55
|
+
constructor(ws) {
|
|
56
|
+
super();
|
|
57
|
+
ws.onmessage = request => this.emit('message', request && request.data ? request.data : request);
|
|
58
|
+
ws.onclose = () => this.emit('disconnect');
|
|
59
|
+
this.ws = ws;
|
|
60
|
+
}
|
|
61
|
+
send(message) {
|
|
62
|
+
this.ws.send(message);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.ParseWebSocket = ParseWebSocket;
|
|
66
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQWRhcHRlckxvYWRlciIsInJlcXVpcmUiLCJfV1NBZGFwdGVyIiwiX2xvZ2dlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfZXZlbnRzIiwiX3V0aWwiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJQYXJzZVdlYlNvY2tldFNlcnZlciIsImNvbnN0cnVjdG9yIiwic2VydmVyIiwib25Db25uZWN0IiwiY29uZmlnIiwid3NzIiwibG9hZEFkYXB0ZXIiLCJ3c3NBZGFwdGVyIiwiV1NBZGFwdGVyIiwib25MaXN0ZW4iLCJsb2dnZXIiLCJpbmZvIiwib25Db25uZWN0aW9uIiwid3MiLCJ3YWl0aW5nRm9yUG9uZyIsIm9uIiwiZXJyb3IiLCJtZXNzYWdlIiwiaW5zcGVjdCIsIlBhcnNlV2ViU29ja2V0IiwicGluZ0ludGVydmFsSWQiLCJzZXRJbnRlcnZhbCIsInBpbmciLCJjbGVhckludGVydmFsIiwidGVybWluYXRlIiwid2Vic29ja2V0VGltZW91dCIsIm9uRXJyb3IiLCJzdGFydCIsImNsb3NlIiwiZXhwb3J0cyIsImV2ZW50cyIsIkV2ZW50RW1pdHRlciIsIm9ubWVzc2FnZSIsInJlcXVlc3QiLCJlbWl0IiwiZGF0YSIsIm9uY2xvc2UiLCJzZW5kIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL0xpdmVRdWVyeS9QYXJzZVdlYlNvY2tldFNlcnZlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBsb2FkQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgV1NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvV2ViU29ja2V0U2VydmVyL1dTQWRhcHRlcic7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSAndXRpbCc7XG5cbmV4cG9ydCBjbGFzcyBQYXJzZVdlYlNvY2tldFNlcnZlciB7XG4gIHNlcnZlcjogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNlcnZlcjogYW55LCBvbkNvbm5lY3Q6IEZ1bmN0aW9uLCBjb25maWcpIHtcbiAgICBjb25maWcuc2VydmVyID0gc2VydmVyO1xuICAgIGNvbnN0IHdzcyA9IGxvYWRBZGFwdGVyKGNvbmZpZy53c3NBZGFwdGVyLCBXU0FkYXB0ZXIsIGNvbmZpZyk7XG4gICAgd3NzLm9uTGlzdGVuID0gKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oJ1BhcnNlIExpdmVRdWVyeSBTZXJ2ZXIgc3RhcnRlZCBydW5uaW5nJyk7XG4gICAgfTtcbiAgICB3c3Mub25Db25uZWN0aW9uID0gd3MgPT4ge1xuICAgICAgd3Mud2FpdGluZ0ZvclBvbmcgPSBmYWxzZTtcbiAgICAgIHdzLm9uKCdwb25nJywgKCkgPT4ge1xuICAgICAgICB3cy53YWl0aW5nRm9yUG9uZyA9IGZhbHNlO1xuICAgICAgfSk7XG4gICAgICB3cy5vbignZXJyb3InLCBlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGluc3BlY3Qod3MsIGZhbHNlKSk7XG4gICAgICB9KTtcbiAgICAgIG9uQ29ubmVjdChuZXcgUGFyc2VXZWJTb2NrZXQod3MpKTtcbiAgICAgIC8vIFNlbmQgcGluZyB0byBjbGllbnQgcGVyaW9kaWNhbGx5XG4gICAgICBjb25zdCBwaW5nSW50ZXJ2YWxJZCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKCF3cy53YWl0aW5nRm9yUG9uZykge1xuICAgICAgICAgIHdzLnBpbmcoKTtcbiAgICAgICAgICB3cy53YWl0aW5nRm9yUG9uZyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWxJZCk7XG4gICAgICAgICAgd3MudGVybWluYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sIGNvbmZpZy53ZWJzb2NrZXRUaW1lb3V0IHx8IDEwICogMTAwMCk7XG4gICAgfTtcbiAgICB3c3Mub25FcnJvciA9IGVycm9yID0+IHtcbiAgICAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgfTtcbiAgICB3c3Muc3RhcnQoKTtcbiAgICB0aGlzLnNlcnZlciA9IHdzcztcbiAgfVxuXG4gIGNsb3NlKCkge1xuICAgIGlmICh0aGlzLnNlcnZlciAmJiB0aGlzLnNlcnZlci5jbG9zZSkge1xuICAgICAgdGhpcy5zZXJ2ZXIuY2xvc2UoKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBhcnNlV2ViU29ja2V0IGV4dGVuZHMgZXZlbnRzLkV2ZW50RW1pdHRlciB7XG4gIHdzOiBhbnk7XG5cbiAgY29uc3RydWN0b3Iod3M6IGFueSkge1xuICAgIHN1cGVyKCk7XG4gICAgd3Mub25tZXNzYWdlID0gcmVxdWVzdCA9PlxuICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlJywgcmVxdWVzdCAmJiByZXF1ZXN0LmRhdGEgPyByZXF1ZXN0LmRhdGEgOiByZXF1ZXN0KTtcbiAgICB3cy5vbmNsb3NlID0gKCkgPT4gdGhpcy5lbWl0KCdkaXNjb25uZWN0Jyk7XG4gICAgdGhpcy53cyA9IHdzO1xuICB9XG5cbiAgc2VuZChtZXNzYWdlOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLndzLnNlbmQobWVzc2FnZSk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsY0FBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsVUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsT0FBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBRCxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUssS0FBQSxHQUFBTCxPQUFBO0FBQStCLFNBQUFHLHVCQUFBRyxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRXhCLE1BQU1HLG9CQUFv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
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var equalObjects = require('./equalObjects');
|
|
4
|
+
var Id = require('./Id');
|
|
5
|
+
var Parse = require('parse/node');
|
|
6
|
+
var vm = require('vm');
|
|
7
|
+
var logger = require('../logger').default;
|
|
8
|
+
var regexTimeout = 0;
|
|
9
|
+
// IMPORTANT: vmContext is shared across all calls for performance (vm.createContext() is expensive).
|
|
10
|
+
// This is safe because safeRegexTest is synchronous — setting the context properties and calling
|
|
11
|
+
// runInContext happen in the same event loop tick with no interruption possible. Do NOT add any
|
|
12
|
+
// asynchronous operations (await, callbacks, promises) between setting vmContext properties and
|
|
13
|
+
// calling script.runInContext, as this would allow other calls to overwrite the context values
|
|
14
|
+
// and cause cross-contamination between regex evaluations.
|
|
15
|
+
var vmContext = vm.createContext(Object.create(null));
|
|
16
|
+
var scriptCache = new Map();
|
|
17
|
+
var SCRIPT_CACHE_MAX = 1000;
|
|
18
|
+
function setRegexTimeout(ms) {
|
|
19
|
+
regexTimeout = ms;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// IMPORTANT: This function must remain synchronous. See vmContext comment above.
|
|
23
|
+
function safeRegexTest(pattern, flags, input) {
|
|
24
|
+
try {
|
|
25
|
+
if (!regexTimeout) {
|
|
26
|
+
var re = new RegExp(pattern, flags);
|
|
27
|
+
return re.test(input);
|
|
28
|
+
}
|
|
29
|
+
var cacheKey = flags + ':' + pattern;
|
|
30
|
+
var script = scriptCache.get(cacheKey);
|
|
31
|
+
if (!script) {
|
|
32
|
+
if (scriptCache.size >= SCRIPT_CACHE_MAX) {
|
|
33
|
+
scriptCache.clear();
|
|
34
|
+
}
|
|
35
|
+
script = new vm.Script('new RegExp(pattern, flags).test(input)');
|
|
36
|
+
scriptCache.set(cacheKey, script);
|
|
37
|
+
}
|
|
38
|
+
vmContext.pattern = pattern;
|
|
39
|
+
vmContext.flags = flags;
|
|
40
|
+
vmContext.input = input;
|
|
41
|
+
return script.runInContext(vmContext, {
|
|
42
|
+
timeout: regexTimeout
|
|
43
|
+
});
|
|
44
|
+
} catch (e) {
|
|
45
|
+
if (e.code === 'ERR_SCRIPT_EXECUTION_TIMEOUT') {
|
|
46
|
+
logger.warn(`Regex timeout: pattern "${pattern}" with flags "${flags}" exceeded ${regexTimeout}ms limit`);
|
|
47
|
+
} else {
|
|
48
|
+
logger.warn(`Invalid regex: pattern "${pattern}" with flags "${flags}": ${e.message}`);
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Query Hashes are deterministic hashes for Parse Queries.
|
|
56
|
+
* Any two queries that have the same set of constraints will produce the same
|
|
57
|
+
* hash. This lets us reliably group components by the queries they depend upon,
|
|
58
|
+
* and quickly determine if a query has changed.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Convert $or queries into an array of where conditions
|
|
63
|
+
*/
|
|
64
|
+
function flattenOrQueries(where) {
|
|
65
|
+
if (!Object.prototype.hasOwnProperty.call(where, '$or')) {
|
|
66
|
+
return where;
|
|
67
|
+
}
|
|
68
|
+
var accum = [];
|
|
69
|
+
for (var i = 0; i < where.$or.length; i++) {
|
|
70
|
+
accum = accum.concat(where.$or[i]);
|
|
71
|
+
}
|
|
72
|
+
return accum;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Deterministically turns an object into a string. Disregards ordering
|
|
77
|
+
*/
|
|
78
|
+
function stringify(object) {
|
|
79
|
+
if (typeof object !== 'object' || object === null) {
|
|
80
|
+
if (typeof object === 'string') {
|
|
81
|
+
return '"' + object.replace(/\|/g, '%|') + '"';
|
|
82
|
+
}
|
|
83
|
+
return object + '';
|
|
84
|
+
}
|
|
85
|
+
if (Array.isArray(object)) {
|
|
86
|
+
var copy = object.map(stringify);
|
|
87
|
+
copy.sort();
|
|
88
|
+
return '[' + copy.join(',') + ']';
|
|
89
|
+
}
|
|
90
|
+
var sections = [];
|
|
91
|
+
var keys = Object.keys(object);
|
|
92
|
+
keys.sort();
|
|
93
|
+
for (var k = 0; k < keys.length; k++) {
|
|
94
|
+
sections.push(stringify(keys[k]) + ':' + stringify(object[keys[k]]));
|
|
95
|
+
}
|
|
96
|
+
return '{' + sections.join(',') + '}';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Generate a hash from a query, with unique fields for columns, values, order,
|
|
101
|
+
* skip, and limit.
|
|
102
|
+
*/
|
|
103
|
+
function queryHash(query) {
|
|
104
|
+
if (query instanceof Parse.Query) {
|
|
105
|
+
query = {
|
|
106
|
+
className: query.className,
|
|
107
|
+
where: query._where
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
var where = flattenOrQueries(query.where || {});
|
|
111
|
+
var columns = [];
|
|
112
|
+
var values = [];
|
|
113
|
+
var i;
|
|
114
|
+
if (Array.isArray(where)) {
|
|
115
|
+
var uniqueColumns = {};
|
|
116
|
+
for (i = 0; i < where.length; i++) {
|
|
117
|
+
var subValues = {};
|
|
118
|
+
var keys = Object.keys(where[i]);
|
|
119
|
+
keys.sort();
|
|
120
|
+
for (var j = 0; j < keys.length; j++) {
|
|
121
|
+
subValues[keys[j]] = where[i][keys[j]];
|
|
122
|
+
uniqueColumns[keys[j]] = true;
|
|
123
|
+
}
|
|
124
|
+
values.push(subValues);
|
|
125
|
+
}
|
|
126
|
+
columns = Object.keys(uniqueColumns);
|
|
127
|
+
columns.sort();
|
|
128
|
+
} else {
|
|
129
|
+
columns = Object.keys(where);
|
|
130
|
+
columns.sort();
|
|
131
|
+
for (i = 0; i < columns.length; i++) {
|
|
132
|
+
values.push(where[columns[i]]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
var sections = [columns.join(','), stringify(values)];
|
|
136
|
+
return query.className + ':' + sections.join('|');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* contains -- Determines if an object is contained in a list with special handling for Parse pointers.
|
|
141
|
+
*/
|
|
142
|
+
function contains(haystack, needle) {
|
|
143
|
+
if (needle && needle.__type && needle.__type === 'Pointer') {
|
|
144
|
+
for (const i in haystack) {
|
|
145
|
+
const ptr = haystack[i];
|
|
146
|
+
if (typeof ptr === 'string' && ptr === needle.objectId) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
if (ptr.className === needle.className && ptr.objectId === needle.objectId) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
if (Array.isArray(needle)) {
|
|
156
|
+
for (const need of needle) {
|
|
157
|
+
if (contains(haystack, need)) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return haystack.indexOf(needle) > -1;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* matchesQuery -- Determines if an object would be returned by a Parse Query
|
|
166
|
+
* It's a lightweight, where-clause only implementation of a full query engine.
|
|
167
|
+
* Since we find queries that match objects, rather than objects that match
|
|
168
|
+
* queries, we can avoid building a full-blown query tool.
|
|
169
|
+
*/
|
|
170
|
+
function matchesQuery(object, query) {
|
|
171
|
+
if (query instanceof Parse.Query) {
|
|
172
|
+
var className = object.id instanceof Id ? object.id.className : object.className;
|
|
173
|
+
if (className !== query.className) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
return matchesQuery(object, query._where);
|
|
177
|
+
}
|
|
178
|
+
for (var field in query) {
|
|
179
|
+
if (!matchesKeyConstraints(object, field, query[field])) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
function equalObjectsGeneric(obj, compareTo, eqlFn) {
|
|
186
|
+
if (Array.isArray(obj)) {
|
|
187
|
+
for (var i = 0; i < obj.length; i++) {
|
|
188
|
+
if (eqlFn(obj[i], compareTo)) {
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return eqlFn(obj, compareTo);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Determines whether an object matches a single key's constraints
|
|
199
|
+
*/
|
|
200
|
+
function matchesKeyConstraints(object, key, constraints) {
|
|
201
|
+
if (constraints === null) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if (key.indexOf('.') >= 0) {
|
|
205
|
+
// Key references a subobject
|
|
206
|
+
var keyComponents = key.split('.');
|
|
207
|
+
var subObjectKey = keyComponents[0];
|
|
208
|
+
var keyRemainder = keyComponents.slice(1).join('.');
|
|
209
|
+
return matchesKeyConstraints(object[subObjectKey] || {}, keyRemainder, constraints);
|
|
210
|
+
}
|
|
211
|
+
var i;
|
|
212
|
+
if (key === '$or') {
|
|
213
|
+
if (!Array.isArray(constraints)) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
for (i = 0; i < constraints.length; i++) {
|
|
217
|
+
if (matchesQuery(object, constraints[i])) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
if (key === '$and') {
|
|
224
|
+
if (!Array.isArray(constraints)) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
for (i = 0; i < constraints.length; i++) {
|
|
228
|
+
if (!matchesQuery(object, constraints[i])) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
if (key === '$nor') {
|
|
235
|
+
if (!Array.isArray(constraints)) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
for (i = 0; i < constraints.length; i++) {
|
|
239
|
+
if (matchesQuery(object, constraints[i])) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
if (key === '$relatedTo') {
|
|
246
|
+
// Bail! We can't handle relational queries locally
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
// Decode Date JSON value
|
|
250
|
+
if (object[key] && object[key].__type == 'Date') {
|
|
251
|
+
object[key] = new Date(object[key].iso);
|
|
252
|
+
}
|
|
253
|
+
// Equality (or Array contains) cases
|
|
254
|
+
if (typeof constraints !== 'object') {
|
|
255
|
+
if (Array.isArray(object[key])) {
|
|
256
|
+
return object[key].indexOf(constraints) > -1;
|
|
257
|
+
}
|
|
258
|
+
return object[key] === constraints;
|
|
259
|
+
}
|
|
260
|
+
var compareTo;
|
|
261
|
+
if (constraints.__type) {
|
|
262
|
+
if (constraints.__type === 'Pointer') {
|
|
263
|
+
return equalObjectsGeneric(object[key], constraints, function (obj, ptr) {
|
|
264
|
+
return typeof obj !== 'undefined' && ptr.className === obj.className && ptr.objectId === obj.objectId;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return equalObjectsGeneric(object[key], Parse._decode(key, constraints), equalObjects);
|
|
268
|
+
}
|
|
269
|
+
// More complex cases
|
|
270
|
+
for (var condition in constraints) {
|
|
271
|
+
compareTo = constraints[condition];
|
|
272
|
+
if (compareTo?.__type) {
|
|
273
|
+
compareTo = Parse._decode(key, compareTo);
|
|
274
|
+
}
|
|
275
|
+
switch (condition) {
|
|
276
|
+
case '$lt':
|
|
277
|
+
if (object[key] >= compareTo) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
break;
|
|
281
|
+
case '$lte':
|
|
282
|
+
if (object[key] > compareTo) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
case '$gt':
|
|
287
|
+
if (object[key] <= compareTo) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
break;
|
|
291
|
+
case '$gte':
|
|
292
|
+
if (object[key] < compareTo) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
case '$eq':
|
|
297
|
+
if (!equalObjects(object[key], compareTo)) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
break;
|
|
301
|
+
case '$ne':
|
|
302
|
+
if (equalObjects(object[key], compareTo)) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
break;
|
|
306
|
+
case '$in':
|
|
307
|
+
if (!contains(compareTo, object[key])) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
break;
|
|
311
|
+
case '$nin':
|
|
312
|
+
if (contains(compareTo, object[key])) {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
case '$all':
|
|
317
|
+
if (!object[key]) {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
for (i = 0; i < compareTo.length; i++) {
|
|
321
|
+
if (object[key].indexOf(compareTo[i]) < 0) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
break;
|
|
326
|
+
case '$exists':
|
|
327
|
+
{
|
|
328
|
+
const propertyExists = typeof object[key] !== 'undefined';
|
|
329
|
+
const existenceIsRequired = constraints['$exists'];
|
|
330
|
+
if (typeof constraints['$exists'] !== 'boolean') {
|
|
331
|
+
// The SDK will never submit a non-boolean for $exists, but if someone
|
|
332
|
+
// tries to submit a non-boolean for $exits outside the SDKs, just ignore it.
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
if (!propertyExists && existenceIsRequired || propertyExists && !existenceIsRequired) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
case '$regex':
|
|
341
|
+
{
|
|
342
|
+
if (typeof compareTo === 'object') {
|
|
343
|
+
if (!safeRegexTest(compareTo.source, compareTo.flags, object[key])) {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
// JS doesn't support perl-style escaping
|
|
349
|
+
var expString = '';
|
|
350
|
+
var escapeEnd = -2;
|
|
351
|
+
var escapeStart = compareTo.indexOf('\\Q');
|
|
352
|
+
while (escapeStart > -1) {
|
|
353
|
+
// Add the unescaped portion
|
|
354
|
+
expString += compareTo.substring(escapeEnd + 2, escapeStart);
|
|
355
|
+
escapeEnd = compareTo.indexOf('\\E', escapeStart);
|
|
356
|
+
if (escapeEnd > -1) {
|
|
357
|
+
expString += compareTo.substring(escapeStart + 2, escapeEnd).replace(/\\\\\\\\E/g, '\\E').replace(/\W/g, '\\$&');
|
|
358
|
+
}
|
|
359
|
+
escapeStart = compareTo.indexOf('\\Q', escapeEnd);
|
|
360
|
+
}
|
|
361
|
+
expString += compareTo.substring(Math.max(escapeStart, escapeEnd + 2));
|
|
362
|
+
if (!safeRegexTest(expString, constraints.$options || '', object[key])) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
case '$nearSphere':
|
|
368
|
+
if (!compareTo || !object[key]) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
var distance = compareTo.radiansTo(object[key]);
|
|
372
|
+
var max = constraints.$maxDistance || Infinity;
|
|
373
|
+
return distance <= max;
|
|
374
|
+
case '$within':
|
|
375
|
+
if (!compareTo || !object[key]) {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
var southWest = compareTo.$box[0];
|
|
379
|
+
var northEast = compareTo.$box[1];
|
|
380
|
+
if (southWest.latitude > northEast.latitude || southWest.longitude > northEast.longitude) {
|
|
381
|
+
// Invalid box, crosses the date line
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
return object[key].latitude > southWest.latitude && object[key].latitude < northEast.latitude && object[key].longitude > southWest.longitude && object[key].longitude < northEast.longitude;
|
|
385
|
+
case '$containedBy':
|
|
386
|
+
{
|
|
387
|
+
for (const value of object[key]) {
|
|
388
|
+
if (!contains(compareTo, value)) {
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
case '$geoWithin':
|
|
395
|
+
{
|
|
396
|
+
if (compareTo.$polygon) {
|
|
397
|
+
const points = compareTo.$polygon.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]);
|
|
398
|
+
const polygon = new Parse.Polygon(points);
|
|
399
|
+
return polygon.containsPoint(object[key]);
|
|
400
|
+
}
|
|
401
|
+
if (compareTo.$centerSphere) {
|
|
402
|
+
const [WGS84Point, maxDistance] = compareTo.$centerSphere;
|
|
403
|
+
const centerPoint = new Parse.GeoPoint({
|
|
404
|
+
latitude: WGS84Point[1],
|
|
405
|
+
longitude: WGS84Point[0]
|
|
406
|
+
});
|
|
407
|
+
const point = new Parse.GeoPoint(object[key]);
|
|
408
|
+
const distance = point.radiansTo(centerPoint);
|
|
409
|
+
return distance <= maxDistance;
|
|
410
|
+
}
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
case '$geoIntersects':
|
|
414
|
+
{
|
|
415
|
+
const polygon = new Parse.Polygon(object[key].coordinates);
|
|
416
|
+
const point = new Parse.GeoPoint(compareTo.$point);
|
|
417
|
+
return polygon.containsPoint(point);
|
|
418
|
+
}
|
|
419
|
+
case '$options':
|
|
420
|
+
// Not a query type, but a way to add options to $regex. Ignore and
|
|
421
|
+
// avoid the default
|
|
422
|
+
break;
|
|
423
|
+
case '$maxDistance':
|
|
424
|
+
// Not a query type, but a way to add a cap to $nearSphere. Ignore and
|
|
425
|
+
// avoid the default
|
|
426
|
+
break;
|
|
427
|
+
case '$select':
|
|
428
|
+
return false;
|
|
429
|
+
case '$dontSelect':
|
|
430
|
+
return false;
|
|
431
|
+
default:
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
var QueryTools = {
|
|
438
|
+
queryHash: queryHash,
|
|
439
|
+
matchesQuery: matchesQuery,
|
|
440
|
+
setRegexTimeout: setRegexTimeout
|
|
441
|
+
};
|
|
442
|
+
module.exports = QueryTools;
|
|
443
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJlcXVhbE9iamVjdHMiLCJyZXF1aXJlIiwiSWQiLCJQYXJzZSIsInZtIiwibG9nZ2VyIiwiZGVmYXVsdCIsInJlZ2V4VGltZW91dCIsInZtQ29udGV4dCIsImNyZWF0ZUNvbnRleHQiLCJPYmplY3QiLCJjcmVhdGUiLCJzY3JpcHRDYWNoZSIsIk1hcCIsIlNDUklQVF9DQUNIRV9NQVgiLCJzZXRSZWdleFRpbWVvdXQiLCJtcyIsInNhZmVSZWdleFRlc3QiLCJwYXR0ZXJuIiwiZmxhZ3MiLCJpbnB1dCIsInJlIiwiUmVnRXhwIiwidGVzdCIsImNhY2hlS2V5Iiwic2NyaXB0IiwiZ2V0Iiwic2l6ZSIsImNsZWFyIiwiU2NyaXB0Iiwic2V0IiwicnVuSW5Db250ZXh0IiwidGltZW91dCIsImUiLCJjb2RlIiwid2FybiIsIm1lc3NhZ2UiLCJmbGF0dGVuT3JRdWVyaWVzIiwid2hlcmUiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJhY2N1bSIsImkiLCIkb3IiLCJsZW5ndGgiLCJjb25jYXQiLCJzdHJpbmdpZnkiLCJvYmplY3QiLCJyZXBsYWNlIiwiQXJyYXkiLCJpc0FycmF5IiwiY29weSIsIm1hcCIsInNvcnQiLCJqb2luIiwic2VjdGlvbnMiLCJrZXlzIiwiayIsInB1c2giLCJxdWVyeUhhc2giLCJxdWVyeSIsIlF1ZXJ5IiwiY2xhc3NOYW1lIiwiX3doZXJlIiwiY29sdW1ucyIsInZhbHVlcyIsInVuaXF1ZUNvbHVtbnMiLCJzdWJWYWx1ZXMiLCJqIiwiY29udGFpbnMiLCJoYXlzdGFjayIsIm5lZWRsZSIsIl9fdHlwZSIsInB0ciIsIm9iamVjdElkIiwibmVlZCIsImluZGV4T2YiLCJtYXRjaGVzUXVlcnkiLCJpZCIsImZpZWxkIiwibWF0Y2hlc0tleUNvbnN0cmFpbnRzIiwiZXF1YWxPYmplY3RzR2VuZXJpYyIsIm9iaiIsImNvbXBhcmVUbyIsImVxbEZuIiwia2V5IiwiY29uc3RyYWludHMiLCJrZXlDb21wb25lbnRzIiwic3BsaXQiLCJzdWJPYmplY3RLZXkiLCJrZXlSZW1haW5kZXIiLCJzbGljZSIsIkRhdGUiLCJpc28iLCJfZGVjb2RlIiwiY29uZGl0aW9uIiwicHJvcGVydHlFeGlzdHMiLCJleGlzdGVuY2VJc1JlcXVpcmVkIiwic291cmNlIiwiZXhwU3RyaW5nIiwiZXNjYXBlRW5kIiwiZXNjYXBlU3RhcnQiLCJzdWJzdHJpbmciLCJNYXRoIiwibWF4IiwiJG9wdGlvbnMiLCJkaXN0YW5jZSIsInJhZGlhbnNUbyIsIiRtYXhEaXN0YW5jZSIsIkluZmluaXR5Iiwic291dGhXZXN0IiwiJGJveCIsIm5vcnRoRWFzdCIsImxhdGl0dWRlIiwibG9uZ2l0dWRlIiwidmFsdWUiLCIkcG9seWdvbiIsInBvaW50cyIsImdlb1BvaW50IiwicG9seWdvbiIsIlBvbHlnb24iLCJjb250YWluc1BvaW50IiwiJGNlbnRlclNwaGVyZSIsIldHUzg0UG9pbnQiLCJtYXhEaXN0YW5jZSIsImNlbnRlclBvaW50IiwiR2VvUG9pbnQiLCJwb2ludCIsImNvb3JkaW5hdGVzIiwiJHBvaW50IiwiUXVlcnlUb29scyIsIm1vZHVsZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvTGl2ZVF1ZXJ5L1F1ZXJ5VG9vbHMuanMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vZXF1YWxPYmplY3RzJyk7XG52YXIgSWQgPSByZXF1aXJlKCcuL0lkJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG52YXIgdm0gPSByZXF1aXJlKCd2bScpO1xudmFyIGxvZ2dlciA9IHJlcXVpcmUoJy4uL2xvZ2dlcicpLmRlZmF1bHQ7XG5cbnZhciByZWdleFRpbWVvdXQgPSAwO1xuLy8gSU1QT1JUQU5UOiB2bUNvbnRleHQgaXMgc2hhcmVkIGFjcm9zcyBhbGwgY2FsbHMgZm9yIHBlcmZvcm1hbmNlICh2bS5jcmVhdGVDb250ZXh0KCkgaXMgZXhwZW5zaXZlKS5cbi8vIFRoaXMgaXMgc2FmZSBiZWNhdXNlIHNhZmVSZWdleFRlc3QgaXMgc3luY2hyb25vdXMg4oCUIHNldHRpbmcgdGhlIGNvbnRleHQgcHJvcGVydGllcyBhbmQgY2FsbGluZ1xuLy8gcnVuSW5Db250ZXh0IGhhcHBlbiBpbiB0aGUgc2FtZSBldmVudCBsb29wIHRpY2sgd2l0aCBubyBpbnRlcnJ1cHRpb24gcG9zc2libGUuIERvIE5PVCBhZGQgYW55XG4vLyBhc3luY2hyb25vdXMgb3BlcmF0aW9ucyAoYXdhaXQsIGNhbGxiYWNrcywgcHJvbWlzZXMpIGJldHdlZW4gc2V0dGluZyB2bUNvbnRleHQgcHJvcGVydGllcyBhbmRcbi8vIGNhbGxpbmcgc2NyaXB0LnJ1bkluQ29udGV4dCwgYXMgdGhpcyB3b3VsZCBhbGxvdyBvdGhlciBjYWxscyB0byBvdmVyd3JpdGUgdGhlIGNvbnRleHQgdmFsdWVzXG4vLyBhbmQgY2F1c2UgY3Jvc3MtY29udGFtaW5hdGlvbiBiZXR3ZWVuIHJlZ2V4IGV2YWx1YXRpb25zLlxudmFyIHZtQ29udGV4dCA9IHZtLmNyZWF0ZUNvbnRleHQoT2JqZWN0LmNyZWF0ZShudWxsKSk7XG52YXIgc2NyaXB0Q2FjaGUgPSBuZXcgTWFwKCk7XG52YXIgU0NSSVBUX0NBQ0hFX01BWCA9IDEwMDA7XG5cbmZ1bmN0aW9uIHNldFJlZ2V4VGltZW91dChtcykge1xuICByZWdleFRpbWVvdXQgPSBtcztcbn1cblxuLy8gSU1QT1JUQU5UOiBUaGlzIGZ1bmN0aW9uIG11c3QgcmVtYWluIHN5bmNocm9ub3VzLiBTZWUgdm1Db250ZXh0IGNvbW1lbnQgYWJvdmUuXG5mdW5jdGlvbiBzYWZlUmVnZXhUZXN0KHBhdHRlcm4sIGZsYWdzLCBpbnB1dCkge1xuICB0cnkge1xuICAgIGlmICghcmVnZXhUaW1lb3V0KSB7XG4gICAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKHBhdHRlcm4sIGZsYWdzKTtcbiAgICAgIHJldHVybiByZS50ZXN0KGlucHV0KTtcbiAgICB9XG4gICAgdmFyIGNhY2hlS2V5ID0gZmxhZ3MgKyAnOicgKyBwYXR0ZXJuO1xuICAgIHZhciBzY3JpcHQgPSBzY3JpcHRDYWNoZS5nZXQoY2FjaGVLZXkpO1xuICAgIGlmICghc2NyaXB0KSB7XG4gICAgICBpZiAoc2NyaXB0Q2FjaGUuc2l6ZSA+PSBTQ1JJUFRfQ0FDSEVfTUFYKSB7IHNjcmlwdENhY2hlLmNsZWFyKCk7IH1cbiAgICAgIHNjcmlwdCA9IG5ldyB2bS5TY3JpcHQoJ25ldyBSZWdFeHAocGF0dGVybiwgZmxhZ3MpLnRlc3QoaW5wdXQpJyk7XG4gICAgICBzY3JpcHRDYWNoZS5zZXQoY2FjaGVLZXksIHNjcmlwdCk7XG4gICAgfVxuICAgIHZtQ29udGV4dC5wYXR0ZXJuID0gcGF0dGVybjtcbiAgICB2bUNvbnRleHQuZmxhZ3MgPSBmbGFncztcbiAgICB2bUNvbnRleHQuaW5wdXQgPSBpbnB1dDtcbiAgICByZXR1cm4gc2NyaXB0LnJ1bkluQ29udGV4dCh2bUNvbnRleHQsIHsgdGltZW91dDogcmVnZXhUaW1lb3V0IH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUuY29kZSA9PT0gJ0VSUl9TQ1JJUFRfRVhFQ1VUSU9OX1RJTUVPVVQnKSB7XG4gICAgICBsb2dnZXIud2FybihgUmVnZXggdGltZW91dDogcGF0dGVybiBcIiR7cGF0dGVybn1cIiB3aXRoIGZsYWdzIFwiJHtmbGFnc31cIiBleGNlZWRlZCAke3JlZ2V4VGltZW91dH1tcyBsaW1pdGApO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIud2FybihgSW52YWxpZCByZWdleDogcGF0dGVybiBcIiR7cGF0dGVybn1cIiB3aXRoIGZsYWdzIFwiJHtmbGFnc31cIjogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIFF1ZXJ5IEhhc2hlcyBhcmUgZGV0ZXJtaW5pc3RpYyBoYXNoZXMgZm9yIFBhcnNlIFF1ZXJpZXMuXG4gKiBBbnkgdHdvIHF1ZXJpZXMgdGhhdCBoYXZlIHRoZSBzYW1lIHNldCBvZiBjb25zdHJhaW50cyB3aWxsIHByb2R1Y2UgdGhlIHNhbWVcbiAqIGhhc2guIFRoaXMgbGV0cyB1cyByZWxpYWJseSBncm91cCBjb21wb25lbnRzIGJ5IHRoZSBxdWVyaWVzIHRoZXkgZGVwZW5kIHVwb24sXG4gKiBhbmQgcXVpY2tseSBkZXRlcm1pbmUgaWYgYSBxdWVyeSBoYXMgY2hhbmdlZC5cbiAqL1xuXG4vKipcbiAqIENvbnZlcnQgJG9yIHF1ZXJpZXMgaW50byBhbiBhcnJheSBvZiB3aGVyZSBjb25kaXRpb25zXG4gKi9cbmZ1bmN0aW9uIGZsYXR0ZW5PclF1ZXJpZXMod2hlcmUpIHtcbiAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwod2hlcmUsICckb3InKSkge1xuICAgIHJldHVybiB3aGVyZTtcbiAgfVxuICB2YXIgYWNjdW0gPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB3aGVyZS4kb3IubGVuZ3RoOyBpKyspIHtcbiAgICBhY2N1bSA9IGFjY3VtLmNvbmNhdCh3aGVyZS4kb3JbaV0pO1xuICB9XG4gIHJldHVybiBhY2N1bTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmlzdGljYWxseSB0dXJucyBhbiBvYmplY3QgaW50byBhIHN0cmluZy4gRGlzcmVnYXJkcyBvcmRlcmluZ1xuICovXG5mdW5jdGlvbiBzdHJpbmdpZnkob2JqZWN0KTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiBvYmplY3QgIT09ICdvYmplY3QnIHx8IG9iamVjdCA9PT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuICdcIicgKyBvYmplY3QucmVwbGFjZSgvXFx8L2csICclfCcpICsgJ1wiJztcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdCArICcnO1xuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KG9iamVjdCkpIHtcbiAgICB2YXIgY29weSA9IG9iamVjdC5tYXAoc3RyaW5naWZ5KTtcbiAgICBjb3B5LnNvcnQoKTtcbiAgICByZXR1cm4gJ1snICsgY29weS5qb2luKCcsJykgKyAnXSc7XG4gIH1cbiAgdmFyIHNlY3Rpb25zID0gW107XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTtcbiAga2V5cy5zb3J0KCk7XG4gIGZvciAodmFyIGsgPSAwOyBrIDwga2V5cy5sZW5ndGg7IGsrKykge1xuICAgIHNlY3Rpb25zLnB1c2goc3RyaW5naWZ5KGtleXNba10pICsgJzonICsgc3RyaW5naWZ5KG9iamVjdFtrZXlzW2tdXSkpO1xuICB9XG4gIHJldHVybiAneycgKyBzZWN0aW9ucy5qb2luKCcsJykgKyAnfSc7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBoYXNoIGZyb20gYSBxdWVyeSwgd2l0aCB1bmlxdWUgZmllbGRzIGZvciBjb2x1bW5zLCB2YWx1ZXMsIG9yZGVyLFxuICogc2tpcCwgYW5kIGxpbWl0LlxuICovXG5mdW5jdGlvbiBxdWVyeUhhc2gocXVlcnkpIHtcbiAgaWYgKHF1ZXJ5IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICBxdWVyeSA9IHtcbiAgICAgIGNsYXNzTmFtZTogcXVlcnkuY2xhc3NOYW1lLFxuICAgICAgd2hlcmU6IHF1ZXJ5Ll93aGVyZSxcbiAgICB9O1xuICB9XG4gIHZhciB3aGVyZSA9IGZsYXR0ZW5PclF1ZXJpZXMocXVlcnkud2hlcmUgfHwge30pO1xuICB2YXIgY29sdW1ucyA9IFtdO1xuICB2YXIgdmFsdWVzID0gW107XG4gIHZhciBpO1xuICBpZiAoQXJyYXkuaXNBcnJheSh3aGVyZSkpIHtcbiAgICB2YXIgdW5pcXVlQ29sdW1ucyA9IHt9O1xuICAgIGZvciAoaSA9IDA7IGkgPCB3aGVyZS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHN1YlZhbHVlcyA9IHt9O1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh3aGVyZVtpXSk7XG4gICAgICBrZXlzLnNvcnQoKTtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7IGorKykge1xuICAgICAgICBzdWJWYWx1ZXNba2V5c1tqXV0gPSB3aGVyZVtpXVtrZXlzW2pdXTtcbiAgICAgICAgdW5pcXVlQ29sdW1uc1trZXlzW2pdXSA9IHRydWU7XG4gICAgICB9XG4gICAgICB2YWx1ZXMucHVzaChzdWJWYWx1ZXMpO1xuICAgIH1cbiAgICBjb2x1bW5zID0gT2JqZWN0LmtleXModW5pcXVlQ29sdW1ucyk7XG4gICAgY29sdW1ucy5zb3J0KCk7XG4gIH0gZWxzZSB7XG4gICAgY29sdW1ucyA9IE9iamVjdC5rZXlzKHdoZXJlKTtcbiAgICBjb2x1bW5zLnNvcnQoKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY29sdW1ucy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFsdWVzLnB1c2god2hlcmVbY29sdW1uc1tpXV0pO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzZWN0aW9ucyA9IFtjb2x1bW5zLmpvaW4oJywnKSwgc3RyaW5naWZ5KHZhbHVlcyldO1xuXG4gIHJldHVybiBxdWVyeS5jbGFzc05hbWUgKyAnOicgKyBzZWN0aW9ucy5qb2luKCd8Jyk7XG59XG5cbi8qKlxuICogY29udGFpbnMgLS0gRGV0ZXJtaW5lcyBpZiBhbiBvYmplY3QgaXMgY29udGFpbmVkIGluIGEgbGlzdCB3aXRoIHNwZWNpYWwgaGFuZGxpbmcgZm9yIFBhcnNlIHBvaW50ZXJzLlxuICovXG5mdW5jdGlvbiBjb250YWlucyhoYXlzdGFjazogQXJyYXksIG5lZWRsZTogYW55KTogYm9vbGVhbiB7XG4gIGlmIChuZWVkbGUgJiYgbmVlZGxlLl9fdHlwZSAmJiBuZWVkbGUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICBmb3IgKGNvbnN0IGkgaW4gaGF5c3RhY2spIHtcbiAgICAgIGNvbnN0IHB0ciA9IGhheXN0YWNrW2ldO1xuICAgICAgaWYgKHR5cGVvZiBwdHIgPT09ICdzdHJpbmcnICYmIHB0ciA9PT0gbmVlZGxlLm9iamVjdElkKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHB0ci5jbGFzc05hbWUgPT09IG5lZWRsZS5jbGFzc05hbWUgJiYgcHRyLm9iamVjdElkID09PSBuZWVkbGUub2JqZWN0SWQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkobmVlZGxlKSkge1xuICAgIGZvciAoY29uc3QgbmVlZCBvZiBuZWVkbGUpIHtcbiAgICAgIGlmIChjb250YWlucyhoYXlzdGFjaywgbmVlZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGhheXN0YWNrLmluZGV4T2YobmVlZGxlKSA+IC0xO1xufVxuLyoqXG4gKiBtYXRjaGVzUXVlcnkgLS0gRGV0ZXJtaW5lcyBpZiBhbiBvYmplY3Qgd291bGQgYmUgcmV0dXJuZWQgYnkgYSBQYXJzZSBRdWVyeVxuICogSXQncyBhIGxpZ2h0d2VpZ2h0LCB3aGVyZS1jbGF1c2Ugb25seSBpbXBsZW1lbnRhdGlvbiBvZiBhIGZ1bGwgcXVlcnkgZW5naW5lLlxuICogU2luY2Ugd2UgZmluZCBxdWVyaWVzIHRoYXQgbWF0Y2ggb2JqZWN0cywgcmF0aGVyIHRoYW4gb2JqZWN0cyB0aGF0IG1hdGNoXG4gKiBxdWVyaWVzLCB3ZSBjYW4gYXZvaWQgYnVpbGRpbmcgYSBmdWxsLWJsb3duIHF1ZXJ5IHRvb2wuXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNRdWVyeShvYmplY3Q6IGFueSwgcXVlcnk6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAocXVlcnkgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgIHZhciBjbGFzc05hbWUgPSBvYmplY3QuaWQgaW5zdGFuY2VvZiBJZCA/IG9iamVjdC5pZC5jbGFzc05hbWUgOiBvYmplY3QuY2xhc3NOYW1lO1xuICAgIGlmIChjbGFzc05hbWUgIT09IHF1ZXJ5LmNsYXNzTmFtZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hlc1F1ZXJ5KG9iamVjdCwgcXVlcnkuX3doZXJlKTtcbiAgfVxuICBmb3IgKHZhciBmaWVsZCBpbiBxdWVyeSkge1xuICAgIGlmICghbWF0Y2hlc0tleUNvbnN0cmFpbnRzKG9iamVjdCwgZmllbGQsIHF1ZXJ5W2ZpZWxkXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGVxdWFsT2JqZWN0c0dlbmVyaWMob2JqLCBjb21wYXJlVG8sIGVxbEZuKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGVxbEZuKG9ialtpXSwgY29tcGFyZVRvKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGVxbEZuKG9iaiwgY29tcGFyZVRvKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW4gb2JqZWN0IG1hdGNoZXMgYSBzaW5nbGUga2V5J3MgY29uc3RyYWludHNcbiAqL1xuZnVuY3Rpb24gbWF0Y2hlc0tleUNvbnN0cmFpbnRzKG9iamVjdCwga2V5LCBjb25zdHJhaW50cykge1xuICBpZiAoY29uc3RyYWludHMgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGtleS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgIC8vIEtleSByZWZlcmVuY2VzIGEgc3Vib2JqZWN0XG4gICAgdmFyIGtleUNvbXBvbmVudHMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICB2YXIgc3ViT2JqZWN0S2V5ID0ga2V5Q29tcG9uZW50c1swXTtcbiAgICB2YXIga2V5UmVtYWluZGVyID0ga2V5Q29tcG9uZW50cy5zbGljZSgxKS5qb2luKCcuJyk7XG4gICAgcmV0dXJuIG1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3Rbc3ViT2JqZWN0S2V5XSB8fCB7fSwga2V5UmVtYWluZGVyLCBjb25zdHJhaW50cyk7XG4gIH1cbiAgdmFyIGk7XG4gIGlmIChrZXkgPT09ICckb3InKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbnN0cmFpbnRzKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgY29uc3RyYWludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChtYXRjaGVzUXVlcnkob2JqZWN0LCBjb25zdHJhaW50c1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoa2V5ID09PSAnJGFuZCcpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29uc3RyYWludHMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCFtYXRjaGVzUXVlcnkob2JqZWN0LCBjb25zdHJhaW50c1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoa2V5ID09PSAnJG5vcicpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29uc3RyYWludHMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG1hdGNoZXNRdWVyeShvYmplY3QsIGNvbnN0cmFpbnRzW2ldKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChrZXkgPT09ICckcmVsYXRlZFRvJykge1xuICAgIC8vIEJhaWwhIFdlIGNhbid0IGhhbmRsZSByZWxhdGlvbmFsIHF1ZXJpZXMgbG9jYWxseVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBEZWNvZGUgRGF0ZSBKU09OIHZhbHVlXG4gIGlmIChvYmplY3Rba2V5XSAmJiBvYmplY3Rba2V5XS5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgb2JqZWN0W2tleV0gPSBuZXcgRGF0ZShvYmplY3Rba2V5XS5pc28pO1xuICB9XG4gIC8vIEVxdWFsaXR5IChvciBBcnJheSBjb250YWlucykgY2FzZXNcbiAgaWYgKHR5cGVvZiBjb25zdHJhaW50cyAhPT0gJ29iamVjdCcpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmplY3Rba2V5XSkpIHtcbiAgICAgIHJldHVybiBvYmplY3Rba2V5XS5pbmRleE9mKGNvbnN0cmFpbnRzKSA+IC0xO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IGNvbnN0cmFpbnRzO1xuICB9XG4gIHZhciBjb21wYXJlVG87XG4gIGlmIChjb25zdHJhaW50cy5fX3R5cGUpIHtcbiAgICBpZiAoY29uc3RyYWludHMuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIHJldHVybiBlcXVhbE9iamVjdHNHZW5lcmljKG9iamVjdFtrZXldLCBjb25zdHJhaW50cywgZnVuY3Rpb24gKG9iaiwgcHRyKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgdHlwZW9mIG9iaiAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICBwdHIuY2xhc3NOYW1lID09PSBvYmouY2xhc3NOYW1lICYmXG4gICAgICAgICAgcHRyLm9iamVjdElkID09PSBvYmoub2JqZWN0SWRcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBlcXVhbE9iamVjdHNHZW5lcmljKG9iamVjdFtrZXldLCBQYXJzZS5fZGVjb2RlKGtleSwgY29uc3RyYWludHMpLCBlcXVhbE9iamVjdHMpO1xuICB9XG4gIC8vIE1vcmUgY29tcGxleCBjYXNlc1xuICBmb3IgKHZhciBjb25kaXRpb24gaW4gY29uc3RyYWludHMpIHtcbiAgICBjb21wYXJlVG8gPSBjb25zdHJhaW50c1tjb25kaXRpb25dO1xuICAgIGlmIChjb21wYXJlVG8/Ll9fdHlwZSkge1xuICAgICAgY29tcGFyZVRvID0gUGFyc2UuX2RlY29kZShrZXksIGNvbXBhcmVUbyk7XG4gICAgfVxuICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7XG4gICAgICBjYXNlICckbHQnOlxuICAgICAgICBpZiAob2JqZWN0W2tleV0gPj0gY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGx0ZSc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA+IGNvbXBhcmVUbykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRndCc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA8PSBjb21wYXJlVG8pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckZ3RlJzpcbiAgICAgICAgaWYgKG9iamVjdFtrZXldIDwgY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGVxJzpcbiAgICAgICAgaWYgKCFlcXVhbE9iamVjdHMob2JqZWN0W2tleV0sIGNvbXBhcmVUbykpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbmUnOlxuICAgICAgICBpZiAoZXF1YWxPYmplY3RzKG9iamVjdFtrZXldLCBjb21wYXJlVG8pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGluJzpcbiAgICAgICAgaWYgKCFjb250YWlucyhjb21wYXJlVG8sIG9iamVjdFtrZXldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRuaW4nOlxuICAgICAgICBpZiAoY29udGFpbnMoY29tcGFyZVRvLCBvYmplY3Rba2V5XSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckYWxsJzpcbiAgICAgICAgaWYgKCFvYmplY3Rba2V5XSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29tcGFyZVRvLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKG9iamVjdFtrZXldLmluZGV4T2YoY29tcGFyZVRvW2ldKSA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckZXhpc3RzJzoge1xuICAgICAgICBjb25zdCBwcm9wZXJ0eUV4aXN0cyA9IHR5cGVvZiBvYmplY3Rba2V5XSAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGNvbnN0IGV4aXN0ZW5jZUlzUmVxdWlyZWQgPSBjb25zdHJhaW50c1snJGV4aXN0cyddO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnN0cmFpbnRzWyckZXhpc3RzJ10gIT09ICdib29sZWFuJykge1xuICAgICAgICAgIC8vIFRoZSBTREsgd2lsbCBuZXZlciBzdWJtaXQgYSBub24tYm9vbGVhbiBmb3IgJGV4aXN0cywgYnV0IGlmIHNvbWVvbmVcbiAgICAgICAgICAvLyB0cmllcyB0byBzdWJtaXQgYSBub24tYm9vbGVhbiBmb3IgJGV4aXRzIG91dHNpZGUgdGhlIFNES3MsIGp1c3QgaWdub3JlIGl0LlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoIXByb3BlcnR5RXhpc3RzICYmIGV4aXN0ZW5jZUlzUmVxdWlyZWQpIHx8IChwcm9wZXJ0eUV4aXN0cyAmJiAhZXhpc3RlbmNlSXNSZXF1aXJlZCkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckcmVnZXgnOiB7XG4gICAgICAgIGlmICh0eXBlb2YgY29tcGFyZVRvID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGlmICghc2FmZVJlZ2V4VGVzdChjb21wYXJlVG8uc291cmNlLCBjb21wYXJlVG8uZmxhZ3MsIG9iamVjdFtrZXldKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBKUyBkb2Vzbid0IHN1cHBvcnQgcGVybC1zdHlsZSBlc2NhcGluZ1xuICAgICAgICB2YXIgZXhwU3RyaW5nID0gJyc7XG4gICAgICAgIHZhciBlc2NhcGVFbmQgPSAtMjtcbiAgICAgICAgdmFyIGVzY2FwZVN0YXJ0ID0gY29tcGFyZVRvLmluZGV4T2YoJ1xcXFxRJyk7XG4gICAgICAgIHdoaWxlIChlc2NhcGVTdGFydCA+IC0xKSB7XG4gICAgICAgICAgLy8gQWRkIHRoZSB1bmVzY2FwZWQgcG9ydGlvblxuICAgICAgICAgIGV4cFN0cmluZyArPSBjb21wYXJlVG8uc3Vic3RyaW5nKGVzY2FwZUVuZCArIDIsIGVzY2FwZVN0YXJ0KTtcbiAgICAgICAgICBlc2NhcGVFbmQgPSBjb21wYXJlVG8uaW5kZXhPZignXFxcXEUnLCBlc2NhcGVTdGFydCk7XG4gICAgICAgICAgaWYgKGVzY2FwZUVuZCA+IC0xKSB7XG4gICAgICAgICAgICBleHBTdHJpbmcgKz0gY29tcGFyZVRvXG4gICAgICAgICAgICAgIC5zdWJzdHJpbmcoZXNjYXBlU3RhcnQgKyAyLCBlc2NhcGVFbmQpXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXFxcXFxcXFxcXFxcRS9nLCAnXFxcXEUnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXFxXL2csICdcXFxcJCYnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlc2NhcGVTdGFydCA9IGNvbXBhcmVUby5pbmRleE9mKCdcXFxcUScsIGVzY2FwZUVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwU3RyaW5nICs9IGNvbXBhcmVUby5zdWJzdHJpbmcoTWF0aC5tYXgoZXNjYXBlU3RhcnQsIGVzY2FwZUVuZCArIDIpKTtcbiAgICAgICAgaWYgKCFzYWZlUmVnZXhUZXN0KGV4cFN0cmluZywgY29uc3RyYWludHMuJG9wdGlvbnMgfHwgJycsIG9iamVjdFtrZXldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRuZWFyU3BoZXJlJzpcbiAgICAgICAgaWYgKCFjb21wYXJlVG8gfHwgIW9iamVjdFtrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkaXN0YW5jZSA9IGNvbXBhcmVUby5yYWRpYW5zVG8ob2JqZWN0W2tleV0pO1xuICAgICAgICB2YXIgbWF4ID0gY29uc3RyYWludHMuJG1heERpc3RhbmNlIHx8IEluZmluaXR5O1xuICAgICAgICByZXR1cm4gZGlzdGFuY2UgPD0gbWF4O1xuICAgICAgY2FzZSAnJHdpdGhpbic6XG4gICAgICAgIGlmICghY29tcGFyZVRvIHx8ICFvYmplY3Rba2V5XSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc291dGhXZXN0ID0gY29tcGFyZVRvLiRib3hbMF07XG4gICAgICAgIHZhciBub3J0aEVhc3QgPSBjb21wYXJlVG8uJGJveFsxXTtcbiAgICAgICAgaWYgKHNvdXRoV2VzdC5sYXRpdHVkZSA+IG5vcnRoRWFzdC5sYXRpdHVkZSB8fCBzb3V0aFdlc3QubG9uZ2l0dWRlID4gbm9ydGhFYXN0LmxvbmdpdHVkZSkge1xuICAgICAgICAgIC8vIEludmFsaWQgYm94LCBjcm9zc2VzIHRoZSBkYXRlIGxpbmVcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBvYmplY3Rba2V5XS5sYXRpdHVkZSA+IHNvdXRoV2VzdC5sYXRpdHVkZSAmJlxuICAgICAgICAgIG9iamVjdFtrZXldLmxhdGl0dWRlIDwgbm9ydGhFYXN0LmxhdGl0dWRlICYmXG4gICAgICAgICAgb2JqZWN0W2tleV0ubG9uZ2l0dWRlID4gc291dGhXZXN0LmxvbmdpdHVkZSAmJlxuICAgICAgICAgIG9iamVjdFtrZXldLmxvbmdpdHVkZSA8IG5vcnRoRWFzdC5sb25naXR1ZGVcbiAgICAgICAgKTtcbiAgICAgIGNhc2UgJyRjb250YWluZWRCeSc6IHtcbiAgICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiBvYmplY3Rba2V5XSkge1xuICAgICAgICAgIGlmICghY29udGFpbnMoY29tcGFyZVRvLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjYXNlICckZ2VvV2l0aGluJzoge1xuICAgICAgICBpZiAoY29tcGFyZVRvLiRwb2x5Z29uKSB7XG4gICAgICAgICAgY29uc3QgcG9pbnRzID0gY29tcGFyZVRvLiRwb2x5Z29uLm1hcChnZW9Qb2ludCA9PiBbXG4gICAgICAgICAgICBnZW9Qb2ludC5sYXRpdHVkZSxcbiAgICAgICAgICAgIGdlb1BvaW50LmxvbmdpdHVkZSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgICBjb25zdCBwb2x5Z29uID0gbmV3IFBhcnNlLlBvbHlnb24ocG9pbnRzKTtcbiAgICAgICAgICByZXR1cm4gcG9seWdvbi5jb250YWluc1BvaW50KG9iamVjdFtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tcGFyZVRvLiRjZW50ZXJTcGhlcmUpIHtcbiAgICAgICAgICBjb25zdCBbV0dTODRQb2ludCwgbWF4RGlzdGFuY2VdID0gY29tcGFyZVRvLiRjZW50ZXJTcGhlcmU7XG4gICAgICAgICAgY29uc3QgY2VudGVyUG9pbnQgPSBuZXcgUGFyc2UuR2VvUG9pbnQoe1xuICAgICAgICAgICAgbGF0aXR1ZGU6IFdHUzg0UG9pbnRbMV0sXG4gICAgICAgICAgICBsb25naXR1ZGU6IFdHUzg0UG9pbnRbMF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3QgcG9pbnQgPSBuZXcgUGFyc2UuR2VvUG9pbnQob2JqZWN0W2tleV0pO1xuICAgICAgICAgIGNvbnN0IGRpc3RhbmNlID0gcG9pbnQucmFkaWFuc1RvKGNlbnRlclBvaW50KTtcbiAgICAgICAgICByZXR1cm4gZGlzdGFuY2UgPD0gbWF4RGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckZ2VvSW50ZXJzZWN0cyc6IHtcbiAgICAgICAgY29uc3QgcG9seWdvbiA9IG5ldyBQYXJzZS5Qb2x5Z29uKG9iamVjdFtrZXldLmNvb3JkaW5hdGVzKTtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBuZXcgUGFyc2UuR2VvUG9pbnQoY29tcGFyZVRvLiRwb2ludCk7XG4gICAgICAgIHJldHVybiBwb2x5Z29uLmNvbnRhaW5zUG9pbnQocG9pbnQpO1xuICAgICAgfVxuICAgICAgY2FzZSAnJG9wdGlvbnMnOlxuICAgICAgICAvLyBOb3QgYSBxdWVyeSB0eXBlLCBidXQgYSB3YXkgdG8gYWRkIG9wdGlvbnMgdG8gJHJlZ2V4LiBJZ25vcmUgYW5kXG4gICAgICAgIC8vIGF2b2lkIHRoZSBkZWZhdWx0XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG1heERpc3RhbmNlJzpcbiAgICAgICAgLy8gTm90IGEgcXVlcnkgdHlwZSwgYnV0IGEgd2F5IHRvIGFkZCBhIGNhcCB0byAkbmVhclNwaGVyZS4gSWdub3JlIGFuZFxuICAgICAgICAvLyBhdm9pZCB0aGUgZGVmYXVsdFxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRzZWxlY3QnOlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBjYXNlICckZG9udFNlbGVjdCc6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbnZhciBRdWVyeVRvb2xzID0ge1xuICBxdWVyeUhhc2g6IHF1ZXJ5SGFzaCxcbiAgbWF0Y2hlc1F1ZXJ5OiBtYXRjaGVzUXVlcnksXG4gIHNldFJlZ2V4VGltZW91dDogc2V0UmVnZXhUaW1lb3V0LFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBRdWVyeVRvb2xzO1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLFlBQVksR0FBR0MsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzVDLElBQUlDLEVBQUUsR0FBR0QsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUN4QixJQUFJRSxLQUFLLEdBQUdGLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDakMsSUFBSUcsRUFBRSxHQUFHSCxPQUFPLENBQUMsSUFBSSxDQUFDO0FBQ3RCLElBQUlJLE1BQU0sR0FBR0osT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDSyxPQUFPO0FBRXpDLElBQUlDLFlBQVksR0FBRyxDQUFDO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUlDLFNBQVMsR0FBR0osRUFBRSxDQUFDSyxhQUFhLENBQUNDLE1BQU0sQ0FBQ0MsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3JELElBQUlDLFdBQVcsR0FBRyxJQUFJQyxHQUFHLENBQUMsQ0FBQztBQUMzQixJQUFJQyxnQkFBZ0IsR0FBRyxJQUFJO0FBRTNCLFNBQVNDLGVBQWVBLENBQUNDLEVBQUUsRUFBRTtFQUMzQlQsWUFBWSxHQUFHUyxFQUFFO0FBQ25COztBQUVBO0FBQ0EsU0FBU0MsYUFBYUEsQ0FBQ0MsT0FBTyxFQUFFQyxLQUFLLEVBQUVDLEtBQUssRUFBRTtFQUM1QyxJQUFJO0lBQ0YsSUFBSSxDQUFDYixZQUFZLEVBQUU7TUFDakIsSUFBSWMsRUFBRSxHQUFHLElBQUlDLE1BQU0sQ0FBQ0osT0FBTyxFQUFFQyxLQUFLLENBQUM7TUFDbkMsT0FBT0UsRUFBRSxDQUFDRSxJQUFJLENBQUNILEtBQUssQ0FBQztJQUN2QjtJQUNBLElBQUlJLFFBQVEsR0FBR0wsS0FBSyxHQUFHLEdBQUcsR0FBR0QsT0FBTztJQUNwQyxJQUFJTyxNQUFNLEdBQUdiLFdBQVcsQ0FBQ2MsR0FBRyxDQUFDRixRQUFRLENBQUM7SUFDdEMsSUFBSSxDQUFDQyxNQUFNLEVBQUU7TUFDWCxJQUFJYixXQUFXLENBQUNlLElBQUksSUFBSWIsZ0JBQWdCLEVBQUU7UUFBRUYsV0FBVyxDQUFDZ0IsS0FBSyxDQUFDLENBQUM7TUFBRTtNQUNqRUgsTUFBTSxHQUFHLElBQUlyQixFQUFFLENBQUN5QixNQUFNLENBQUMsd0NBQXdDLENBQUM7TUFDaEVqQixXQUFXLENBQUNrQixHQUFHLENBQUNOLFFBQVEsRUFBRUMsTUFBTSxDQUFDO0lBQ25DO0lBQ0FqQixTQUFTLENBQUNVLE9BQU8sR0FBR0EsT0FBTztJQUMzQlYsU0FBUyxDQUFDVyxLQUFLLEdBQUdBLEtBQUs7SUFDdkJYLFNBQVMsQ0FBQ1ksS0FBSyxHQUFHQSxLQUFLO0lBQ3ZCLE9BQU9LLE1BQU0sQ0FBQ00sWUFBWSxDQUFDdkIsU0FBUyxFQUFFO01BQUV3QixPQUFPLEVBQUV6QjtJQUFhLENBQUMsQ0FBQztFQUNsRSxDQUFDLENBQUMsT0FBTzBCLENBQUMsRUFBRTtJQUNWLElBQUlBLENBQUMsQ0FBQ0MsSUFBSSxLQUFLLDhCQUE4QixFQUFFO01BQzdDN0IsTUFBTSxDQUFDOEIsSUFBSSxDQUFDLDJCQUEyQmpCLE9BQU8saUJBQWlCQyxLQUFLLGNBQWNaLFlBQVksVUFBVSxDQUFDO0lBQzNHLENBQUMsTUFBTTtNQUNMRixNQUFNLENBQUM4QixJQUFJLENBQUMsMkJBQTJCakIsT0FBTyxpQkFBaUJDLEtBQUssTUFBTWMsQ0FBQyxDQUFDRyxPQUFPLEVBQUUsQ0FBQztJQUN4RjtJQUNBLE9BQU8sS0FBSztFQUNkO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVNDLGdCQUFnQkEsQ0FBQ0MsS0FBSyxFQUFFO0VBQy9CLElBQUksQ0FBQzVCLE1BQU0sQ0FBQzZCLFNBQVMsQ0FBQ0MsY0FBYyxDQUFDQyxJQUFJLENBQUNILEtBQUssRUFBRSxLQUFLLENBQUMsRUFBRTtJQUN2RCxPQUFPQSxLQUFLO0VBQ2Q7RUFDQSxJQUFJSSxLQUFLLEdBQUcsRUFBRTtFQUNkLEtBQUssSUFBSUMsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHTCxLQUFLLENBQUNNLEdBQUcsQ0FBQ0MsTUFBTSxFQUFFRixDQUFDLEVBQUUsRUFBRTtJQUN6Q0QsS0FBSyxHQUFHQSxLQUFLLENBQUNJLE1BQU0sQ0FBQ1IsS0FBSyxDQUFDTSxHQUFHLENBQUNELENBQUMsQ0FBQyxDQUFDO0VBQ3BDO0VBQ0EsT0FBT0QsS0FBSztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVNLLFNBQVNBLENBQUNDLE1BQU0sRUFBVTtFQUNqQyxJQUFJLE9BQU9BLE1BQU0sS0FBSyxRQUFRLElBQUlBLE1BQU0sS0FBSyxJQUFJLEVBQUU7SUFDakQsSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO01BQzlCLE9BQU8sR0FBRyxHQUFHQSxNQUFNLENBQUNDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRztJQUNoRDtJQUNBLE9BQU9ELE1BQU0sR0FBRyxFQUFFO0VBQ3BCO0VBQ0EsSUFBSUUsS0FBSyxDQUFDQyxPQUFPLENBQUNILE1BQU0sQ0FBQyxFQUFFO0lBQ3pCLElBQUlJLElBQUksR0FBR0osTUFBTSxDQUFDSyxHQUFHLENBQUNOLFNBQVMsQ0FBQztJQUNoQ0ssSUFBSSxDQUFDRSxJQUFJLENBQUMsQ0FBQztJQUNYLE9BQU8sR0FBRyxHQUFHRixJQUFJLENBQUNHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHO0VBQ25DO0VBQ0EsSUFBSUMsUUFBUSxHQUFHLEVBQUU7RUFDakIsSUFBSUMsSUFBSSxHQUFHL0MsTUFBTSxDQUFDK0MsSUFBSSxDQUFDVCxNQUFNLENBQUM7RUFDOUJTLElBQUksQ0FBQ0gsSUFBSSxDQUFDLENBQUM7RUFDWCxLQUFLLElBQUlJLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR0QsSUFBSSxDQUFDWixNQUFNLEVBQUVhLENBQUMsRUFBRSxFQUFFO0lBQ3BDRixRQUFRLENBQUNHLElBQUksQ0FBQ1osU0FBUyxDQUFDVSxJQUFJLENBQUNDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHWCxTQUFTLENBQUNDLE1BQU0sQ0FBQ1MsSUFBSSxDQUFDQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDdEU7RUFDQSxPQUFPLEdBQUcsR0FBR0YsUUFBUSxDQUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRztBQUN2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNLLFNBQVNBLENBQUNDLEtBQUssRUFBRTtFQUN4QixJQUFJQSxLQUFLLFlBQVkxRCxLQUFLLENBQUMyRCxLQUFLLEVBQUU7SUFDaENELEtBQUssR0FBRztNQUNORSxTQUFTLEVBQUVGLEtBQUssQ0FBQ0UsU0FBUztNQUMxQnpCLEtBQUssRUFBRXVCLEtBQUssQ0FBQ0c7SUFDZixDQUFDO0VBQ0g7RUFDQSxJQUFJMUIsS0FBSyxHQUFHRCxnQkFBZ0IsQ0FBQ3dCLEtBQUssQ0FBQ3ZCLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztFQUMvQyxJQUFJMkIsT0FBTyxHQUFHLEVBQUU7RUFDaEIsSUFBSUMsTUFBTSxHQUFHLEVBQUU7RUFDZixJQUFJdkIsQ0FBQztFQUNMLElBQUlPLEtBQUssQ0FBQ0MsT0FBTyxDQUFDYixLQUFLLENBQUMsRUFBRTtJQUN4QixJQUFJNkIsYUFBYSxHQUFHLENBQUMsQ0FBQztJQUN0QixLQUFLeEIsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHTCxLQUFLLENBQUNPLE1BQU0sRUFBRUYsQ0FBQyxFQUFFLEVBQUU7TUFDakMsSUFBSXlCLFNBQVMsR0FBRyxDQUFDLENBQUM7TUFDbEIsSUFBSVgsSUFBSSxHQUFHL0MsTUFBTSxDQUFDK0MsSUFBSSxDQUFDbkIsS0FBSyxDQUFDSyxDQUFDLENBQUMsQ0FBQztNQUNoQ2MsSUFBSSxDQUFDSCxJQUFJLENBQUMsQ0FBQztNQUNYLEtBQUssSUFBSWUsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHWixJQUFJLENBQUNaLE1BQU0sRUFBRXdCLENBQUMsRUFBRSxFQUFFO1FBQ3BDRCxTQUFTLENBQUNYLElBQUksQ0FBQ1ksQ0FBQyxDQUFDLENBQUMsR0FBRy9CLEtBQUssQ0FBQ0ssQ0FBQyxDQUFDLENBQUNjLElBQUksQ0FBQ1ksQ0FBQyxDQUFDLENBQUM7UUFDdENGLGFBQWEsQ0FBQ1YsSUFBSSxDQUFDWSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7TUFDL0I7TUFDQUgsTUFBTSxDQUFDUCxJQUFJLENBQUNTLFNBQVMsQ0FBQztJQUN4QjtJQUNBSCxPQUFPLEdBQUd2RCxNQUFNLENBQUMrQyxJQUFJLENBQUNVLGFBQWEsQ0FBQztJQUNwQ0YsT0FBTyxDQUFDWCxJQUFJLENBQUMsQ0FBQztFQUNoQixDQUFDLE1BQU07SUFDTFcsT0FBTyxHQUFHdkQsTUFBTSxDQUFDK0MsSUFBSSxDQUFDbkIsS0FBSyxDQUFDO0lBQzVCMkIsT0FBTyxDQUFDWCxJQUFJLENBQUMsQ0FBQztJQUNkLEtBQUtYLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR3NCLE9BQU8sQ0FBQ3BCLE1BQU0sRUFBRUYsQ0FBQyxFQUFFLEVBQUU7TUFDbkN1QixNQUFNLENBQUNQLElBQUksQ0FBQ3JCLEtBQUssQ0FBQzJCLE9BQU8sQ0FBQ3RCLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEM7RUFDRjtFQUVBLElBQUlhLFFBQVEsR0FBRyxDQUFDUyxPQUFPLENBQUNWLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRVIsU0FBUyxDQUFDbUIsTUFBTSxDQUFDLENBQUM7RUFFckQsT0FBT0wsS0FBSyxDQUFDRSxTQUFTLEdBQUcsR0FBRyxHQUFHUCxRQUFRLENBQUNELElBQUksQ0FBQyxHQUFHLENBQUM7QUFDbkQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBU2UsUUFBUUEsQ0FBQ0MsUUFBZSxFQUFFQyxNQUFXLEVBQVc7RUFDdkQsSUFBSUEsTUFBTSxJQUFJQSxNQUFNLENBQUNDLE1BQU0sSUFBSUQsTUFBTSxDQUFDQyxNQUFNLEtBQUssU0FBUyxFQUFFO0lBQzFELEtBQUssTUFBTTlCLENBQUMsSUFBSTRCLFFBQVEsRUFBRTtNQUN4QixNQUFNRyxHQUFHLEdBQUdILFFBQVEsQ0FBQzVCLENBQUMsQ0FBQztNQUN2QixJQUFJLE9BQU8rQixHQUFHLEtBQUssUUFBUSxJQUFJQSxHQUFHLEtBQUtGLE1BQU0sQ0FBQ0csUUFBUSxFQUFFO1FBQ3RELE9BQU8sSUFBSTtNQUNiO01BQ0EsSUFBSUQsR0FBRyxDQUFDWCxTQUFTLEtBQUtTLE1BQU0sQ0FBQ1QsU0FBUyxJQUFJVyxHQUFHLENBQUNDLFFBQVEsS0FBS0gsTUFBTSxDQUFDRyxRQUFRLEVBQUU7UUFDMUUsT0FBTyxJQUFJO01BQ2I7SUFDRjtJQUVBLE9BQU8sS0FBSztFQUNkO0VBRUEsSUFBSXpCLEtBQUssQ0FBQ0MsT0FBTyxDQUFDcUIsTUFBTSxDQUFDLEVBQUU7SUFDekIsS0FBSyxNQUFNSSxJQUFJLElBQUlKLE1BQU0sRUFBRTtNQUN6QixJQUFJRixRQUFRLENBQUNDLFFBQVEsRUFBRUssSUFBSSxDQUFDLEVBQUU7UUFDNUIsT0FBTyxJQUFJO01BQ2I7SUFDRjtFQUNGO0VBRUEsT0FBT0wsUUFBUSxDQUFDTSxPQUFPLENBQUNMLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNNLFlBQVlBLENBQUM5QixNQUFXLEVBQUVhLEtBQVUsRUFBVztFQUN0RCxJQUFJQSxLQUFLLFlBQVkxRCxLQUFLLENBQUMyRCxLQUFLLEVBQUU7SUFDaEMsSUFBSUMsU0FBUyxHQUFHZixNQUFNLENBQUMrQixFQUFFLFlBQVk3RSxFQUFFLEdBQUc4QyxNQUFNLENBQUMrQixFQUFFLENBQUNoQixTQUFTLEdBQUdmLE1BQU0sQ0FBQ2UsU0FBUztJQUNoRixJQUFJQSxTQUFTLEtBQUtGLEtBQUssQ0FBQ0UsU0FBUyxFQUFFO01BQ2pDLE9BQU8sS0FBSztJQUNkO0lBQ0EsT0FBT2UsWUFBWSxDQUFDOUIsTUFBTSxFQUFFYSxLQUFLLENBQUNHLE1BQU0sQ0FBQztFQUMzQztFQUNBLEtBQUssSUFBSWdCLEtBQUssSUFBSW5CLEtBQUssRUFBRTtJQUN2QixJQUFJLENBQUNvQixxQkFBcUIsQ0FBQ2pDLE1BQU0sRUFBRWdDLEtBQUssRUFBRW5CLEtBQUssQ0FBQ21CLEtBQUssQ0FBQyxDQUFDLEVBQUU7TUFDdkQsT0FBTyxLQUFLO0lBQ2Q7RUFDRjtFQUNBLE9BQU8sSUFBSTtBQUNiO0FBRUEsU0FBU0UsbUJBQW1CQSxDQUFDQyxHQUFHLEVBQUVDLFNBQVMsRUFBRUMsS0FBSyxFQUFFO0VBQ2xELElBQUluQyxLQUFLLENBQUNDLE9BQU8sQ0FBQ2dDLEdBQUcsQ0FBQyxFQUFFO0lBQ3RCLEtBQUssSUFBSXhDLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR3dDLEdBQUcsQ0FBQ3RDLE1BQU0sRUFBRUYsQ0FBQyxFQUFFLEVBQUU7TUFDbkMsSUFBSTBDLEtBQUssQ0FBQ0YsR0FBRyxDQUFDeEMsQ0FBQyxDQUFDLEVBQUV5QyxTQUFTLENBQUMsRUFBRTtRQUM1QixPQUFPLElBQUk7TUFDYjtJQUNGO0lBQ0EsT0FBTyxLQUFLO0VBQ2Q7RUFFQSxPQUFPQyxLQUFLLENBQUNGLEdBQUcsRUFBRUMsU0FBUyxDQUFDO0FBQzlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVNILHFCQUFxQkEsQ0FBQ2pDLE1BQU0sRUFBRXNDLEdBQUcsRUFBRUMsV0FBVyxFQUFFO0VBQ3ZELElBQUlBLFdBQVcsS0FBSyxJQUFJLEVBQUU7SUFDeEIsT0FBTyxLQUFLO0VBQ2Q7RUFDQSxJQUFJRCxHQUFHLENBQUNULE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7SUFDekI7SUFDQSxJQUFJVyxhQUFhLEdBQUdGLEdBQUcsQ0FBQ0csS0FBSyxDQUFDLEdBQUcsQ0FBQztJQUNsQyxJQUFJQyxZQUFZLEdBQUdGLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDbkMsSUFBSUcsWUFBWSxHQUFHSCxhQUFhLENBQUNJLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQ3JDLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDbkQsT0FBTzBCLHFCQUFxQixDQUFDakMsTUFBTSxDQUFDMEMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUVDLFlBQVksRUFBRUosV0FBVyxDQUFDO0VBQ3JGO0VBQ0EsSUFBSTVDLENBQUM7RUFDTCxJQUFJMkMsR0FBRyxLQUFLLEtBQUssRUFBRTtJQUNqQixJQUFJLENBQUNwQyxLQUFLLENBQUNDLE9BQU8sQ0FBQ29DLFdBQVcsQ0FBQyxFQUFFO01BQy9CLE9BQU8sS0FBSztJQUNkO0lBQ0EsS0FBSzVDLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBRzRDLFdBQVcsQ0FBQzFDLE1BQU0sRUFBRUYsQ0FBQyxFQUFFLEVBQUU7TUFDdkMsSUFBSW1DLFlBQVksQ0FBQzlCLE1BQU0sRUFBRXVDLFdBQVcsQ0FBQzVDLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDeEMsT0FBTyxJQUFJO01BQ2I7SUFDRjtJQUNBLE9BQU8sS0FBSztFQUNkO0VBQ0EsSUFBSTJDLEdBQUcsS0FBSyxNQUFNLEVBQUU7SUFDbEIsSUFBSSxDQUFDcEMsS0FBSyxDQUFDQyxPQUFPLENBQUNvQyxXQUFXLENBQUMsRUFBRTtNQUMvQixPQUFPLEtBQUs7SUFDZDtJQUNBLEtBQUs1QyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUc0QyxXQUFXLENBQUMxQyxNQUFNLEVBQUVGLENBQUMsRUFBRSxFQUFFO01BQ3ZDLElBQUksQ0FBQ21DLFlBQVksQ0FBQzlCLE1BQU0sRUFBRXVDLFdBQVcsQ0FBQzVDLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDekMsT0FBTyxLQUFLO01BQ2Q7SUFDRjtJQUNBLE9BQU8sSUFBSTtFQUNiO0VBQ0EsSUFBSTJDLEdBQUcsS0FBSyxNQUFNLEVBQUU7SUFDbEIsSUFBSSxDQUFDcEMsS0FBSyxDQUFDQyxPQUFPLENBQUNvQyxXQUFXLENBQUMsRUFBRTtNQUMvQixPQUFPLEtBQUs7SUFDZDtJQUNBLEtBQUs1QyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUc0QyxXQUFXLENBQUMxQyxNQUFNLEVBQUVGLENBQUMsRUFBRSxFQUFFO01BQ3ZDLElBQUltQyxZQUFZLENBQUM5QixNQUFNLEVBQUV1QyxXQUFXLENBQUM1QyxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQ3hDLE9BQU8sS0FBSztNQUNkO0lBQ0Y7SUFDQSxPQUFPLElBQUk7RUFDYjtFQUNBLElBQUkyQyxHQUFHLEtBQUssWUFBWSxFQUFFO0lBQ3hCO0lBQ0EsT0FBTyxLQUFLO0VBQ2Q7RUFDQTtFQUNBLElBQUl0QyxNQUFNLENBQUNzQyxHQUFHLENBQUMsSUFBSXRDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxDQUFDYixNQUFNLElBQUksTUFBTSxFQUFFO0lBQy9DekIsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLEdBQUcsSUFBSU8sSUFBSSxDQUFDN0MsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUNRLEdBQUcsQ0FBQztFQUN6QztFQUNBO0VBQ0EsSUFBSSxPQUFPUCxXQUFXLEtBQUssUUFBUSxFQUFFO0lBQ25DLElBQUlyQyxLQUFLLENBQUNDLE9BQU8sQ0FBQ0gsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUMsRUFBRTtNQUM5QixPQUFPdEMsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUNULE9BQU8sQ0FBQ1UsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlDO0lBQ0EsT0FBT3ZDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxLQUFLQyxXQUFXO0VBQ3BDO0VBQ0EsSUFBSUgsU0FBUztFQUNiLElBQUlHLFdBQVcsQ0FBQ2QsTUFBTSxFQUFFO0lBQ3RCLElBQUljLFdBQVcsQ0FBQ2QsTUFBTSxLQUFLLFNBQVMsRUFBRTtNQUNwQyxPQUFPUyxtQkFBbUIsQ0FBQ2xDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxFQUFFQyxXQUFXLEVBQUUsVUFBVUosR0FBRyxFQUFFVCxHQUFHLEVBQUU7UUFDdkUsT0FDRSxPQUFPUyxHQUFHLEtBQUssV0FBVyxJQUMxQlQsR0FBRyxDQUFDWCxTQUFTLEtBQUtvQixHQUFHLENBQUNwQixTQUFTLElBQy9CVyxHQUFHLENBQUNDLFFBQVEsS0FBS1EsR0FBRyxDQUFDUixRQUFRO01BRWpDLENBQUMsQ0FBQztJQUNKO0lBRUEsT0FBT08sbUJBQW1CLENBQUNsQyxNQUFNLENBQUNzQyxHQUFHLENBQUMsRUFBRW5GLEtBQUssQ0FBQzRGLE9BQU8sQ0FBQ1QsR0FBRyxFQUFFQyxXQUFXLENBQUMsRUFBRXZGLFlBQVksQ0FBQztFQUN4RjtFQUNBO0VBQ0EsS0FBSyxJQUFJZ0csU0FBUyxJQUFJVCxXQUFXLEVBQUU7SUFDakNILFNBQVMsR0FBR0csV0FBVyxDQUFDUyxTQUFTLENBQUM7SUFDbEMsSUFBSVosU0FBUyxFQUFFWCxNQUFNLEVBQUU7TUFDckJXLFNBQVMsR0FBR2pGLEtBQUssQ0FBQzRGLE9BQU8sQ0FBQ1QsR0FBRyxFQUFFRixTQUFTLENBQUM7SUFDM0M7SUFDQSxRQUFRWSxTQUFTO01BQ2YsS0FBSyxLQUFLO1FBQ1IsSUFBSWhELE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxJQUFJRixTQUFTLEVBQUU7VUFDNUIsT0FBTyxLQUFLO1FBQ2Q7UUFDQTtNQUNGLEtBQUssTUFBTTtRQUNULElBQUlwQyxNQUFNLENBQUNzQyxHQUFHLENBQUMsR0FBR0YsU0FBUyxFQUFFO1VBQzNCLE9BQU8sS0FBSztRQUNkO1FBQ0E7TUFDRixLQUFLLEtBQUs7UUFDUixJQUFJcEMsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLElBQUlGLFNBQVMsRUFBRTtVQUM1QixPQUFPLEtBQUs7UUFDZDtRQUNBO01BQ0YsS0FBSyxNQUFNO1FBQ1QsSUFBSXBDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxHQUFHRixTQUFTLEVBQUU7VUFDM0IsT0FBTyxLQUFLO1FBQ2Q7UUFDQTtNQUNGLEtBQUssS0FBSztRQUNSLElBQUksQ0FBQ3BGLFlBQVksQ0FBQ2dELE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxFQUFFRixTQUFTLENBQUMsRUFBRTtVQUN6QyxPQUFPLEtBQUs7UUFDZDtRQUNBO01BQ0YsS0FBSyxLQUFLO1FBQ1IsSUFBSXBGLFlBQVksQ0FBQ2dELE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxFQUFFRixTQUFTLENBQUMsRUFBRTtVQUN4QyxPQUFPLEtBQUs7UUFDZDtRQUNBO01BQ0YsS0FBSyxLQUFLO1FBQ1IsSUFBSSxDQUFDZCxRQUFRLENBQUNjLFNBQVMsRUFBRXBDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7VUFDckMsT0FBTyxLQUFLO1FBQ2Q7UUFDQTtNQUNGLEtBQUssTUFBTTtRQUNULElBQUloQixRQUFRLENBQUNjLFNBQVMsRUFBRXBDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7VUFDcEMsT0FBTyxLQUFLO1FBQ2Q7UUFDQTtNQUNGLEtBQUssTUFBTTtRQUNULElBQUksQ0FBQ3RDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxFQUFFO1VBQ2hCLE9BQU8sS0FBSztRQUNkO1FBQ0EsS0FBSzNDLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR3lDLFNBQVMsQ0FBQ3ZDLE1BQU0sRUFBRUYsQ0FBQyxFQUFFLEVBQUU7VUFDckMsSUFBSUssTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUNULE9BQU8sQ0FBQ08sU0FBUyxDQUFDekMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDekMsT0FBTyxLQUFLO1VBQ2Q7UUFDRjtRQUNBO01BQ0YsS0FBSyxTQUFTO1FBQUU7VUFDZCxNQUFNc0QsY0FBYyxHQUFHLE9BQU9qRCxNQUFNLENBQUNzQyxHQUFHLENBQUMsS0FBSyxXQUFXO1VBQ3pELE1BQU1ZLG1CQUFtQixHQUFHWCxXQUFXLENBQUMsU0FBUyxDQUFDO1VBQ2xELElBQUksT0FBT0EsV0FBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLFNBQVMsRUFBRTtZQUMvQztZQUNBO1lBQ0E7VUFDRjtVQUNBLElBQUssQ0FBQ1UsY0FBYyxJQUFJQyxtQkFBbUIsSUFBTUQsY0FBYyxJQUFJLENBQUNDLG1CQUFvQixFQUFFO1lBQ3hGLE9BQU8sS0FBSztVQUNkO1VBQ0E7UUFDRjtNQUNBLEtBQUssUUFBUTtRQUFFO1VBQ2IsSUFBSSxPQUFPZCxTQUFTLEtBQUssUUFBUSxFQUFFO1lBQ2pDLElBQUksQ0FBQ25FLGFBQWEsQ0FBQ21FLFNBQVMsQ0FBQ2UsTUFBTSxFQUFFZixTQUFTLENBQUNqRSxLQUFLLEVBQUU2QixNQUFNLENBQUNzQyxHQUFHLENBQUMsQ0FBQyxFQUFFO2NBQ2xFLE9BQU8sS0FBSztZQUNkO1lBQ0E7VUFDRjtVQUNBO1VBQ0EsSUFBSWMsU0FBUyxHQUFHLEVBQUU7VUFDbEIsSUFBSUMsU0FBUyxHQUFHLENBQUMsQ0FBQztVQUNsQixJQUFJQyxXQUFXLEdBQUdsQixTQUFTLENBQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUM7VUFDMUMsT0FBT3lCLFdBQVcsR0FBRyxDQUFDLENBQUMsRUFBRTtZQUN2QjtZQUNBRixTQUFTLElBQUloQixTQUFTLENBQUNtQixTQUFTLENBQUNGLFNBQVMsR0FBRyxDQUFDLEVBQUVDLFdBQVcsQ0FBQztZQUM1REQsU0FBUyxHQUFHakIsU0FBUyxDQUFDUCxPQUFPLENBQUMsS0FBSyxFQUFFeUIsV0FBVyxDQUFDO1lBQ2pELElBQUlELFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRTtjQUNsQkQsU0FBUyxJQUFJaEIsU0FBUyxDQUNuQm1CLFNBQVMsQ0FBQ0QsV0FBVyxHQUFHLENBQUMsRUFBRUQsU0FBUyxDQUFDLENBQ3JDcEQsT0FBTyxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FDNUJBLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDO1lBQzNCO1lBRUFxRCxXQUFXLEdBQUdsQixTQUFTLENBQUNQLE9BQU8sQ0FBQyxLQUFLLEVBQUV3QixTQUFTLENBQUM7VUFDbkQ7VUFDQUQsU0FBUyxJQUFJaEIsU0FBUyxDQUFDbUIsU0FBUyxDQUFDQyxJQUFJLENBQUNDLEdBQUcsQ0FBQ0gsV0FBVyxFQUFFRCxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUM7VUFDdEUsSUFBSSxDQUFDcEYsYUFBYSxDQUFDbUYsU0FBUyxFQUFFYixXQUFXLENBQUNtQixRQUFRLElBQUksRUFBRSxFQUFFMUQsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUMsRUFBRTtZQUN0RSxPQUFPLEtBQUs7VUFDZDtVQUNBO1FBQ0Y7TUFDQSxLQUFLLGFBQWE7UUFDaEIsSUFBSSxDQUFDRixTQUFTLElBQUksQ0FBQ3BDLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxFQUFFO1VBQzlCLE9BQU8sS0FBSztRQUNkO1FBQ0EsSUFBSXFCLFFBQVEsR0FBR3ZCLFNBQVMsQ0FBQ3dCLFNBQVMsQ0FBQzVELE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxDQUFDO1FBQy9DLElBQUltQixHQUFHLEdBQUdsQixXQUFXLENBQUNzQixZQUFZLElBQUlDLFFBQVE7UUFDOUMsT0FBT0gsUUFBUSxJQUFJRixHQUFHO01BQ3hCLEtBQUssU0FBUztRQUNaLElBQUksQ0FBQ3JCLFNBQVMsSUFBSSxDQUFDcEMsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLEVBQUU7VUFDOUIsT0FBTyxLQUFLO1FBQ2Q7UUFDQSxJQUFJeUIsU0FBUyxHQUFHM0IsU0FBUyxDQUFDNEIsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNqQyxJQUFJQyxTQUFTLEdBQUc3QixTQUFTLENBQUM0QixJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUlELFNBQVMsQ0FBQ0csUUFBUSxHQUFHRCxTQUFTLENBQUNDLFFBQVEsSUFBSUgsU0FBUyxDQUFDSSxTQUFTLEdBQUdGLFNBQVMsQ0FBQ0UsU0FBUyxFQUFFO1VBQ3hGO1VBQ0EsT0FBTyxLQUFLO1FBQ2Q7UUFDQSxPQUNFbkUsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUM0QixRQUFRLEdBQUdILFNBQVMsQ0FBQ0csUUFBUSxJQUN6Q2xFLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxDQUFDNEIsUUFBUSxHQUFHRCxTQUFTLENBQUNDLFFBQVEsSUFDekNsRSxNQUFNLENBQUNzQyxHQUFHLENBQUMsQ0FBQzZCLFNBQVMsR0FBR0osU0FBUyxDQUFDSSxTQUFTLElBQzNDbkUsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUM2QixTQUFTLEdBQUdGLFNBQVMsQ0FBQ0UsU0FBUztNQUUvQyxLQUFLLGNBQWM7UUFBRTtVQUNuQixLQUFLLE1BQU1DLEtBQUssSUFBSXBFLE1BQU0sQ0FBQ3NDLEdBQUcsQ0FBQyxFQUFFO1lBQy9CLElBQUksQ0FBQ2hCLFFBQVEsQ0FBQ2MsU0FBUyxFQUFFZ0MsS0FBSyxDQUFDLEVBQUU7Y0FDL0IsT0FBTyxLQUFLO1lBQ2Q7VUFDRjtVQUNBLE9BQU8sSUFBSTtRQUNiO01BQ0EsS0FBSyxZQUFZO1FBQUU7VUFDakIsSUFBSWhDLFNBQVMsQ0FBQ2lDLFFBQVEsRUFBRTtZQUN0QixNQUFNQyxNQUFNLEdBQUdsQyxTQUFTLENBQUNpQyxRQUFRLENBQUNoRSxHQUFHLENBQUNrRSxRQUFRLElBQUksQ0FDaERBLFFBQVEsQ0FBQ0wsUUFBUSxFQUNqQkssUUFBUSxDQUFDSixTQUFTLENBQ25CLENBQUM7WUFDRixNQUFNSyxPQUFPLEdBQUcsSUFBSXJILEtBQUssQ0FBQ3NILE9BQU8sQ0FBQ0gsTUFBTSxDQUFDO1lBQ3pDLE9BQU9FLE9BQU8sQ0FBQ0UsYUFBYSxDQUFDMUUsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUM7VUFDM0M7VUFDQSxJQUFJRixTQUFTLENBQUN1QyxhQUFhLEVBQUU7WUFDM0IsTUFBTSxDQUFDQyxVQUFVLEVBQUVDLFdBQVcsQ0FBQyxHQUFHekMsU0FBUyxDQUFDdUMsYUFBYTtZQUN6RCxNQUFNRyxXQUFXLEdBQUcsSUFBSTNILEtBQUssQ0FBQzRILFFBQVEsQ0FBQztjQUNyQ2IsUUFBUSxFQUFFVSxVQUFVLENBQUMsQ0FBQyxDQUFDO2NBQ3ZCVCxTQUFTLEVBQUVTLFVBQVUsQ0FBQyxDQUFDO1lBQ3pCLENBQUMsQ0FBQztZQUNGLE1BQU1JLEtBQUssR0FBRyxJQUFJN0gsS0FBSyxDQUFDNEgsUUFBUSxDQUFDL0UsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUM7WUFDN0MsTUFBTXFCLFFBQVEsR0FBR3FCLEtBQUssQ0FBQ3BCLFNBQVMsQ0FBQ2tCLFdBQVcsQ0FBQztZQUM3QyxPQUFPbkIsUUFBUSxJQUFJa0IsV0FBVztVQUNoQztVQUNBO1FBQ0Y7TUFDQSxLQUFLLGdCQUFnQjtRQUFFO1VBQ3JCLE1BQU1MLE9BQU8sR0FBRyxJQUFJckgsS0FBSyxDQUFDc0gsT0FBTyxDQUFDekUsTUFBTSxDQUFDc0MsR0FBRyxDQUFDLENBQUMyQyxXQUFXLENBQUM7VUFDMUQsTUFBTUQsS0FBSyxHQUFHLElBQUk3SCxLQUFLLENBQUM0SCxRQUFRLENBQUMzQyxTQUFTLENBQUM4QyxNQUFNLENBQUM7VUFDbEQsT0FBT1YsT0FBTyxDQUFDRSxhQUFhLENBQUNNLEtBQUssQ0FBQztRQUNyQztNQUNBLEtBQUssVUFBVTtRQUNiO1FBQ0E7UUFDQTtNQUNGLEtBQUssY0FBYztRQUNqQjtRQUNBO1FBQ0E7TUFDRixLQUFLLFNBQVM7UUFDWixPQUFPLEtBQUs7TUFDZCxLQUFLLGFBQWE7UUFDaEIsT0FBTyxLQUFLO01BQ2Q7UUFDRSxPQUFPLEtBQUs7SUFDaEI7RUFDRjtFQUNBLE9BQU8sSUFBSTtBQUNiO0FBRUEsSUFBSUcsVUFBVSxHQUFHO0VBQ2Z2RSxTQUFTLEVBQUVBLFNBQVM7RUFDcEJrQixZQUFZLEVBQUVBLFlBQVk7RUFDMUIvRCxlQUFlLEVBQUVBO0FBQ25CLENBQUM7QUFFRHFILE1BQU0sQ0FBQ0MsT0FBTyxHQUFHRixVQUFVIiwiaWdub3JlTGlzdCI6W119
|