postgraphile 4.13.0 → 5.0.0-0.10

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.
Files changed (134) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/LICENSE.md +15 -20
  3. package/README.md +15 -170
  4. package/dist/cli-run.d.ts +3 -0
  5. package/dist/cli-run.d.ts.map +1 -0
  6. package/dist/cli-run.js +7 -0
  7. package/dist/cli-run.js.map +1 -0
  8. package/dist/cli.d.ts +21 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +199 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/index.d.ts +14 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +88 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/plugins/PgV4BehaviorPlugin.d.ts +11 -0
  17. package/dist/plugins/PgV4BehaviorPlugin.d.ts.map +1 -0
  18. package/dist/plugins/PgV4BehaviorPlugin.js +73 -0
  19. package/dist/plugins/PgV4BehaviorPlugin.js.map +1 -0
  20. package/dist/plugins/PgV4InflectionPlugin.d.ts +11 -0
  21. package/dist/plugins/PgV4InflectionPlugin.d.ts.map +1 -0
  22. package/dist/plugins/PgV4InflectionPlugin.js +91 -0
  23. package/dist/plugins/PgV4InflectionPlugin.js.map +1 -0
  24. package/dist/plugins/PgV4NoIgnoreIndexes.d.ts +2 -0
  25. package/dist/plugins/PgV4NoIgnoreIndexes.d.ts.map +1 -0
  26. package/dist/plugins/PgV4NoIgnoreIndexes.js +72 -0
  27. package/dist/plugins/PgV4NoIgnoreIndexes.js.map +1 -0
  28. package/dist/plugins/PgV4SmartTagsPlugin.d.ts +11 -0
  29. package/dist/plugins/PgV4SmartTagsPlugin.d.ts.map +1 -0
  30. package/dist/plugins/PgV4SmartTagsPlugin.js +190 -0
  31. package/dist/plugins/PgV4SmartTagsPlugin.js.map +1 -0
  32. package/dist/presets/amber.d.ts +5 -0
  33. package/dist/presets/amber.d.ts.map +1 -0
  34. package/dist/presets/amber.js +38 -0
  35. package/dist/presets/amber.js.map +1 -0
  36. package/dist/presets/v4.d.ts +34 -0
  37. package/dist/presets/v4.d.ts.map +1 -0
  38. package/dist/presets/v4.js +142 -0
  39. package/dist/presets/v4.js.map +1 -0
  40. package/dist/schema.d.ts +34 -0
  41. package/dist/schema.d.ts.map +1 -0
  42. package/dist/schema.js +82 -0
  43. package/dist/schema.js.map +1 -0
  44. package/package.json +79 -154
  45. package/build/assets/favicon.ico.d.ts +0 -3
  46. package/build/assets/favicon.ico.js +0 -6
  47. package/build/assets/graphiql.html.d.ts +0 -2
  48. package/build/assets/graphiql.html.js +0 -6
  49. package/build/index.d.ts +0 -8
  50. package/build/index.js +0 -34
  51. package/build/interfaces.d.ts +0 -163
  52. package/build/interfaces.js +0 -3
  53. package/build/plugins.d.ts +0 -3
  54. package/build/plugins.js +0 -53
  55. package/build/postgraphile/cli.d.ts +0 -3
  56. package/build/postgraphile/cli.js +0 -541
  57. package/build/postgraphile/extendedFormatError.d.ts +0 -9
  58. package/build/postgraphile/extendedFormatError.js +0 -51
  59. package/build/postgraphile/http/createPostGraphileHttpRequestHandler.d.ts +0 -11
  60. package/build/postgraphile/http/createPostGraphileHttpRequestHandler.js +0 -976
  61. package/build/postgraphile/http/frameworks.d.ts +0 -110
  62. package/build/postgraphile/http/frameworks.js +0 -258
  63. package/build/postgraphile/http/liveSubscribe.d.ts +0 -22
  64. package/build/postgraphile/http/liveSubscribe.js +0 -89
  65. package/build/postgraphile/http/mapAsyncIterator.d.ts +0 -15
  66. package/build/postgraphile/http/mapAsyncIterator.js +0 -71
  67. package/build/postgraphile/http/setupServerSentEvents.d.ts +0 -9
  68. package/build/postgraphile/http/setupServerSentEvents.js +0 -51
  69. package/build/postgraphile/http/subscriptions.d.ts +0 -7
  70. package/build/postgraphile/http/subscriptions.js +0 -411
  71. package/build/postgraphile/index.d.ts +0 -5
  72. package/build/postgraphile/index.js +0 -14
  73. package/build/postgraphile/pluginHook.d.ts +0 -104
  74. package/build/postgraphile/pluginHook.js +0 -100
  75. package/build/postgraphile/postgraphile.d.ts +0 -20
  76. package/build/postgraphile/postgraphile.js +0 -332
  77. package/build/postgraphile/postgraphilerc.d.ts +0 -2
  78. package/build/postgraphile/postgraphilerc.js +0 -16
  79. package/build/postgraphile/schema/exportPostGraphileSchema.d.ts +0 -6
  80. package/build/postgraphile/schema/exportPostGraphileSchema.js +0 -45
  81. package/build/postgraphile/shutdownActions.d.ts +0 -41
  82. package/build/postgraphile/shutdownActions.js +0 -87
  83. package/build/postgraphile/withPostGraphileContext.d.ts +0 -55
  84. package/build/postgraphile/withPostGraphileContext.js +0 -457
  85. package/build/postgres/inventory/pgClientFromContext.d.ts +0 -8
  86. package/build/postgres/inventory/pgClientFromContext.js +0 -21
  87. package/build-turbo/assets/favicon.ico.d.ts +0 -3
  88. package/build-turbo/assets/favicon.ico.js +0 -6
  89. package/build-turbo/assets/graphiql.html.d.ts +0 -2
  90. package/build-turbo/assets/graphiql.html.js +0 -6
  91. package/build-turbo/index.d.ts +0 -8
  92. package/build-turbo/index.js +0 -34
  93. package/build-turbo/interfaces.d.ts +0 -163
  94. package/build-turbo/interfaces.js +0 -3
  95. package/build-turbo/plugins.d.ts +0 -3
  96. package/build-turbo/plugins.js +0 -53
  97. package/build-turbo/postgraphile/cli.d.ts +0 -3
  98. package/build-turbo/postgraphile/cli.js +0 -572
  99. package/build-turbo/postgraphile/extendedFormatError.d.ts +0 -9
  100. package/build-turbo/postgraphile/extendedFormatError.js +0 -61
  101. package/build-turbo/postgraphile/http/createPostGraphileHttpRequestHandler.d.ts +0 -11
  102. package/build-turbo/postgraphile/http/createPostGraphileHttpRequestHandler.js +0 -984
  103. package/build-turbo/postgraphile/http/frameworks.d.ts +0 -110
  104. package/build-turbo/postgraphile/http/frameworks.js +0 -258
  105. package/build-turbo/postgraphile/http/liveSubscribe.d.ts +0 -22
  106. package/build-turbo/postgraphile/http/liveSubscribe.js +0 -89
  107. package/build-turbo/postgraphile/http/mapAsyncIterator.d.ts +0 -15
  108. package/build-turbo/postgraphile/http/mapAsyncIterator.js +0 -71
  109. package/build-turbo/postgraphile/http/setupServerSentEvents.d.ts +0 -9
  110. package/build-turbo/postgraphile/http/setupServerSentEvents.js +0 -51
  111. package/build-turbo/postgraphile/http/subscriptions.d.ts +0 -7
  112. package/build-turbo/postgraphile/http/subscriptions.js +0 -410
  113. package/build-turbo/postgraphile/index.d.ts +0 -5
  114. package/build-turbo/postgraphile/index.js +0 -14
  115. package/build-turbo/postgraphile/pluginHook.d.ts +0 -104
  116. package/build-turbo/postgraphile/pluginHook.js +0 -100
  117. package/build-turbo/postgraphile/postgraphile.d.ts +0 -20
  118. package/build-turbo/postgraphile/postgraphile.js +0 -337
  119. package/build-turbo/postgraphile/postgraphilerc.d.ts +0 -2
  120. package/build-turbo/postgraphile/postgraphilerc.js +0 -16
  121. package/build-turbo/postgraphile/schema/exportPostGraphileSchema.d.ts +0 -6
  122. package/build-turbo/postgraphile/schema/exportPostGraphileSchema.js +0 -45
  123. package/build-turbo/postgraphile/shutdownActions.d.ts +0 -41
  124. package/build-turbo/postgraphile/shutdownActions.js +0 -87
  125. package/build-turbo/postgraphile/withPostGraphileContext.d.ts +0 -55
  126. package/build-turbo/postgraphile/withPostGraphileContext.js +0 -466
  127. package/build-turbo/postgres/inventory/pgClientFromContext.d.ts +0 -8
  128. package/build-turbo/postgres/inventory/pgClientFromContext.js +0 -21
  129. package/cli.js +0 -6
  130. package/index.js +0 -5
  131. package/isTurbo.js +0 -11
  132. package/plugins.d.ts +0 -1
  133. package/plugins.js +0 -5
  134. package/sponsors.json +0 -151
@@ -1,984 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEmpty = void 0;
4
- /* eslint-disable @typescript-eslint/no-explicit-any,require-atomic-updates */
5
- const graphql_1 = require("graphql");
6
- const extendedFormatError_1 = require("../extendedFormatError");
7
- const pluginHook_1 = require("../pluginHook");
8
- const setupServerSentEvents_1 = require("./setupServerSentEvents");
9
- const withPostGraphileContext_1 = require("../withPostGraphileContext");
10
- const lru_1 = require("@graphile/lru");
11
- const chalk_1 = require("chalk");
12
- const Debugger = require("debug"); // tslint:disable-line variable-name
13
- const httpError = require("http-errors");
14
- const parseUrl = require("parseurl");
15
- const finalHandler = require("finalhandler");
16
- const bodyParser = require("body-parser");
17
- const crypto = require("crypto");
18
- const isKoaApp = (a, b) => a.req && a.res && typeof b === 'function';
19
- const CACHE_MULTIPLIER = 100000;
20
- const ALLOW_EXPLAIN_PLACEHOLDER = '__SHOULD_ALLOW_EXPLAIN__';
21
- const noop = () => {
22
- /* noop */
23
- };
24
- const { createHash } = crypto;
25
- /**
26
- * The favicon file in `Buffer` format. We can send a `Buffer` directly to the
27
- * client.
28
- *
29
- * @type {Buffer}
30
- */
31
- const favicon_ico_1 = require("../../assets/favicon.ico");
32
- /**
33
- * The GraphiQL HTML file as a string. We need it to be a string, because we
34
- * will use a regular expression to replace some variables.
35
- */
36
- const graphiql_html_1 = require("../../assets/graphiql.html");
37
- const subscriptions_1 = require("./subscriptions");
38
- const frameworks_1 = require("./frameworks");
39
- /**
40
- * When writing JSON to the browser, we need to be careful that it doesn't get
41
- * interpretted as HTML.
42
- */
43
- const JS_ESCAPE_LOOKUP = {
44
- '<': '\\u003c',
45
- '>': '\\u003e',
46
- '/': '\\u002f',
47
- '\u2028': '\\u2028',
48
- '\u2029': '\\u2029',
49
- };
50
- function safeJSONStringify(obj) {
51
- return JSON.stringify(obj).replace(/[<>/\u2028\u2029]/g, chr => JS_ESCAPE_LOOKUP[chr]);
52
- }
53
- /**
54
- * When people webpack us up, e.g. for lambda, if they don't want GraphiQL then
55
- * they can seriously reduce bundle size by omitting the assets.
56
- */
57
- const shouldOmitAssets = process.env.POSTGRAPHILE_OMIT_ASSETS === '1';
58
- // Used by `createPostGraphileHttpRequestHandler`
59
- let lastString;
60
- let lastHash;
61
- const calculateQueryHash = (queryString) => {
62
- if (queryString !== lastString) {
63
- lastString = queryString;
64
- lastHash = createHash('sha1').update(queryString).digest('base64');
65
- }
66
- return lastHash;
67
- };
68
- // Fast way of checking if an object is empty,
69
- // faster than `Object.keys(value).length === 0`.
70
- // NOTE: we don't need a `hasOwnProperty` call here because isEmpty is called
71
- // with an `Object.create(null)` object, so it has no no-own properties.
72
- /* tslint:disable forin */
73
- function isEmpty(value) {
74
- for (const _key in value) {
75
- return false;
76
- }
77
- return true;
78
- }
79
- exports.isEmpty = isEmpty;
80
- /* tslint:enable forin */
81
- const isPostGraphileDevelopmentMode = process.env.POSTGRAPHILE_ENV === 'development';
82
- const debugGraphql = Debugger('postgraphile:graphql');
83
- const debugRequest = Debugger('postgraphile:request');
84
- /**
85
- * We need to be able to share the withPostGraphileContext logic between HTTP
86
- * and websockets
87
- */
88
- function withPostGraphileContextFromReqResGenerator(options) {
89
- const { pgSettings: pgSettingsGenerator, allowExplain: allowExplainGenerator, jwtSecret, jwtPublicKey, additionalGraphQLContextFromRequest, } = options;
90
- return async (req, res, moreOptions, fn) => {
91
- const jwtVerificationSecret = jwtPublicKey || jwtSecret;
92
- const jwtToken = jwtVerificationSecret ? getJwtToken(req) : null;
93
- const additionalContext = typeof additionalGraphQLContextFromRequest === 'function'
94
- ? await additionalGraphQLContextFromRequest(req, res)
95
- : null;
96
- const pgSettings = typeof pgSettingsGenerator === 'function'
97
- ? await pgSettingsGenerator(req)
98
- : pgSettingsGenerator;
99
- const allowExplain = typeof allowExplainGenerator === 'function'
100
- ? await allowExplainGenerator(req)
101
- : allowExplainGenerator;
102
- return withPostGraphileContext_1.default({
103
- ...options,
104
- jwtToken,
105
- pgSettings,
106
- explain: allowExplain && req.headers['x-postgraphile-explain'] === 'on',
107
- ...moreOptions,
108
- }, context => {
109
- const graphqlContext = additionalContext
110
- ? { ...additionalContext, ...context }
111
- : context;
112
- return fn(graphqlContext);
113
- });
114
- };
115
- }
116
- /**
117
- * Creates a GraphQL request handler that can support many different `http` frameworks, including:
118
- *
119
- * - Native Node.js `http`.
120
- * - `connect`.
121
- * - `express`.
122
- * - `koa` (2.0).
123
- */
124
- function createPostGraphileHttpRequestHandler(options) {
125
- const MEGABYTE = 1024 * 1024;
126
- const subscriptions = !!options.subscriptions;
127
- const { getGqlSchema, pgPool, pgSettings, pgDefaultRole, shutdownActions, queryCacheMaxSize = 50 * MEGABYTE, extendedErrors, showErrorStack, watchPg, disableQueryLog, enableQueryBatching, websockets = options.subscriptions || options.live ? ['v0', 'v1'] : [], } = options;
128
- const live = !!options.live;
129
- const enhanceGraphiql = options.enhanceGraphiql === false ? false : !!options.enhanceGraphiql || subscriptions || live;
130
- const enableCors = !!options.enableCors || isPostGraphileDevelopmentMode;
131
- const graphiql = options.graphiql === true;
132
- if (options['absoluteRoutes']) {
133
- throw new Error('Sorry - the `absoluteRoutes` setting has been replaced with `externalUrlBase` which solves the issue in a cleaner way. Please update your settings. Thank you for testing a PostGraphile pre-release 🙏');
134
- }
135
- // Using let because we might override it on the first request.
136
- let externalUrlBase = options.externalUrlBase;
137
- if (externalUrlBase && externalUrlBase.endsWith('/')) {
138
- throw new Error('externalUrlBase must not end with a slash (`/`)');
139
- }
140
- // Validate websockets argument
141
- if (
142
- // must be array
143
- !Array.isArray(websockets) ||
144
- // empty array = 'none'
145
- (websockets.length &&
146
- // array can only hold the versions
147
- websockets.some(ver => !['v0', 'v1'].includes(ver)))) {
148
- throw new Error(`Invalid value for \`websockets\` option: '${websockets}'`);
149
- }
150
- const pluginHook = pluginHook_1.pluginHookFromOptions(options);
151
- const origGraphiqlHtml = pluginHook('postgraphile:graphiql:html', graphiql_html_1.default, { options });
152
- if (pgDefaultRole && typeof pgSettings === 'function') {
153
- throw new Error('pgDefaultRole cannot be combined with pgSettings(req) - please remove pgDefaultRole and instead always return a `role` key from pgSettings(req).');
154
- }
155
- if (pgDefaultRole &&
156
- pgSettings &&
157
- typeof pgSettings === 'object' &&
158
- Object.keys(pgSettings)
159
- .map(s => s.toLowerCase())
160
- .includes('role')) {
161
- throw new Error('pgDefaultRole cannot be combined with pgSettings.role - please use one or the other.');
162
- }
163
- if (graphiql && shouldOmitAssets) {
164
- throw new Error('Cannot enable GraphiQL when POSTGRAPHILE_OMIT_ASSETS is set');
165
- }
166
- // Gets the route names for our GraphQL endpoint, and our GraphiQL endpoint.
167
- const graphqlRoute = options.graphqlRoute || '/graphql';
168
- const graphiqlRoute = options.graphiqlRoute || '/graphiql';
169
- // Set the request credential behavior in graphiql.
170
- const graphiqlCredentials = options.graphiqlCredentials || 'same-origin';
171
- const eventStreamRoute = options.eventStreamRoute || `${graphqlRoute.replace(/\/+$/, '')}/stream`;
172
- const externalGraphqlRoute = options.externalGraphqlRoute;
173
- const externalEventStreamRoute = options.externalEventStreamRoute ||
174
- (externalGraphqlRoute && !options.eventStreamRoute
175
- ? `${externalGraphqlRoute.replace(/\/+$/, '')}/stream`
176
- : undefined);
177
- // Throw an error of the GraphQL and GraphiQL routes are the same.
178
- if (graphqlRoute === graphiqlRoute)
179
- throw new Error(`Cannot use the same route, '${graphqlRoute}', for both GraphQL and GraphiQL. Please use different routes.`);
180
- // Formats an error using the default GraphQL `formatError` function, and
181
- // custom formatting using some other options.
182
- const formatError = (error) => {
183
- // Get the appropriate formatted error object, including any extended error
184
- // fields if the user wants them.
185
- const formattedError = extendedErrors && extendedErrors.length
186
- ? extendedFormatError_1.extendedFormatError(error, extendedErrors)
187
- : graphql_1.formatError(error);
188
- // If the user wants to see the error’s stack, let’s add it to the
189
- // formatted error.
190
- if (showErrorStack)
191
- formattedError['stack'] =
192
- error.stack != null && showErrorStack === 'json' ? error.stack.split('\n') : error.stack;
193
- return formattedError;
194
- };
195
- const DEFAULT_HANDLE_ERRORS = (errors) => errors.map(formatError);
196
- const handleErrors = options.handleErrors || DEFAULT_HANDLE_ERRORS;
197
- // Define a list of middlewares that will get run before our request handler.
198
- // Note though that none of these middlewares will intercept a request (i.e.
199
- // not call `next`). Middlewares that handle a request like favicon
200
- // middleware will result in a promise that never resolves, and we don’t
201
- // want that.
202
- const bodyParserMiddlewares = [
203
- // Parse JSON bodies.
204
- bodyParser.json({ limit: options.bodySizeLimit }),
205
- // Parse URL encoded bodies (forms).
206
- bodyParser.urlencoded({ extended: false, limit: options.bodySizeLimit }),
207
- // Parse `application/graphql` content type bodies as text.
208
- bodyParser.text({ type: 'application/graphql', limit: options.bodySizeLimit }),
209
- ];
210
- // We'll turn this into one function now so it can be better JIT optimised
211
- const bodyParserMiddlewaresComposed = bodyParserMiddlewares.reduce((parent, fn) => {
212
- return (req, res, next) => {
213
- parent(req, res, error => {
214
- if (error) {
215
- return next(error);
216
- }
217
- fn(req, res, next);
218
- });
219
- };
220
- }, (_req, _res, next) => next());
221
- // And we really want that function to be await-able
222
- const parseBody = (req, res) => new Promise((resolve, reject) => {
223
- bodyParserMiddlewaresComposed(req,
224
- // Note: middleware here doesn't actually use the response, but we pass
225
- // the underlying value so types match up.
226
- res.getNodeServerResponse(), (error) => {
227
- if (error) {
228
- reject(error);
229
- }
230
- else {
231
- resolve();
232
- }
233
- });
234
- });
235
- // We only need to calculate the graphiql HTML once; but we need to receive the first request to do so.
236
- let graphiqlHtml;
237
- const withPostGraphileContextFromReqRes = withPostGraphileContextFromReqResGenerator(options);
238
- const staticValidationRules = pluginHook('postgraphile:validationRules:static', graphql_1.specifiedRules, {
239
- options,
240
- });
241
- const cacheSize = Math.ceil(queryCacheMaxSize / CACHE_MULTIPLIER);
242
- // Do not create an LRU for cache size < 2 because @graphile/lru will baulk.
243
- const cacheEnabled = cacheSize >= 2;
244
- const queryCache = cacheEnabled ? new lru_1.default({ maxLength: cacheSize }) : null;
245
- let lastGqlSchema;
246
- const parseQuery = (gqlSchema, queryString) => {
247
- if (gqlSchema !== lastGqlSchema) {
248
- if (queryCache) {
249
- queryCache.reset();
250
- }
251
- lastGqlSchema = gqlSchema;
252
- }
253
- // Only cache queries that are less than 100kB, we don't want DOS attacks
254
- // attempting to exhaust our memory.
255
- const canCache = cacheEnabled && queryString.length < 100000;
256
- const hash = canCache ? calculateQueryHash(queryString) : null;
257
- const result = canCache ? queryCache.get(hash) : null;
258
- if (result) {
259
- return result;
260
- }
261
- else {
262
- const source = new graphql_1.Source(queryString, 'GraphQL Http Request');
263
- let queryDocumentAst;
264
- // Catch an errors while parsing so that we can set the `statusCode` to
265
- // 400. Otherwise we don’t need to parse this way.
266
- try {
267
- queryDocumentAst = graphql_1.parse(source);
268
- }
269
- catch (error) {
270
- error.statusCode = 400;
271
- throw error;
272
- }
273
- if (debugRequest.enabled)
274
- debugRequest('GraphQL query is parsed.');
275
- // Validate our GraphQL query using given rules.
276
- const validationErrors = graphql_1.validate(gqlSchema, queryDocumentAst, staticValidationRules);
277
- const cacheResult = {
278
- queryDocumentAst,
279
- validationErrors,
280
- length: queryString.length,
281
- };
282
- if (canCache) {
283
- queryCache.set(hash, cacheResult);
284
- }
285
- return cacheResult;
286
- }
287
- };
288
- let firstRequestHandler = req => {
289
- // Never be called again
290
- firstRequestHandler = null;
291
- let graphqlRouteForWs = graphqlRoute;
292
- const parsed = parseUrl(req) || { pathname: '' };
293
- const pathname = parsed && typeof parsed.pathname === 'string' ? parsed.pathname : '';
294
- const parsed2 = parseUrl.original(req) || { pathname: '' };
295
- const originalPathname = parsed2 && typeof parsed2.pathname === 'string' ? parsed2.pathname : '';
296
- if (originalPathname !== pathname && originalPathname.endsWith(pathname)) {
297
- const base = originalPathname.slice(0, originalPathname.length - pathname.length);
298
- // Our websocket GraphQL route must be at a different place
299
- graphqlRouteForWs = base + graphqlRouteForWs;
300
- if (externalUrlBase == null) {
301
- // User hasn't specified externalUrlBase; let's try and guess it
302
- // We were mounted on a subpath (e.g. `app.use('/path/to', postgraphile(...))`).
303
- // Figure out our externalUrlBase for ourselves.
304
- externalUrlBase = base;
305
- }
306
- }
307
- // Make sure we have a string, at least
308
- externalUrlBase = externalUrlBase || '';
309
- // Takes the original GraphiQL HTML file and replaces the default config object.
310
- graphiqlHtml = origGraphiqlHtml
311
- ? origGraphiqlHtml.replace(/<\/head>/, ` <script>window.POSTGRAPHILE_CONFIG=${safeJSONStringify({
312
- graphqlUrl: externalGraphqlRoute || `${externalUrlBase}${graphqlRoute}`,
313
- streamUrl: watchPg
314
- ? externalEventStreamRoute || `${externalUrlBase}${eventStreamRoute}`
315
- : null,
316
- enhanceGraphiql,
317
- // if 'v1' websockets are included, use the v1 client always
318
- websockets: !websockets.length ? 'none' : websockets.includes('v1') ? 'v1' : 'v0',
319
- allowExplain: typeof options.allowExplain === 'function'
320
- ? ALLOW_EXPLAIN_PLACEHOLDER
321
- : !!options.allowExplain,
322
- credentials: graphiqlCredentials,
323
- })};</script>\n </head>`)
324
- : null;
325
- if (websockets.length) {
326
- const server = req && req.connection && req.connection['server'];
327
- if (!server) {
328
- // tslint:disable-next-line no-console
329
- console.warn("Failed to find server to add websocket listener to, you'll need to call `enhanceHttpServerWithWebSockets` manually");
330
- }
331
- else {
332
- // Relying on this means that a normal request must come in before an
333
- // upgrade attempt. It's better to call it manually.
334
- subscriptions_1.enhanceHttpServerWithWebSockets(server, middleware, {
335
- graphqlRoute: graphqlRouteForWs,
336
- });
337
- }
338
- }
339
- };
340
- /*
341
- * If we're not in watch mode, then avoid the cost of `await`ing the schema
342
- * on every tick by having it available once it was generated.
343
- */
344
- let theOneAndOnlyGraphQLSchema = null;
345
- if (!watchPg) {
346
- getGqlSchema()
347
- .then(schema => {
348
- theOneAndOnlyGraphQLSchema = schema;
349
- })
350
- .catch(noop);
351
- }
352
- function neverReject(middlewareName, middleware) {
353
- return async (res) => {
354
- try {
355
- await middleware(res);
356
- }
357
- catch (e) {
358
- console.error(`An unexpected error occurred whilst processing '${middlewareName}'; this indicates a bug. The connection will be terminated.`);
359
- console.error(e);
360
- try {
361
- // At least terminate the connection
362
- res.statusCode = 500;
363
- res.end();
364
- }
365
- catch (e) {
366
- /*NOOP*/
367
- }
368
- }
369
- };
370
- }
371
- /**
372
- * The actual request handler. It’s an async function so it will return a
373
- * promise when complete. If the function doesn’t handle anything, it calls
374
- * `next` to let the next middleware try and handle it. If the function
375
- * throws an error, it's up to the wrapping middleware (imaginatively named
376
- * `middleware`, below) to handle the error. Frameworks like Koa have
377
- * middlewares reject a promise on error, whereas Express requires you pass
378
- * the error to the `next(err)` function.
379
- */
380
- const requestHandler = async (responseHandler, next) => {
381
- const res = responseHandler;
382
- const incomingReq = res.getNodeServerRequest();
383
- const nodeRes = res.getNodeServerResponse();
384
- // You can use this hook either to modify the incoming request or to tell
385
- // PostGraphile not to handle the request further (return null). NOTE: if
386
- // you return `null` from this hook then you are also responsible for
387
- // calling `next()` (should that be required).
388
- const req = pluginHook('postgraphile:http:handler', incomingReq, {
389
- options,
390
- res: nodeRes,
391
- next,
392
- });
393
- if (req == null) {
394
- return;
395
- }
396
- const { pathname = '' } = parseUrl(req) || {};
397
- // Certain things depend on externalUrlBase, which we guess if the user
398
- // doesn't supply it, so we calculate them on the first request. After
399
- // first request, this function becomes a NOOP
400
- if (firstRequestHandler)
401
- firstRequestHandler(req);
402
- // ======================================================================
403
- // GraphQL Watch Stream
404
- // ======================================================================
405
- if (watchPg) {
406
- // Setup an event stream so we can broadcast events to graphiql, etc.
407
- if (pathname === eventStreamRoute || pathname === '/_postgraphile/stream') {
408
- return eventStreamRouteHandler(res);
409
- }
410
- }
411
- const isGraphqlRoute = pathname === graphqlRoute;
412
- // ========================================================================
413
- // Serve GraphiQL and Related Assets
414
- // ========================================================================
415
- if (!shouldOmitAssets && graphiql && !isGraphqlRoute) {
416
- // ======================================================================
417
- // Favicon
418
- // ======================================================================
419
- // If this is the favicon path and it has not yet been handled, let us
420
- // serve our GraphQL favicon.
421
- if (pathname === '/favicon.ico') {
422
- return faviconRouteHandler(res);
423
- }
424
- // ======================================================================
425
- // GraphiQL HTML
426
- // ======================================================================
427
- // If this is the GraphiQL route, show GraphiQL and stop execution.
428
- if (pathname === graphiqlRoute) {
429
- // If we are developing PostGraphile, instead just redirect.
430
- if (isPostGraphileDevelopmentMode) {
431
- res.statusCode = 302;
432
- res.setHeader('Location', 'http://localhost:5783');
433
- res.end();
434
- return;
435
- }
436
- return graphiqlRouteHandler(res);
437
- }
438
- }
439
- if (isGraphqlRoute) {
440
- return graphqlRouteHandler(res);
441
- }
442
- else {
443
- // This request wasn't for us.
444
- return next();
445
- }
446
- };
447
- const eventStreamRouteHandler = neverReject('eventStreamRouteHandler', async function eventStreamRouteHandler(res) {
448
- try {
449
- // You can use this hook either to modify the incoming request or to tell
450
- // PostGraphile not to handle the request further (return null). NOTE: if
451
- // you return `null` from this hook then you are also responsible for
452
- // terminating the request however your framework handles that (e.g.
453
- // `res.send(...)` or `next()`).
454
- const req = pluginHook('postgraphile:http:eventStreamRouteHandler', res.getNodeServerRequest(), { options, response: res });
455
- if (req == null) {
456
- return;
457
- }
458
- // Add our CORS headers to be good web citizens (there are perf
459
- // implications though so be careful!)
460
- //
461
- // Always enable CORS when developing PostGraphile because GraphiQL will be
462
- // on port 5783.
463
- if (enableCors)
464
- addCORSHeaders(res);
465
- if (req.headers.accept !== 'text/event-stream') {
466
- res.statusCode = 405;
467
- res.end();
468
- return;
469
- }
470
- setupServerSentEvents_1.default(res, options);
471
- }
472
- catch (e) {
473
- console.error('Unexpected error occurred in eventStreamRouteHandler');
474
- console.error(e);
475
- res.statusCode = 500;
476
- res.end();
477
- }
478
- });
479
- const faviconRouteHandler = neverReject('faviconRouteHandler', async function faviconRouteHandler(res) {
480
- // You can use this hook either to modify the incoming request or to tell
481
- // PostGraphile not to handle the request further (return null). NOTE: if
482
- // you return `null` from this hook then you are also responsible for
483
- // terminating the request however your framework handles that (e.g.
484
- // `res.send(...)` or `next()`).
485
- const req = pluginHook('postgraphile:http:faviconRouteHandler', res.getNodeServerRequest(), {
486
- options,
487
- response: res,
488
- });
489
- if (req == null) {
490
- return;
491
- }
492
- // If this is the wrong method, we should let the client know.
493
- if (!(req.method === 'GET' || req.method === 'HEAD')) {
494
- res.statusCode = req.method === 'OPTIONS' ? 200 : 405;
495
- res.setHeader('Allow', 'GET, HEAD, OPTIONS');
496
- res.end();
497
- return;
498
- }
499
- // Otherwise we are good and should pipe the favicon to the browser.
500
- res.statusCode = 200;
501
- res.setHeader('Cache-Control', 'public, max-age=86400');
502
- res.setHeader('Content-Type', 'image/x-icon');
503
- // End early if the method is `HEAD`.
504
- if (req.method === 'HEAD') {
505
- res.end();
506
- return;
507
- }
508
- res.end(favicon_ico_1.default);
509
- });
510
- const graphiqlRouteHandler = neverReject('graphiqlRouteHandler', async function graphiqlRouteHandler(res) {
511
- // You can use this hook either to modify the incoming request or to tell
512
- // PostGraphile not to handle the request further (return null). NOTE: if
513
- // you return `null` from this hook then you are also responsible for
514
- // terminating the request however your framework handles that (e.g.
515
- // `res.send(...)` or `next()`).
516
- const req = pluginHook('postgraphile:http:graphiqlRouteHandler', res.getNodeServerRequest(), {
517
- options,
518
- response: res,
519
- });
520
- if (req == null) {
521
- return;
522
- }
523
- if (firstRequestHandler)
524
- firstRequestHandler(req);
525
- // If using the incorrect method, let the user know.
526
- if (!(req.method === 'GET' || req.method === 'HEAD')) {
527
- res.statusCode = req.method === 'OPTIONS' ? 200 : 405;
528
- res.setHeader('Allow', 'GET, HEAD, OPTIONS');
529
- res.end();
530
- return;
531
- }
532
- res.statusCode = 200;
533
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
534
- res.setHeader('X-Frame-Options', 'SAMEORIGIN');
535
- res.setHeader('Content-Security-Policy', "frame-ancestors 'self'");
536
- // End early if the method is `HEAD`.
537
- if (req.method === 'HEAD') {
538
- res.end();
539
- return;
540
- }
541
- // Actually renders GraphiQL.
542
- if (graphiqlHtml && typeof options.allowExplain === 'function') {
543
- res.end(graphiqlHtml.replace(`"${ALLOW_EXPLAIN_PLACEHOLDER}"`, // Because JSON escaped
544
- JSON.stringify(!!(await options.allowExplain(req)))));
545
- }
546
- else {
547
- res.end(graphiqlHtml);
548
- }
549
- });
550
- const graphqlRouteHandler = neverReject('graphqlRouteHandler', async function graphqlRouteHandler(res) {
551
- // You can use this hook either to modify the incoming request or to tell
552
- // PostGraphile not to handle the request further (return null). NOTE: if
553
- // you return `null` from this hook then you are also responsible for
554
- // terminating the request however your framework handles that (e.g.
555
- // `res.send(...)` or `next()`).
556
- const req = pluginHook('postgraphile:http:graphqlRouteHandler', res.getNodeServerRequest(), {
557
- options,
558
- response: res,
559
- });
560
- if (req == null) {
561
- return;
562
- }
563
- if (firstRequestHandler)
564
- firstRequestHandler(req);
565
- // Add our CORS headers to be good web citizens (there are perf
566
- // implications though so be careful!)
567
- //
568
- // Always enable CORS when developing PostGraphile because GraphiQL will be
569
- // on port 5783.
570
- if (enableCors)
571
- addCORSHeaders(res);
572
- // ========================================================================
573
- // Execute GraphQL Queries
574
- // ========================================================================
575
- // If we didn’t call `next` above, all requests will return 200 by default!
576
- res.statusCode = 200;
577
- if (watchPg) {
578
- // Inform GraphiQL and other clients that they can subscribe to events
579
- // (such as the schema being updated) at the following URL
580
- res.setHeader('X-GraphQL-Event-Stream', externalEventStreamRoute || `${externalUrlBase}${eventStreamRoute}`);
581
- }
582
- // Don’t execute our GraphQL stuffs for `OPTIONS` requests.
583
- if (req.method === 'OPTIONS') {
584
- res.statusCode = 200;
585
- res.end();
586
- return;
587
- }
588
- // The `result` will be used at the very end in our `finally` block.
589
- // Statements inside the `try` will assign to `result` when they get
590
- // a result. We also keep track of `params`.
591
- let paramsList;
592
- let results = [];
593
- const queryTimeStart = !disableQueryLog && process.hrtime();
594
- let pgRole;
595
- if (debugRequest.enabled)
596
- debugRequest('GraphQL query request has begun.');
597
- let returnArray = false;
598
- // This big `try`/`catch`/`finally` block represents the execution of our
599
- // GraphQL query. All errors thrown in this block will be returned to the
600
- // client as GraphQL errors.
601
- try {
602
- // First thing we need to do is get the GraphQL schema for this request.
603
- // It should never really change unless we are in watch mode.
604
- const gqlSchema = theOneAndOnlyGraphQLSchema || (await getGqlSchema());
605
- // Note that we run our middleware after we make sure we are on the
606
- // correct route. This is so that if our middleware modifies the `req` or
607
- // `res` objects, only we downstream will see the modifications.
608
- //
609
- // We also run our middleware inside the `try` so that we get the GraphQL
610
- // error reporting style for syntax errors.
611
- await parseBody(req, res);
612
- // If this is not one of the correct methods, throw an error.
613
- if (req.method !== 'POST') {
614
- res.setHeader('Allow', 'POST, OPTIONS');
615
- throw httpError(405, 'Only `POST` requests are allowed.');
616
- }
617
- // Get the parameters we will use to run a GraphQL request. `params` may
618
- // include:
619
- //
620
- // - `query`: The required GraphQL query string.
621
- // - `variables`: An optional JSON object containing GraphQL variables.
622
- // - `operationName`: The optional name of the GraphQL operation we will
623
- // be executing.
624
- const body = req.body;
625
- paramsList = typeof body === 'string' ? { query: body } : body;
626
- // Validate our paramsList object a bit.
627
- if (paramsList == null)
628
- throw httpError(400, 'Must provide an object parameters, not nullish value.');
629
- if (typeof paramsList !== 'object')
630
- throw httpError(400, `Expected parameter object, not value of type '${typeof paramsList}'.`);
631
- if (Array.isArray(paramsList)) {
632
- if (!enableQueryBatching) {
633
- throw httpError(501, 'Batching queries as an array is currently unsupported. Please provide a single query object.');
634
- }
635
- else {
636
- returnArray = true;
637
- }
638
- }
639
- else {
640
- paramsList = [paramsList];
641
- }
642
- paramsList = pluginHook('postgraphile:httpParamsList', paramsList, {
643
- options,
644
- req,
645
- res,
646
- returnArray,
647
- httpError,
648
- });
649
- results = await Promise.all(paramsList.map(async (params) => {
650
- let queryDocumentAst = null;
651
- let result;
652
- const meta = Object.create(null);
653
- try {
654
- if (!params)
655
- throw httpError(400, 'Invalid query structure.');
656
- const { query, operationName } = params;
657
- let { variables } = params;
658
- if (!query)
659
- throw httpError(400, 'Must provide a query string.');
660
- // If variables is a string, we assume it is a JSON string and that it
661
- // needs to be parsed.
662
- if (typeof variables === 'string') {
663
- // If variables is just an empty string, we should set it to null and
664
- // ignore it.
665
- if (variables === '') {
666
- variables = null;
667
- }
668
- else {
669
- // Otherwise, let us try to parse it as JSON.
670
- try {
671
- variables = JSON.parse(variables);
672
- }
673
- catch (error) {
674
- error.statusCode = 400;
675
- throw error;
676
- }
677
- }
678
- }
679
- // Throw an error if `variables` is not an object.
680
- if (variables != null && typeof variables !== 'object')
681
- throw httpError(400, `Variables must be an object, not '${typeof variables}'.`);
682
- // Throw an error if `operationName` is not a string.
683
- if (operationName != null && typeof operationName !== 'string')
684
- throw httpError(400, `Operation name must be a string, not '${typeof operationName}'.`);
685
- let validationErrors;
686
- ({ queryDocumentAst, validationErrors } = parseQuery(gqlSchema, query));
687
- if (validationErrors.length === 0) {
688
- // You are strongly encouraged to use
689
- // `postgraphile:validationRules:static` if possible - you should
690
- // only use this one if you need access to variables.
691
- const moreValidationRules = pluginHook('postgraphile:validationRules', [], {
692
- options,
693
- req,
694
- res,
695
- variables,
696
- operationName,
697
- meta,
698
- });
699
- if (moreValidationRules.length) {
700
- validationErrors = graphql_1.validate(gqlSchema, queryDocumentAst, moreValidationRules);
701
- }
702
- }
703
- // If we have some validation errors, don’t execute the query. Instead
704
- // send the errors to the client with a `400` code.
705
- if (validationErrors.length > 0) {
706
- result = { errors: validationErrors, statusCode: 400 };
707
- }
708
- else if (!queryDocumentAst) {
709
- throw new Error('Could not process query');
710
- }
711
- else {
712
- if (debugRequest.enabled)
713
- debugRequest('GraphQL query is validated.');
714
- // Lazily log the query. If this debugger isn’t enabled, don’t run it.
715
- if (debugGraphql.enabled)
716
- debugGraphql('%s', graphql_1.print(queryDocumentAst).replace(/\s+/g, ' ').trim());
717
- result = await withPostGraphileContextFromReqRes(req,
718
- // For backwards compatibilty we must pass the actual node request object.
719
- res.getNodeServerResponse(), {
720
- singleStatement: false,
721
- queryDocumentAst,
722
- variables,
723
- operationName,
724
- }, (graphqlContext) => {
725
- pgRole = graphqlContext.pgRole;
726
- const graphqlResult = graphql_1.execute(gqlSchema, queryDocumentAst, null, graphqlContext, variables, operationName);
727
- if (typeof graphqlContext.getExplainResults === 'function') {
728
- return Promise.resolve(graphqlResult).then(async (obj) => ({
729
- ...obj,
730
- // Add our explain data
731
- explain: await graphqlContext.getExplainResults(),
732
- }));
733
- }
734
- else {
735
- return graphqlResult;
736
- }
737
- });
738
- }
739
- }
740
- catch (error) {
741
- result = {
742
- errors: [error],
743
- statusCode: error.status || error.statusCode || 500,
744
- };
745
- // If the status code is 500, let’s log our error.
746
- if (result.statusCode === 500)
747
- // tslint:disable-next-line no-console
748
- console.error(error.stack);
749
- }
750
- finally {
751
- // Format our errors so the client doesn’t get the full thing.
752
- if (result && result.errors) {
753
- result.errors = handleErrors(result.errors, req, res);
754
- }
755
- if (!isEmpty(meta)) {
756
- result.meta = meta;
757
- }
758
- result = pluginHook('postgraphile:http:result', result, {
759
- options,
760
- returnArray,
761
- queryDocumentAst,
762
- req,
763
- pgRole,
764
- });
765
- // Log the query. If this debugger isn’t enabled, don’t run it.
766
- if (!disableQueryLog && queryDocumentAst) {
767
- // To appease TypeScript
768
- const definitelyQueryDocumentAst = queryDocumentAst;
769
- // We must reference this before it's deleted!
770
- const resultStatusCode = result.statusCode;
771
- const timeDiff = queryTimeStart && process.hrtime(queryTimeStart);
772
- setImmediate(() => {
773
- const prettyQuery = graphql_1.print(definitelyQueryDocumentAst)
774
- .replace(/\s+/g, ' ')
775
- .trim();
776
- const errorCount = (result.errors || []).length;
777
- const ms = timeDiff[0] * 1e3 + timeDiff[1] * 1e-6;
778
- let message;
779
- if (resultStatusCode === 401) {
780
- // Users requested that JWT errors were raised differently:
781
- //
782
- // https://github.com/graphile/postgraphile/issues/560
783
- message = chalk_1.default.red(`401 authentication error`);
784
- }
785
- else if (resultStatusCode === 403) {
786
- message = chalk_1.default.red(`403 forbidden error`);
787
- }
788
- else {
789
- message = chalk_1.default[errorCount === 0 ? 'green' : 'red'](`${errorCount} error(s)`);
790
- }
791
- // tslint:disable-next-line no-console
792
- console.log(`${message} ${pgRole != null ? `as ${chalk_1.default.magenta(pgRole)} ` : ''}in ${chalk_1.default.grey(`${ms.toFixed(2)}ms`)} :: ${prettyQuery}`);
793
- });
794
- }
795
- if (debugRequest.enabled)
796
- debugRequest('GraphQL query has been executed.');
797
- }
798
- return result;
799
- }));
800
- }
801
- catch (error) {
802
- // Set our status code and send the client our results!
803
- if (res.statusCode === 200)
804
- res.statusCode = error.status || error.statusCode || 500;
805
- // Overwrite entire response
806
- returnArray = false;
807
- results = [{ errors: handleErrors([error], req, res) }];
808
- // If the status code is 500, let’s log our error.
809
- if (res.statusCode === 500) {
810
- // tslint:disable-next-line no-console
811
- console.error(error.stack);
812
- }
813
- }
814
- finally {
815
- // Finally, we send the client the results.
816
- if (!returnArray) {
817
- if (res.statusCode === 200 && results[0].statusCode) {
818
- res.statusCode = results[0].statusCode;
819
- }
820
- results[0].statusCode = undefined;
821
- }
822
- res.setHeader('Content-Type', 'application/json; charset=utf-8');
823
- const { statusCode, result } = pluginHook('postgraphile:http:end', {
824
- statusCode: res.statusCode,
825
- result: returnArray ? results : results[0],
826
- }, {
827
- options,
828
- returnArray,
829
- req,
830
- // For backwards compatibility, the underlying response object.
831
- res: res.getNodeServerResponse(),
832
- });
833
- if (statusCode) {
834
- res.statusCode = statusCode;
835
- }
836
- res.end(JSON.stringify(result));
837
- if (debugRequest.enabled) {
838
- debugRequest('GraphQL ' + (returnArray ? 'queries' : 'query') + ' request finished.');
839
- }
840
- }
841
- });
842
- /**
843
- * A polymorphic request handler that should detect what `http` framework is
844
- * being used and specifically handle that framework.
845
- *
846
- * Supported frameworks include:
847
- *
848
- * - Native Node.js `http`.
849
- * - `connect`.
850
- * - `express`.
851
- * - `koa` (2.0).
852
- */
853
- const middleware = (a, b, c) => {
854
- // If are arguments look like the arguments to koa middleware, this is
855
- // `koa` middleware.
856
- if (isKoaApp(a, b)) {
857
- // Set the correct `koa` variable names…
858
- const ctx = a;
859
- const next = b;
860
- const responseHandler = new frameworks_1.PostGraphileResponseKoa(ctx, next);
861
- // Execute our request handler. If an error is thrown, we don’t call
862
- // `next` with an error. Instead we return the promise and let `koa`
863
- // handle the error.
864
- return requestHandler(responseHandler, next);
865
- }
866
- else {
867
- // Set the correct `connect` style variable names. If there was no `next`
868
- // defined (likely the case if the client is using `http`) we use the
869
- // final handler.
870
- const req = a;
871
- const res = b;
872
- const next = c || finalHandler(req, res);
873
- const responseHandler = new frameworks_1.PostGraphileResponseNode(req, res, next);
874
- // Execute our request handler. If the request errored out, call `next` with the error.
875
- requestHandler(responseHandler, next).catch(next);
876
- // No return value.
877
- }
878
- };
879
- middleware.getGraphQLSchema = getGqlSchema;
880
- middleware.formatError = formatError;
881
- middleware.pgPool = pgPool;
882
- middleware.withPostGraphileContextFromReqRes = withPostGraphileContextFromReqRes;
883
- middleware.handleErrors = handleErrors;
884
- middleware.options = options;
885
- middleware.graphqlRoute = graphqlRoute;
886
- middleware.graphqlRouteHandler = graphqlRouteHandler;
887
- middleware.graphiqlRoute = graphiqlRoute;
888
- middleware.graphiqlRouteHandler = graphiql ? graphiqlRouteHandler : null;
889
- middleware.faviconRouteHandler = graphiql ? faviconRouteHandler : null;
890
- middleware.eventStreamRoute = eventStreamRoute;
891
- middleware.eventStreamRouteHandler = watchPg ? eventStreamRouteHandler : null;
892
- middleware.shutdownActions = shutdownActions;
893
- // Experimental
894
- middleware.release = () => shutdownActions.invokeAll();
895
- const hookedMiddleware = pluginHook('postgraphile:middleware', middleware, {
896
- options,
897
- // Experimental
898
- shutdownActions,
899
- });
900
- // Sanity check:
901
- if (!hookedMiddleware.getGraphQLSchema) {
902
- throw new Error("Hook for 'postgraphile:middleware' has not copied over the helpers; e.g. missing `Object.assign(newMiddleware, oldMiddleware)`");
903
- }
904
- return hookedMiddleware;
905
- }
906
- exports.default = createPostGraphileHttpRequestHandler;
907
- /**
908
- * Adds CORS to a request. See [this][1] flowchart for an explanation of how
909
- * CORS works. Note that these headers are set for all requests, CORS
910
- * algorithms normally run a preflight request using the `OPTIONS` method to
911
- * get these headers.
912
- *
913
- * Note though, that enabling CORS will incur extra costs when it comes to the
914
- * preflight requests. It is much better if you choose to use a proxy and
915
- * bypass CORS altogether.
916
- *
917
- * [1]: http://www.html5rocks.com/static/images/cors_server_flowchart.png
918
- */
919
- function addCORSHeaders(res) {
920
- res.setHeader('Access-Control-Allow-Origin', '*');
921
- res.setHeader('Access-Control-Allow-Methods', 'HEAD, GET, POST');
922
- res.setHeader('Access-Control-Allow-Headers', [
923
- 'Origin',
924
- 'X-Requested-With',
925
- // Used by `express-graphql` to determine whether to expose the GraphiQL
926
- // interface (`text/html`) or not.
927
- 'Accept',
928
- // Used by PostGraphile for auth purposes.
929
- 'Authorization',
930
- // Used by GraphQL Playground and other Apollo-enabled servers
931
- 'X-Apollo-Tracing',
932
- // The `Content-*` headers are used when making requests with a body,
933
- // like in a POST request.
934
- 'Content-Type',
935
- 'Content-Length',
936
- // For our 'Explain' feature
937
- 'X-PostGraphile-Explain',
938
- ].join(', '));
939
- res.setHeader('Access-Control-Expose-Headers', ['X-GraphQL-Event-Stream'].join(', '));
940
- }
941
- function createBadAuthorizationHeaderError() {
942
- return httpError(400, 'Authorization header is not of the correct bearer scheme format.');
943
- }
944
- /**
945
- * Parses the `Bearer` auth scheme token out of the `Authorization` header as
946
- * defined by [RFC7235][1].
947
- *
948
- * ```
949
- * Authorization = credentials
950
- * credentials = auth-scheme [ 1*SP ( token68 / #auth-param ) ]
951
- * token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" )*"="
952
- * ```
953
- *
954
- * [1]: https://tools.ietf.org/html/rfc7235
955
- *
956
- * @private
957
- */
958
- const authorizationBearerRex = /^\s*bearer\s+([a-z0-9\-._~+/]+=*)\s*$/i;
959
- /**
960
- * Gets the JWT token from the Http request’s headers. Specifically the
961
- * `Authorization` header in the `Bearer` format. Will throw an error if the
962
- * header is in the incorrect format, but will not throw an error if the header
963
- * does not exist.
964
- *
965
- * @private
966
- * @param {IncomingMessage} request
967
- * @returns {string | null}
968
- */
969
- function getJwtToken(request) {
970
- const { authorization } = request.headers;
971
- if (Array.isArray(authorization))
972
- throw createBadAuthorizationHeaderError();
973
- // If there was no authorization header, just return null.
974
- if (authorization == null)
975
- return null;
976
- const match = authorizationBearerRex.exec(authorization);
977
- // If we did not match the authorization header with our expected format,
978
- // throw a 400 error.
979
- if (!match)
980
- throw createBadAuthorizationHeaderError();
981
- // Return the token from our match.
982
- return match[1];
983
- }
984
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlUG9zdEdyYXBoaWxlSHR0cFJlcXVlc3RIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Bvc3RncmFwaGlsZS9odHRwL2NyZWF0ZVBvc3RHcmFwaGlsZUh0dHBSZXF1ZXN0SGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4RUFBOEU7QUFDOUUscUNBV2lCO0FBQ2pCLGdFQUE2RDtBQUU3RCw4Q0FBc0Q7QUFFdEQsbUVBQTREO0FBQzVELHdFQUFpRTtBQUNqRSx1Q0FBZ0M7QUFFaEMsaUNBQTBCO0FBQzFCLGtDQUFtQyxDQUFDLG9DQUFvQztBQUN4RSx5Q0FBMEM7QUFDMUMscUNBQXNDO0FBQ3RDLDZDQUE4QztBQUM5QywwQ0FBMkM7QUFDM0MsaUNBQWtDO0FBRWxDLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFVBQVUsQ0FBQztBQUUvRSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQztBQUVoQyxNQUFNLHlCQUF5QixHQUFHLDBCQUEwQixDQUFDO0FBQzdELE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRTtJQUNoQixVQUFVO0FBQ1osQ0FBQyxDQUFDO0FBRUYsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sQ0FBQztBQUU5Qjs7Ozs7R0FLRztBQUNILDBEQUErQztBQUUvQzs7O0dBR0c7QUFDSCw4REFBMEQ7QUFDMUQsbURBQWtFO0FBQ2xFLDZDQU1zQjtBQUV0Qjs7O0dBR0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCLEdBQUcsRUFBRSxTQUFTO0lBQ2QsR0FBRyxFQUFFLFNBQVM7SUFDZCxHQUFHLEVBQUUsU0FBUztJQUNkLFFBQVEsRUFBRSxTQUFTO0lBQ25CLFFBQVEsRUFBRSxTQUFTO0NBQ3BCLENBQUM7QUFDRixTQUFTLGlCQUFpQixDQUFDLEdBQXdCO0lBQ2pELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEtBQUssR0FBRyxDQUFDO0FBRXRFLGlEQUFpRDtBQUNqRCxJQUFJLFVBQWtCLENBQUM7QUFDdkIsSUFBSSxRQUFnQixDQUFDO0FBQ3JCLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxXQUFtQixFQUFVLEVBQUU7SUFDekQsSUFBSSxXQUFXLEtBQUssVUFBVSxFQUFFO1FBQzlCLFVBQVUsR0FBRyxXQUFXLENBQUM7UUFDekIsUUFBUSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQ3BFO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyxDQUFDO0FBRUYsOENBQThDO0FBQzlDLGlEQUFpRDtBQUNqRCw2RUFBNkU7QUFDN0Usd0VBQXdFO0FBQ3hFLDBCQUEwQjtBQUMxQixTQUFnQixPQUFPLENBQUMsS0FBVTtJQUNoQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtRQUN4QixPQUFPLEtBQUssQ0FBQztLQUNkO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBTEQsMEJBS0M7QUFDRCx5QkFBeUI7QUFFekIsTUFBTSw2QkFBNkIsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixLQUFLLGFBQWEsQ0FBQztBQUVyRixNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsc0JBQXNCLENBQUMsQ0FBQztBQUN0RCxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsc0JBQXNCLENBQUMsQ0FBQztBQUV0RDs7O0dBR0c7QUFDSCxTQUFTLDBDQUEwQyxDQUNqRCxPQUFvQztJQU9wQyxNQUFNLEVBQ0osVUFBVSxFQUFFLG1CQUFtQixFQUMvQixZQUFZLEVBQUUscUJBQXFCLEVBQ25DLFNBQVMsRUFDVCxZQUFZLEVBQ1osbUNBQW1DLEdBQ3BDLEdBQUcsT0FBTyxDQUFDO0lBQ1osT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLEVBQUU7UUFDekMsTUFBTSxxQkFBcUIsR0FBRyxZQUFZLElBQUksU0FBUyxDQUFDO1FBQ3hELE1BQU0sUUFBUSxHQUFHLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNqRSxNQUFNLGlCQUFpQixHQUNyQixPQUFPLG1DQUFtQyxLQUFLLFVBQVU7WUFDdkQsQ0FBQyxDQUFDLE1BQU0sbUNBQW1DLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztZQUNyRCxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ1gsTUFBTSxVQUFVLEdBQ2QsT0FBTyxtQkFBbUIsS0FBSyxVQUFVO1lBQ3ZDLENBQUMsQ0FBQyxNQUFNLG1CQUFtQixDQUFDLEdBQUcsQ0FBQztZQUNoQyxDQUFDLENBQUMsbUJBQW1CLENBQUM7UUFDMUIsTUFBTSxZQUFZLEdBQ2hCLE9BQU8scUJBQXFCLEtBQUssVUFBVTtZQUN6QyxDQUFDLENBQUMsTUFBTSxxQkFBcUIsQ0FBQyxHQUFHLENBQUM7WUFDbEMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDO1FBQzVCLE9BQU8saUNBQXVCLENBQzVCO1lBQ0UsR0FBRyxPQUFPO1lBQ1YsUUFBUTtZQUNSLFVBQVU7WUFDVixPQUFPLEVBQUUsWUFBWSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsS0FBSyxJQUFJO1lBQ3ZFLEdBQUcsV0FBVztTQUNmLEVBQ0QsT0FBTyxDQUFDLEVBQUU7WUFDUixNQUFNLGNBQWMsR0FBRyxpQkFBaUI7Z0JBQ3RDLENBQUMsQ0FBQyxFQUFFLEdBQUcsaUJBQWlCLEVBQUUsR0FBSSxPQUErQixFQUFFO2dCQUMvRCxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ1osT0FBTyxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQXdCLG9DQUFvQyxDQUMxRCxPQUFvQztJQUVwQyxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQzdCLE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO0lBQzlDLE1BQU0sRUFDSixZQUFZLEVBQ1osTUFBTSxFQUNOLFVBQVUsRUFDVixhQUFhLEVBQ2IsZUFBZSxFQUNmLGlCQUFpQixHQUFHLEVBQUUsR0FBRyxRQUFRLEVBQ2pDLGNBQWMsRUFDZCxjQUFjLEVBQ2QsT0FBTyxFQUNQLGVBQWUsRUFDZixtQkFBbUIsRUFDbkIsVUFBVSxHQUFHLE9BQU8sQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FDdkUsR0FBRyxPQUFPLENBQUM7SUFDWixNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUM1QixNQUFNLGVBQWUsR0FDbkIsT0FBTyxDQUFDLGVBQWUsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxlQUFlLElBQUksYUFBYSxJQUFJLElBQUksQ0FBQztJQUNqRyxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsSUFBSSw2QkFBNkIsQ0FBQztJQUN6RSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQztJQUMzQyxJQUFJLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1FBQzdCLE1BQU0sSUFBSSxLQUFLLENBQ2IseU1BQXlNLENBQzFNLENBQUM7S0FDSDtJQUVELCtEQUErRDtJQUMvRCxJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0lBQzlDLElBQUksZUFBZSxJQUFJLGVBQWUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDcEQsTUFBTSxJQUFJLEtBQUssQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO0tBQ3BFO0lBRUQsK0JBQStCO0lBQy9CO0lBQ0UsZ0JBQWdCO0lBQ2hCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7UUFDMUIsdUJBQXVCO1FBQ3ZCLENBQUMsVUFBVSxDQUFDLE1BQU07WUFDaEIsbUNBQW1DO1lBQ25DLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQ3REO1FBQ0EsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsVUFBVSxHQUFHLENBQUMsQ0FBQztLQUM3RTtJQUVELE1BQU0sVUFBVSxHQUFHLGtDQUFxQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRWxELE1BQU0sZ0JBQWdCLEdBQUcsVUFBVSxDQUFDLDRCQUE0QixFQUFFLHVCQUFnQixFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUVqRyxJQUFJLGFBQWEsSUFBSSxPQUFPLFVBQVUsS0FBSyxVQUFVLEVBQUU7UUFDckQsTUFBTSxJQUFJLEtBQUssQ0FDYixrSkFBa0osQ0FDbkosQ0FBQztLQUNIO0lBQ0QsSUFDRSxhQUFhO1FBQ2IsVUFBVTtRQUNWLE9BQU8sVUFBVSxLQUFLLFFBQVE7UUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7YUFDcEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO2FBQ3pCLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFDbkI7UUFDQSxNQUFNLElBQUksS0FBSyxDQUNiLHNGQUFzRixDQUN2RixDQUFDO0tBQ0g7SUFDRCxJQUFJLFFBQVEsSUFBSSxnQkFBZ0IsRUFBRTtRQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7S0FDaEY7SUFFRCw0RUFBNEU7SUFDNUUsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksSUFBSSxVQUFVLENBQUM7SUFDeEQsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxXQUFXLENBQUM7SUFDM0QsbURBQW1EO0lBQ25ELE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixJQUFJLGFBQWEsQ0FBQztJQUV6RSxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUM7SUFDbEcsTUFBTSxvQkFBb0IsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUM7SUFDMUQsTUFBTSx3QkFBd0IsR0FDNUIsT0FBTyxDQUFDLHdCQUF3QjtRQUNoQyxDQUFDLG9CQUFvQixJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQjtZQUNoRCxDQUFDLENBQUMsR0FBRyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxTQUFTO1lBQ3RELENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUVqQixrRUFBa0U7SUFDbEUsSUFBSSxZQUFZLEtBQUssYUFBYTtRQUNoQyxNQUFNLElBQUksS0FBSyxDQUNiLCtCQUErQixZQUFZLGdFQUFnRSxDQUM1RyxDQUFDO0lBRUoseUVBQXlFO0lBQ3pFLDhDQUE4QztJQUM5QyxNQUFNLFdBQVcsR0FBRyxDQUFDLEtBQW1CLEVBQUUsRUFBRTtRQUMxQywyRUFBMkU7UUFDM0UsaUNBQWlDO1FBQ2pDLE1BQU0sY0FBYyxHQUNsQixjQUFjLElBQUksY0FBYyxDQUFDLE1BQU07WUFDckMsQ0FBQyxDQUFDLHlDQUFtQixDQUFDLEtBQUssRUFBRSxjQUFjLENBQUM7WUFDNUMsQ0FBQyxDQUFDLHFCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWhDLGtFQUFrRTtRQUNsRSxtQkFBbUI7UUFDbkIsSUFBSSxjQUFjO1lBQ2YsY0FBc0MsQ0FBQyxPQUFPLENBQUM7Z0JBQzlDLEtBQUssQ0FBQyxLQUFLLElBQUksSUFBSSxJQUFJLGNBQWMsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBRTdGLE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUMsQ0FBQztJQUVGLE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxNQUEyQixFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZGLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLElBQUkscUJBQXFCLENBQUM7SUFFbkUsNkVBQTZFO0lBQzdFLDRFQUE0RTtJQUM1RSxtRUFBbUU7SUFDbkUsd0VBQXdFO0lBQ3hFLGFBQWE7SUFDYixNQUFNLHFCQUFxQixHQUFHO1FBQzVCLHFCQUFxQjtRQUNyQixVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNqRCxvQ0FBb0M7UUFDcEMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN4RSwyREFBMkQ7UUFDM0QsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxxQkFBcUIsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO0tBQy9FLENBQUM7SUFFRiwwRUFBMEU7SUFDMUUsTUFBTSw2QkFBNkIsR0FBRyxxQkFBcUIsQ0FBQyxNQUFNLENBQ2hFLENBQ0UsTUFBd0YsRUFDeEYsRUFBb0YsRUFDQSxFQUFFO1FBQ3RGLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1lBQ3hCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFO2dCQUN2QixJQUFJLEtBQUssRUFBRTtvQkFDVCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDcEI7Z0JBQ0QsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDckIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7SUFDSixDQUFDLEVBQ0QsQ0FBQyxJQUFxQixFQUFFLElBQW9CLEVBQUUsSUFBMkIsRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQ3JGLENBQUM7SUFFRixvREFBb0Q7SUFDcEQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxHQUFvQixFQUFFLEdBQXlCLEVBQUUsRUFBRSxDQUNwRSxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNwQyw2QkFBNkIsQ0FDM0IsR0FBRztRQUNILHVFQUF1RTtRQUN2RSwwQ0FBMEM7UUFDMUMsR0FBRyxDQUFDLHFCQUFxQixFQUFFLEVBQzNCLENBQUMsS0FBWSxFQUFFLEVBQUU7WUFDZixJQUFJLEtBQUssRUFBRTtnQkFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDZjtpQkFBTTtnQkFDTCxPQUFPLEVBQUUsQ0FBQzthQUNYO1FBQ0gsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVMLHVHQUF1RztJQUN2RyxJQUFJLFlBQTJCLENBQUM7SUFFaEMsTUFBTSxpQ0FBaUMsR0FBRywwQ0FBMEMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUU5RixNQUFNLHFCQUFxQixHQUFHLFVBQVUsQ0FBQyxxQ0FBcUMsRUFBRSx3QkFBYyxFQUFFO1FBQzlGLE9BQU87S0FDUixDQUFDLENBQUM7SUFVSCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDLENBQUM7SUFFbEUsNEVBQTRFO0lBQzVFLE1BQU0sWUFBWSxHQUFHLFNBQVMsSUFBSSxDQUFDLENBQUM7SUFDcEMsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLGFBQUcsQ0FBQyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFFM0UsSUFBSSxhQUE0QixDQUFDO0lBQ2pDLE1BQU0sVUFBVSxHQUFHLENBQ2pCLFNBQXdCLEVBQ3hCLFdBQW1CLEVBSW5CLEVBQUU7UUFDRixJQUFJLFNBQVMsS0FBSyxhQUFhLEVBQUU7WUFDL0IsSUFBSSxVQUFVLEVBQUU7Z0JBQ2QsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQ3BCO1lBQ0QsYUFBYSxHQUFHLFNBQVMsQ0FBQztTQUMzQjtRQUVELHlFQUF5RTtRQUN6RSxvQ0FBb0M7UUFDcEMsTUFBTSxRQUFRLEdBQUcsWUFBWSxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBRTdELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMvRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN4RCxJQUFJLE1BQU0sRUFBRTtZQUNWLE9BQU8sTUFBTSxDQUFDO1NBQ2Y7YUFBTTtZQUNMLE1BQU0sTUFBTSxHQUFHLElBQUksZ0JBQU0sQ0FBQyxXQUFXLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztZQUMvRCxJQUFJLGdCQUFxQyxDQUFDO1lBRTFDLHVFQUF1RTtZQUN2RSxrREFBa0Q7WUFDbEQsSUFBSTtnQkFDRixnQkFBZ0IsR0FBRyxlQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDekM7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDZCxLQUFLLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztnQkFDdkIsTUFBTSxLQUFLLENBQUM7YUFDYjtZQUVELElBQUksWUFBWSxDQUFDLE9BQU87Z0JBQUUsWUFBWSxDQUFDLDBCQUEwQixDQUFDLENBQUM7WUFFbkUsZ0RBQWdEO1lBQ2hELE1BQU0sZ0JBQWdCLEdBQUcsa0JBQWUsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLENBQUMsQ0FBQztZQUM3RixNQUFNLFdBQVcsR0FBZTtnQkFDOUIsZ0JBQWdCO2dCQUNoQixnQkFBZ0I7Z0JBQ2hCLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTTthQUMzQixDQUFDO1lBQ0YsSUFBSSxRQUFRLEVBQUU7Z0JBQ1osVUFBVyxDQUFDLEdBQUcsQ0FBQyxJQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFDckM7WUFDRCxPQUFPLFdBQVcsQ0FBQztTQUNwQjtJQUNILENBQUMsQ0FBQztJQUVGLElBQUksbUJBQW1CLEdBQTRDLEdBQUcsQ0FBQyxFQUFFO1FBQ3ZFLHdCQUF3QjtRQUN4QixtQkFBbUIsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxpQkFBaUIsR0FBRyxZQUFZLENBQUM7UUFFckMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ2pELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxPQUFPLE1BQU0sQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEYsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUMzRCxNQUFNLGdCQUFnQixHQUNwQixPQUFPLElBQUksT0FBTyxPQUFPLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzFFLElBQUksZ0JBQWdCLEtBQUssUUFBUSxJQUFJLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUN4RSxNQUFNLElBQUksR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbEYsMkRBQTJEO1lBQzNELGlCQUFpQixHQUFHLElBQUksR0FBRyxpQkFBaUIsQ0FBQztZQUM3QyxJQUFJLGVBQWUsSUFBSSxJQUFJLEVBQUU7Z0JBQzNCLGdFQUFnRTtnQkFDaEUsZ0ZBQWdGO2dCQUNoRixnREFBZ0Q7Z0JBQ2hELGVBQWUsR0FBRyxJQUFJLENBQUM7YUFDeEI7U0FDRjtRQUNELHVDQUF1QztRQUN2QyxlQUFlLEdBQUcsZUFBZSxJQUFJLEVBQUUsQ0FBQztRQUV4QyxnRkFBZ0Y7UUFDaEYsWUFBWSxHQUFHLGdCQUFnQjtZQUM3QixDQUFDLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUN0QixVQUFVLEVBQ1Ysd0NBQXdDLGlCQUFpQixDQUFDO2dCQUN4RCxVQUFVLEVBQUUsb0JBQW9CLElBQUksR0FBRyxlQUFlLEdBQUcsWUFBWSxFQUFFO2dCQUN2RSxTQUFTLEVBQUUsT0FBTztvQkFDaEIsQ0FBQyxDQUFDLHdCQUF3QixJQUFJLEdBQUcsZUFBZSxHQUFHLGdCQUFnQixFQUFFO29CQUNyRSxDQUFDLENBQUMsSUFBSTtnQkFDUixlQUFlO2dCQUNmLDREQUE0RDtnQkFDNUQsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQ2pGLFlBQVksRUFDVixPQUFPLE9BQU8sQ0FBQyxZQUFZLEtBQUssVUFBVTtvQkFDeEMsQ0FBQyxDQUFDLHlCQUF5QjtvQkFDM0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWTtnQkFDNUIsV0FBVyxFQUFFLG1CQUFtQjthQUNqQyxDQUFDLHVCQUF1QixDQUMxQjtZQUNILENBQUMsQ0FBQyxJQUFJLENBQUM7UUFFVCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUU7WUFDckIsTUFBTSxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNqRSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNYLHNDQUFzQztnQkFDdEMsT0FBTyxDQUFDLElBQUksQ0FDVixvSEFBb0gsQ0FDckgsQ0FBQzthQUNIO2lCQUFNO2dCQUNMLHFFQUFxRTtnQkFDckUsb0RBQW9EO2dCQUNwRCwrQ0FBK0IsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFO29CQUNsRCxZQUFZLEVBQUUsaUJBQWlCO2lCQUNoQyxDQUFDLENBQUM7YUFDSjtTQUNGO0lBQ0gsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsSUFBSSwwQkFBMEIsR0FBeUIsSUFBSSxDQUFDO0lBQzVELElBQUksQ0FBQyxPQUFPLEVBQUU7UUFDWixZQUFZLEVBQUU7YUFDWCxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDYiwwQkFBMEIsR0FBRyxNQUFNLENBQUM7UUFDdEMsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2hCO0lBRUQsU0FBUyxXQUFXLENBQ2xCLGNBQXNCLEVBQ3RCLFVBQXdEO1FBRXhELE9BQU8sS0FBSyxFQUFDLEdBQUcsRUFBQyxFQUFFO1lBQ2pCLElBQUk7Z0JBQ0YsTUFBTSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDdkI7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixPQUFPLENBQUMsS0FBSyxDQUNYLG1EQUFtRCxjQUFjLDZEQUE2RCxDQUMvSCxDQUFDO2dCQUNGLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pCLElBQUk7b0JBQ0Ysb0NBQW9DO29CQUNwQyxHQUFHLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztvQkFDckIsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO2lCQUNYO2dCQUFDLE9BQU8sQ0FBQyxFQUFFO29CQUNWLFFBQVE7aUJBQ1Q7YUFDRjtRQUNILENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILE1BQU0sY0FBYyxHQUFHLEtBQUssRUFDMUIsZUFBcUMsRUFDckMsSUFBcUMsRUFDckMsRUFBRTtRQUNGLE1BQU0sR0FBRyxHQUFHLGVBQWUsQ0FBQztRQUM1QixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUMvQyxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUM1Qyx5RUFBeUU7UUFDekUseUVBQXlFO1FBQ3pFLHFFQUFxRTtRQUNyRSw4Q0FBOEM7UUFDOUMsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLDJCQUEyQixFQUFFLFdBQVcsRUFBRTtZQUMvRCxPQUFPO1lBQ1AsR0FBRyxFQUFFLE9BQU87WUFDWixJQUFJO1NBQ0wsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFO1lBQ2YsT0FBTztTQUNSO1FBRUQsTUFBTSxFQUFFLFFBQVEsR0FBRyxFQUFFLEVBQUUsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRTlDLHVFQUF1RTtRQUN2RSxzRUFBc0U7UUFDdEUsOENBQThDO1FBQzlDLElBQUksbUJBQW1CO1lBQUUsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFbEQseUVBQXlFO1FBQ3pFLHVCQUF1QjtRQUN2Qix5RUFBeUU7UUFFekUsSUFBSSxPQUFPLEVBQUU7WUFDWCxxRUFBcUU7WUFDckUsSUFBSSxRQUFRLEtBQUssZ0JBQWdCLElBQUksUUFBUSxLQUFLLHVCQUF1QixFQUFFO2dCQUN6RSxPQUFPLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ3JDO1NBQ0Y7UUFFRCxNQUFNLGNBQWMsR0FBRyxRQUFRLEtBQUssWUFBWSxDQUFDO1FBRWpELDJFQUEyRTtRQUMzRSxvQ0FBb0M7UUFDcEMsMkVBQTJFO1FBRTNFLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxRQUFRLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDcEQseUVBQXlFO1lBQ3pFLFVBQVU7WUFDVix5RUFBeUU7WUFFekUsc0VBQXNFO1lBQ3RFLDZCQUE2QjtZQUM3QixJQUFJLFFBQVEsS0FBSyxjQUFjLEVBQUU7Z0JBQy9CLE9BQU8sbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDakM7WUFFRCx5RUFBeUU7WUFDekUsZ0JBQWdCO1lBQ2hCLHlFQUF5RTtZQUV6RSxtRUFBbUU7WUFDbkUsSUFBSSxRQUFRLEtBQUssYUFBYSxFQUFFO2dCQUM5Qiw0REFBNEQ7Z0JBQzVELElBQUksNkJBQTZCLEVBQUU7b0JBQ2pDLEdBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDO29CQUNyQixHQUFHLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO29CQUNuRCxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7b0JBQ1YsT0FBTztpQkFDUjtnQkFFRCxPQUFPLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ2xDO1NBQ0Y7UUFFRCxJQUFJLGNBQWMsRUFBRTtZQUNsQixPQUFPLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2pDO2FBQU07WUFDTCw4QkFBOEI7WUFDOUIsT0FBTyxJQUFJLEVBQUUsQ0FBQztTQUNmO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsTUFBTSx1QkFBdUIsR0FBRyxXQUFXLENBQ3pDLHlCQUF5QixFQUN6QixLQUFLLFVBQVUsdUJBQXVCLENBQUMsR0FBeUI7UUFDOUQsSUFBSTtZQUNGLHlFQUF5RTtZQUN6RSx5RUFBeUU7WUFDekUscUVBQXFFO1lBQ3JFLG9FQUFvRTtZQUNwRSxnQ0FBZ0M7WUFDaEMsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUNwQiwyQ0FBMkMsRUFDM0MsR0FBRyxDQUFDLG9CQUFvQixFQUFFLEVBQzFCLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FDM0IsQ0FBQztZQUNGLElBQUksR0FBRyxJQUFJLElBQUksRUFBRTtnQkFDZixPQUFPO2FBQ1I7WUFFRCwrREFBK0Q7WUFDL0Qsc0NBQXNDO1lBQ3RDLEVBQUU7WUFDRiwyRUFBMkU7WUFDM0UsZ0JBQWdCO1lBQ2hCLElBQUksVUFBVTtnQkFBRSxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFcEMsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxtQkFBbUIsRUFBRTtnQkFDOUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUM7Z0JBQ3JCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDVixPQUFPO2FBQ1I7WUFDRCwrQkFBcUIsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDckM7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztZQUN0RSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLEdBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDO1lBQ3JCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNYO0lBQ0gsQ0FBQyxDQUNGLENBQUM7SUFFRixNQUFNLG1CQUFtQixHQUFHLFdBQVcsQ0FDckMscUJBQXFCLEVBQ3JCLEtBQUssVUFBVSxtQkFBbUIsQ0FBQyxHQUF5QjtRQUMxRCx5RUFBeUU7UUFDekUseUVBQXlFO1FBQ3pFLHFFQUFxRTtRQUNyRSxvRUFBb0U7UUFDcEUsZ0NBQWdDO1FBQ2hDLE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLENBQUMsb0JBQW9CLEVBQUUsRUFBRTtZQUMxRixPQUFPO1lBQ1AsUUFBUSxFQUFFLEdBQUc7U0FDZCxDQUFDLENBQUM7UUFDSCxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUU7WUFDZixPQUFPO1NBQ1I7UUFFRCw4REFBOEQ7UUFDOUQsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxLQUFLLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsRUFBRTtZQUNwRCxHQUFHLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUN0RCxHQUFHLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO1lBQzdDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNWLE9BQU87U0FDUjtRQUVELG9FQUFvRTtRQUNwRSxHQUFHLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztRQUNyQixHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1FBQ3hELEdBQUcsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBRTlDLHFDQUFxQztRQUNyQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxFQUFFO1lBQ3pCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNWLE9BQU87U0FDUjtRQUVELEdBQUcsQ0FBQyxHQUFHLENBQUMscUJBQU8sQ0FBQyxDQUFDO0lBQ25CLENBQUMsQ0FDRixDQUFDO0lBRUYsTUFBTSxvQkFBb0IsR0FBRyxXQUFXLENBQ3RDLHNCQUFzQixFQUN0QixLQUFLLFVBQVUsb0JBQW9CLENBQUMsR0FBeUI7UUFDM0QseUVBQXlFO1FBQ3pFLHlFQUF5RTtRQUN6RSxxRUFBcUU7UUFDckUsb0VBQW9FO1FBQ3BFLGdDQUFnQztRQUNoQyxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsd0NBQXdDLEVBQUUsR0FBRyxDQUFDLG9CQUFvQixFQUFFLEVBQUU7WUFDM0YsT0FBTztZQUNQLFFBQVEsRUFBRSxHQUFHO1NBQ2QsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFO1lBQ2YsT0FBTztTQUNSO1FBRUQsSUFBSSxtQkFBbUI7WUFBRSxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVsRCxvREFBb0Q7UUFDcEQsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxLQUFLLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsRUFBRTtZQUNwRCxHQUFHLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUN0RCxHQUFHLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO1lBQzdDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNWLE9BQU87U0FDUjtRQUVELEdBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBQ3JCLEdBQUcsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLDBCQUEwQixDQUFDLENBQUM7UUFDMUQsR0FBRyxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUMvQyxHQUFHLENBQUMsU0FBUyxDQUFDLHlCQUF5QixFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFFbkUscUNBQXFDO1FBQ3JDLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxNQUFNLEVBQUU7WUFDekIsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1YsT0FBTztTQUNSO1FBRUQsNkJBQTZCO1FBQzdCLElBQUksWUFBWSxJQUFJLE9BQU8sT0FBTyxDQUFDLFlBQVksS0FBSyxVQUFVLEVBQUU7WUFDOUQsR0FBRyxDQUFDLEdBQUcsQ0FDTCxZQUFZLENBQUMsT0FBTyxDQUNsQixJQUFJLHlCQUF5QixHQUFHLEVBQUUsdUJBQXVCO1lBQ3pELElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FDcEQsQ0FDRixDQUFDO1NBQ0g7YUFBTTtZQUNMLEdBQUcsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDdkI7SUFDSCxDQUFDLENBQ0YsQ0FBQztJQUVGLE1BQU0sbUJBQW1CLEdBQUcsV0FBVyxDQUNyQyxxQkFBcUIsRUFDckIsS0FBSyxVQUFVLG1CQUFtQixDQUFDLEdBQXlCO1FBQzFELHlFQUF5RTtRQUN6RSx5RUFBeUU7UUFDekUscUVBQXFFO1FBQ3JFLG9FQUFvRTtRQUNwRSxnQ0FBZ0M7UUFDaEMsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFO1lBQzFGLE9BQU87WUFDUCxRQUFRLEVBQUUsR0FBRztTQUNkLENBQUMsQ0FBQztRQUNILElBQUksR0FBRyxJQUFJLElBQUksRUFBRTtZQUNmLE9BQU87U0FDUjtRQUVELElBQUksbUJBQW1CO1lBQUUsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFbEQsK0RBQStEO1FBQy9ELHNDQUFzQztRQUN0QyxFQUFFO1FBQ0YsMkVBQTJFO1FBQzNFLGdCQUFnQjtRQUNoQixJQUFJLFVBQVU7WUFBRSxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFcEMsMkVBQTJFO1FBQzNFLDBCQUEwQjtRQUMxQiwyRUFBMkU7UUFFM0UsMkVBQTJFO1FBQzNFLEdBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBQ3JCLElBQUksT0FBTyxFQUFFO1lBQ1gsc0VBQXNFO1lBQ3RFLDBEQUEwRDtZQUMxRCxHQUFHLENBQUMsU0FBUyxDQUNYLHdCQUF3QixFQUN4Qix3QkFBd0IsSUFBSSxHQUFHLGVBQWUsR0FBRyxnQkFBZ0IsRUFBRSxDQUNwRSxDQUFDO1NBQ0g7UUFFRCwyREFBMkQ7UUFDM0QsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtZQUM1QixHQUFHLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUNyQixHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDVixPQUFPO1NBQ1I7UUFFRCxvRUFBb0U7UUFDcEUsb0VBQW9FO1FBQ3BFLDRDQUE0QztRQUM1QyxJQUFJLFVBQWUsQ0FBQztRQUNwQixJQUFJLE9BQU8sR0FJTixFQUFFLENBQUM7UUFDUixNQUFNLGNBQWMsR0FBRyxDQUFDLGVBQWUsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDNUQsSUFBSSxNQUFjLENBQUM7UUFFbkIsSUFBSSxZQUFZLENBQUMsT0FBTztZQUFFLFlBQVksQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1FBQzNFLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztRQUV4Qix5RUFBeUU7UUFDekUseUVBQXlFO1FBQ3pFLDRCQUE0QjtRQUM1QixJQUFJO1lBQ0Ysd0VBQXdFO1lBQ3hFLDZEQUE2RDtZQUM3RCxNQUFNLFNBQVMsR0FBRywwQkFBMEIsSUFBSSxDQUFDLE1BQU0sWUFBWSxFQUFFLENBQUMsQ0FBQztZQUV2RSxtRUFBbUU7WUFDbkUseUVBQXlFO1lBQ3pFLGdFQUFnRTtZQUNoRSxFQUFFO1lBQ0YseUVBQXlFO1lBQ3pFLDJDQUEyQztZQUMzQyxNQUFNLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFFMUIsNkRBQTZEO1lBQzdELElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxNQUFNLEVBQUU7Z0JBQ3pCLEdBQUcsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLGVBQWUsQ0FBQyxDQUFDO2dCQUN4QyxNQUFNLFNBQVMsQ0FBQyxHQUFHLEVBQUUsbUNBQW1DLENBQUMsQ0FBQzthQUMzRDtZQUVELHdFQUF3RTtZQUN4RSxXQUFXO1lBQ1gsRUFBRTtZQUNGLGdEQUFnRDtZQUNoRCx1RUFBdUU7WUFDdkUsd0VBQXdFO1lBQ3hFLGtCQUFrQjtZQUNsQixNQUFNLElBQUksR0FBa0MsR0FBVyxDQUFDLElBQUksQ0FBQztZQUM3RCxVQUFVLEdBQUcsT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBRS9ELHdDQUF3QztZQUN4QyxJQUFJLFVBQVUsSUFBSSxJQUFJO2dCQUNwQixNQUFNLFNBQVMsQ0FBQyxHQUFHLEVBQUUsdURBQXVELENBQUMsQ0FBQztZQUNoRixJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVE7Z0JBQ2hDLE1BQU0sU0FBUyxDQUNiLEdBQUcsRUFDSCxpREFBaUQsT0FBTyxVQUFVLElBQUksQ0FDdkUsQ0FBQztZQUNKLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRTtnQkFDN0IsSUFBSSxDQUFDLG1CQUFtQixFQUFFO29CQUN4QixNQUFNLFNBQVMsQ0FDYixHQUFHLEVBQ0gsOEZBQThGLENBQy9GLENBQUM7aUJBQ0g7cUJBQU07b0JBQ0wsV0FBVyxHQUFHLElBQUksQ0FBQztpQkFDcEI7YUFDRjtpQkFBTTtnQkFDTCxVQUFVLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUMzQjtZQUNELFVBQVUsR0FBRyxVQUFVLENBQUMsNkJBQTZCLEVBQUUsVUFBVSxFQUFFO2dCQUNqRSxPQUFPO2dCQUNQLEdBQUc7Z0JBQ0gsR0FBRztnQkFDSCxXQUFXO2dCQUNYLFNBQVM7YUFDVixDQUFDLENBQUM7WUFDSCxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUN6QixVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFXLEVBQUUsRUFBRTtnQkFDbkMsSUFBSSxnQkFBZ0IsR0FBd0IsSUFBSSxDQUFDO2dCQUNqRCxJQUFJLE1BQVcsQ0FBQztnQkFDaEIsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDakMsSUFBSTtvQkFDRixJQUFJLENBQUMsTUFBTTt3QkFBRSxNQUFNLFNBQVMsQ0FBQyxHQUFHLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztvQkFDOUQsTUFBTSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsR0FBRyxNQUFNLENBQUM7b0JBQ3hDLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxNQUFNLENBQUM7b0JBQzNCLElBQUksQ0FBQyxLQUFLO3dCQUFFLE1BQU0sU0FBUyxDQUFDLEdBQUcsRUFBRSw4QkFBOEIsQ0FBQyxDQUFDO29CQUVqRSxzRUFBc0U7b0JBQ3RFLHNCQUFzQjtvQkFDdEIsSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLEVBQUU7d0JBQ2pDLHFFQUFxRTt3QkFDckUsYUFBYTt3QkFDYixJQUFJLFNBQVMsS0FBSyxFQUFFLEVBQUU7NEJBQ3BCLFNBQVMsR0FBRyxJQUFJLENBQUM7eUJBQ2xCOzZCQUFNOzRCQUNMLDZDQUE2Qzs0QkFDN0MsSUFBSTtnQ0FDRixTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQzs2QkFDbkM7NEJBQUMsT0FBTyxLQUFLLEVBQUU7Z0NBQ2QsS0FBSyxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUM7Z0NBQ3ZCLE1BQU0sS0FBSyxDQUFDOzZCQUNiO3lCQUNGO3FCQUNGO29CQUVELGtEQUFrRDtvQkFDbEQsSUFBSSxTQUFTLElBQUksSUFBSSxJQUFJLE9BQU8sU0FBUyxLQUFLLFFBQVE7d0JBQ3BELE1BQU0sU0FBUyxDQUFDLEdBQUcsRUFBRSxxQ0FBcUMsT0FBTyxTQUFTLElBQUksQ0FBQyxDQUFDO29CQUVsRixxREFBcUQ7b0JBQ3JELElBQUksYUFBYSxJQUFJLElBQUksSUFBSSxPQUFPLGFBQWEsS0FBSyxRQUFRO3dCQUM1RCxNQUFNLFNBQVMsQ0FDYixHQUFHLEVBQ0gseUNBQXlDLE9BQU8sYUFBYSxJQUFJLENBQ2xFLENBQUM7b0JBRUosSUFBSSxnQkFBNkMsQ0FBQztvQkFDbEQsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLEdBQUcsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUV4RSxJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7d0JBQ2pDLHFDQUFxQzt3QkFDckMsaUVBQWlFO3dCQUNqRSxxREFBcUQ7d0JBQ3JELE1BQU0sbUJBQW1CLEdBQUcsVUFBVSxDQUFDLDhCQUE4QixFQUFFLEVBQUUsRUFBRTs0QkFDekUsT0FBTzs0QkFDUCxHQUFHOzRCQUNILEdBQUc7NEJBQ0gsU0FBUzs0QkFDVCxhQUFhOzRCQUNiLElBQUk7eUJBQ0wsQ0FBQyxDQUFDO3dCQUNILElBQUksbUJBQW1CLENBQUMsTUFBTSxFQUFFOzRCQUM5QixnQkFBZ0IsR0FBRyxrQkFBZSxDQUNoQyxTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLG1CQUFtQixDQUNwQixDQUFDO3lCQUNIO3FCQUNGO29CQUVELHNFQUFzRTtvQkFDdEUsbURBQW1EO29CQUNuRCxJQUFJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7d0JBQy9CLE1BQU0sR0FBRyxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLENBQUM7cUJBQ3hEO3lCQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTt3QkFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO3FCQUM1Qzt5QkFBTTt3QkFDTCxJQUFJLFlBQVksQ0FBQyxPQUFPOzRCQUFFLFlBQVksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO3dCQUV0RSxzRUFBc0U7d0JBQ3RFLElBQUksWUFBWSxDQUFDLE9BQU87NEJBQ3RCLFlBQVksQ0FBQyxJQUFJLEVBQUUsZUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO3dCQUVqRixNQUFNLEdBQUcsTUFBTSxpQ0FBaUMsQ0FDOUMsR0FBRzt3QkFDSCwwRUFBMEU7d0JBQzFFLEdBQUcsQ0FBQyxxQkFBcUIsRUFBRSxFQUMzQjs0QkFDRSxlQUFlLEVBQUUsS0FBSzs0QkFDdEIsZ0JBQWdCOzRCQUNoQixTQUFTOzRCQUNULGFBQWE7eUJBQ2QsRUFDRCxDQUFDLGNBQW1CLEVBQUUsRUFBRTs0QkFDdEIsTUFBTSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUM7NEJBQy9CLE1BQU0sYUFBYSxHQUFHLGlCQUFjLENBQ2xDLFNBQVMsRUFDVCxnQkFBaUIsRUFDakIsSUFBSSxFQUNKLGNBQWMsRUFDZCxTQUFTLEVBQ1QsYUFBYSxDQUNkLENBQUM7NEJBQ0YsSUFBSSxPQUFPLGNBQWMsQ0FBQyxpQkFBaUIsS0FBSyxVQUFVLEVBQUU7Z0NBQzFELE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDLEdBQUcsRUFBQyxFQUFFLENBQUMsQ0FBQztvQ0FDdkQsR0FBRyxHQUFHO29DQUNOLHVCQUF1QjtvQ0FDdkIsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDLGlCQUFpQixFQUFFO2lDQUNsRCxDQUFDLENBQUMsQ0FBQzs2QkFDTDtpQ0FBTTtnQ0FDTCxPQUFPLGFBQWEsQ0FBQzs2QkFDdEI7d0JBQ0gsQ0FBQyxDQUNGLENBQUM7cUJBQ0g7aUJBQ0Y7Z0JBQUMsT0FBTyxLQUFLLEVBQUU7b0JBQ2QsTUFBTSxHQUFHO3dCQUNQLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQzt3QkFDZixVQUFVLEVBQUUsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxJQUFJLEdBQUc7cUJBQ3BELENBQUM7b0JBRUYsa0RBQWtEO29CQUNsRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssR0FBRzt3QkFDM0Isc0NBQXNDO3dCQUN0QyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDOUI7d0JBQVM7b0JBQ1IsOERBQThEO29CQUM5RCxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO3dCQUMzQixNQUFNLENBQUMsTUFBTSxHQUFJLFlBQW9CLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7cUJBQ2hFO29CQUNELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQ2xCLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO3FCQUNwQjtvQkFDRCxNQUFNLEdBQUcsVUFBVSxDQUFDLDBCQUEwQixFQUFFLE1BQU0sRUFBRTt3QkFDdEQsT0FBTzt3QkFDUCxXQUFXO3dCQUNYLGdCQUFnQjt3QkFDaEIsR0FBRzt3QkFDSCxNQUFNO3FCQUdQLENBQUMsQ0FBQztvQkFDSCwrREFBK0Q7b0JBQy9ELElBQUksQ0FBQyxlQUFlLElBQUksZ0JBQWdCLEVBQUU7d0JBQ3hDLHdCQUF3Qjt3QkFDeEIsTUFBTSwwQkFBMEIsR0FBRyxnQkFBZ0IsQ0FBQzt3QkFDcEQsOENBQThDO3dCQUM5QyxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7d0JBQzNDLE1BQU0sUUFBUSxHQUFHLGNBQWMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO3dCQUNsRSxZQUFZLENBQUMsR0FBRyxFQUFFOzRCQUNoQixNQUFNLFdBQVcsR0FBRyxlQUFZLENBQUMsMEJBQTBCLENBQUM7aUNBQ3pELE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDO2lDQUNwQixJQUFJLEVBQUUsQ0FBQzs0QkFDVixNQUFNLFVBQVUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDOzRCQUNoRCxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7NEJBRWxELElBQUksT0FBZSxDQUFDOzRCQUNwQixJQUFJLGdCQUFnQixLQUFLLEdBQUcsRUFBRTtnQ0FDNUIsMkRBQTJEO2dDQUMzRCxFQUFFO2dDQUNGLHdEQUF3RDtnQ0FDeEQsT0FBTyxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQzs2QkFDakQ7aUNBQU0sSUFBSSxnQkFBZ0IsS0FBSyxHQUFHLEVBQUU7Z0NBQ25DLE9BQU8sR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7NkJBQzVDO2lDQUFNO2dDQUNMLE9BQU8sR0FBRyxlQUFLLENBQUMsVUFBVSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLFVBQVUsV0FBVyxDQUFDLENBQUM7NkJBQy9FOzRCQUVELHNDQUFzQzs0QkFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FDVCxHQUFHLE9BQU8sSUFDUixNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLGVBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFDcEQsTUFBTSxlQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sV0FBVyxFQUFFLENBQzNELENBQUM7d0JBQ0osQ0FBQyxDQUFDLENBQUM7cUJBQ0o7b0JBQ0QsSUFBSSxZQUFZLENBQUMsT0FBTzt3QkFBRSxZQUFZLENBQUMsa0NBQWtDLENBQUMsQ0FBQztpQkFDNUU7Z0JBQ0QsT0FBTyxNQUFNLENBQUM7WUFDaEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztTQUNIO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCx1REFBdUQ7WUFDdkQsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLEdBQUc7Z0JBQUUsR0FBRyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFDO1lBRXJGLDRCQUE0QjtZQUM1QixXQUFXLEdBQUcsS0FBSyxDQUFDO1lBQ3BCLE9BQU8sR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFHLFlBQW9CLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRWpFLGtEQUFrRDtZQUNsRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLEtBQUssR0FBRyxFQUFFO2dCQUMxQixzQ0FBc0M7Z0JBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzVCO1NBQ0Y7Z0JBQVM7WUFDUiwyQ0FBMkM7WUFDM0MsSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDaEIsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLEdBQUcsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFO29CQUNuRCxHQUFHLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7aUJBQ3hDO2dCQUNELE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO2FBQ25DO1lBRUQsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztZQUNqRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FDdkMsdUJBQXVCLEVBQ3ZCO2dCQUNFLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVTtnQkFDMUIsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFFO2FBQzVDLEVBQ0Q7Z0JBQ0UsT0FBTztnQkFDUCxXQUFXO2dCQUNYLEdBQUc7Z0JBQ0gsK0RBQStEO2dCQUMvRCxHQUFHLEVBQUUsR0FBRyxDQUFDLHFCQUFxQixFQUFFO2FBQ2pDLENBQ0YsQ0FBQztZQUVGLElBQUksVUFBVSxFQUFFO2dCQUNkLEdBQUcsQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO2FBQzdCO1lBQ0QsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFFaEMsSUFBSSxZQUFZLENBQUMsT0FBTyxFQUFFO2dCQUN4QixZQUFZLENBQUMsVUFBVSxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLG9CQUFvQixDQUFDLENBQUM7YUFDdkY7U0FDRjtJQUNILENBQUMsQ0FDRixDQUFDO0lBRUY7Ozs7Ozs7Ozs7T0FVRztJQUNILE1BQU0sVUFBVSxHQUFRLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxDQUFNLEVBQUUsRUFBRTtRQUNqRCxzRUFBc0U7UUFDdEUsb0JBQW9CO1FBQ3BCLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRTtZQUNsQix3Q0FBd0M7WUFDeEMsTUFBTSxHQUFHLEdBQUcsQ0FBcUIsQ0FBQztZQUNsQyxNQUFNLElBQUksR0FBRyxDQUFrQixDQUFDO1lBQ2hDLE1BQU0sZUFBZSxHQUFHLElBQUksb0NBQXVCLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRS9ELG9FQUFvRTtZQUNwRSxvRUFBb0U7WUFDcEUsb0JBQW9CO1lBQ3BCLE9BQU8sY0FBYyxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQztTQUM5QzthQUFNO1lBQ0wseUVBQXlFO1lBQ3pFLHFFQUFxRTtZQUNyRSxpQkFBaUI7WUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBb0IsQ0FBQztZQUNqQyxNQUFNLEdBQUcsR0FBRyxDQUFtQixDQUFDO1lBQ2hDLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sZUFBZSxHQUFHLElBQUkscUNBQXdCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUVyRSx1RkFBdUY7WUFDdkYsY0FBYyxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEQsbUJBQW1CO1NBQ3BCO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsVUFBVSxDQUFDLGdCQUFnQixHQUFHLFlBQVksQ0FBQztJQUMzQyxVQUFVLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUNyQyxVQUFVLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUMzQixVQUFVLENBQUMsaUNBQWlDLEdBQUcsaUNBQWlDLENBQUM7SUFDakYsVUFBVSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDdkMsVUFBVSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDN0IsVUFBVSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDdkMsVUFBVSxDQUFDLG1CQUFtQixHQUFHLG1CQUFtQixDQUFDO0lBQ3JELFVBQVUsQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO0lBQ3pDLFVBQVUsQ0FBQyxvQkFBb0IsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDekUsVUFBVSxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUN2RSxVQUFVLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7SUFDL0MsVUFBVSxDQUFDLHVCQUF1QixHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUM5RSxVQUFVLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztJQUM3QyxlQUFlO0lBQ2YsVUFBVSxDQUFDLE9BQU8sR0FBRyxHQUFrQixFQUFFLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBRXRFLE1BQU0sZ0JBQWdCLEdBQUcsVUFBVSxDQUFDLHlCQUF5QixFQUFFLFVBQVUsRUFBRTtRQUN6RSxPQUFPO1FBQ1AsZUFBZTtRQUNmLGVBQWU7S0FDaEIsQ0FBQyxDQUFDO0lBQ0gsZ0JBQWdCO0lBQ2hCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN0QyxNQUFNLElBQUksS0FBSyxDQUNiLGdJQUFnSSxDQUNqSSxDQUFDO0tBQ0g7SUFFRCxPQUFPLGdCQUFzQyxDQUFDO0FBQ2hELENBQUM7QUE3OEJELHVEQTY4QkM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQVMsY0FBYyxDQUFDLEdBQXlCO0lBQy9DLEdBQUcsQ0FBQyxTQUFTLENBQUMsNkJBQTZCLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDbEQsR0FBRyxDQUFDLFNBQVMsQ0FBQyw4QkFBOEIsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ2pFLEdBQUcsQ0FBQyxTQUFTLENBQ1gsOEJBQThCLEVBQzlCO1FBQ0UsUUFBUTtRQUNSLGtCQUFrQjtRQUNsQix3RUFBd0U7UUFDeEUsa0NBQWtDO1FBQ2xDLFFBQVE7UUFDUiwwQ0FBMEM7UUFDMUMsZUFBZTtRQUNmLDhEQUE4RDtRQUM5RCxrQkFBa0I7UUFDbEIscUVBQXFFO1FBQ3JFLDBCQUEwQjtRQUMxQixjQUFjO1FBQ2QsZ0JBQWdCO1FBQ2hCLDRCQUE0QjtRQUM1Qix3QkFBd0I7S0FDekIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQ2IsQ0FBQztJQUNGLEdBQUcsQ0FBQyxTQUFTLENBQUMsK0JBQStCLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3hGLENBQUM7QUFFRCxTQUFTLGlDQUFpQztJQUN4QyxPQUFPLFNBQVMsQ0FBQyxHQUFHLEVBQUUsa0VBQWtFLENBQUMsQ0FBQztBQUM1RixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sc0JBQXNCLEdBQUcsd0NBQXdDLENBQUM7QUFFeEU7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBUyxXQUFXLENBQUMsT0FBd0I7SUFDM0MsTUFBTSxFQUFFLGFBQWEsRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7SUFDMUMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUFFLE1BQU0saUNBQWlDLEVBQUUsQ0FBQztJQUU1RSwwREFBMEQ7SUFDMUQsSUFBSSxhQUFhLElBQUksSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBRXZDLE1BQU0sS0FBSyxHQUFHLHNCQUFzQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUV6RCx5RUFBeUU7SUFDekUscUJBQXFCO0lBQ3JCLElBQUksQ0FBQyxLQUFLO1FBQUUsTUFBTSxpQ0FBaUMsRUFBRSxDQUFDO0lBRXRELG1DQUFtQztJQUNuQyxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDIn0=