UNPKG

fusion-plugin-rpc

Version:

Fetch data on the server and client with an RPC style interface.

125 lines (122 loc) 14.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _fusionCore = require("fusion-core"); var _fusionPluginUniversalEvents = require("fusion-plugin-universal-events"); var _fusionPluginI18n = require("fusion-plugin-i18n"); var _fusionTokens = require("fusion-tokens"); var _tokens = require("./tokens"); var _utils = require("./utils"); /** Copyright (c) 2018 Uber Technologies, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ /* eslint-env browser */ const statKey = 'rpc:method-client'; class RPC { constructor({ fetch, emitter, rpcConfig, queryParams }) { this.fetch = fetch; this.config = rpcConfig || {}; this.emitter = emitter; this.queryParams = queryParams; this.apiPath = (0, _utils.formatApiPath)(rpcConfig && rpcConfig.apiPath ? rpcConfig.apiPath : 'api'); } request(rpcId, args, headers, options) { if (!this.fetch) { throw new Error('fusion-plugin-rpc requires `fetch`'); } if (!this.emitter) { throw new Error('Missing emitter registered to UniversalEventsToken'); } const fetch = this.fetch; const emitter = this.emitter; const apiPath = this.apiPath; const startTime = Date.now(); const queryParams = this.queryParams.length > 0 ? `?${this.queryParams.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&')}` : ''; return fetch(`${apiPath}${rpcId}${queryParams}`, args instanceof FormData ? { ...options, method: 'POST', headers: { // Content-Type will be set automatically ...(headers || {}) }, body: args } : { ...options, method: 'POST', // $FlowFixMe headers: { 'Content-Type': 'application/json', ...(headers || {}) }, body: JSON.stringify(args || {}) }).then(r => r.json()).then(args => { const { status, data } = args; if (status === 'success') { emitter.emit(statKey, { method: rpcId, status: 'success', timing: Date.now() - startTime }); return data; } else { emitter.emit(statKey, { method: rpcId, error: data, status: 'failure', timing: Date.now() - startTime }); return Promise.reject(data ? data : {}); } }); } } const pluginFactory = () => (0, _fusionCore.createPlugin)({ deps: { fetch: _fusionTokens.FetchToken, emitter: _fusionPluginUniversalEvents.UniversalEventsToken, i18n: _fusionPluginI18n.I18nToken.optional, rpcConfig: _tokens.RPCHandlersConfigToken.optional, queryParams: _tokens.RPCQueryParamsToken.optional }, provides: deps => { const { fetch = window.fetch, emitter, rpcConfig, i18n, queryParams } = deps; return { from: (0, _fusionCore.memoize)(ctx => { const queryParamsValue = queryParams && queryParams.from(ctx) || []; const locale = i18n && i18n.from(ctx).locale || ''; const localeCode = typeof locale === 'string' ? locale : locale.code; if (localeCode) { queryParamsValue.push(['localeCode', localeCode]); } return new RPC({ fetch, emitter, rpcConfig, queryParams: queryParamsValue }); }) }; } }); var _default = true && pluginFactory(); exports.default = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzdGF0S2V5IiwiUlBDIiwiY29uc3RydWN0b3IiLCJmZXRjaCIsImVtaXR0ZXIiLCJycGNDb25maWciLCJxdWVyeVBhcmFtcyIsImNvbmZpZyIsImFwaVBhdGgiLCJmb3JtYXRBcGlQYXRoIiwicmVxdWVzdCIsInJwY0lkIiwiYXJncyIsImhlYWRlcnMiLCJvcHRpb25zIiwiRXJyb3IiLCJzdGFydFRpbWUiLCJEYXRlIiwibm93IiwibGVuZ3RoIiwibWFwIiwiayIsInYiLCJlbmNvZGVVUklDb21wb25lbnQiLCJqb2luIiwiRm9ybURhdGEiLCJtZXRob2QiLCJib2R5IiwiSlNPTiIsInN0cmluZ2lmeSIsInRoZW4iLCJyIiwianNvbiIsInN0YXR1cyIsImRhdGEiLCJlbWl0IiwidGltaW5nIiwiZXJyb3IiLCJQcm9taXNlIiwicmVqZWN0IiwicGx1Z2luRmFjdG9yeSIsImNyZWF0ZVBsdWdpbiIsImRlcHMiLCJGZXRjaFRva2VuIiwiVW5pdmVyc2FsRXZlbnRzVG9rZW4iLCJpMThuIiwiSTE4blRva2VuIiwib3B0aW9uYWwiLCJSUENIYW5kbGVyc0NvbmZpZ1Rva2VuIiwiUlBDUXVlcnlQYXJhbXNUb2tlbiIsInByb3ZpZGVzIiwid2luZG93IiwiZnJvbSIsIm1lbW9pemUiLCJjdHgiLCJxdWVyeVBhcmFtc1ZhbHVlIiwibG9jYWxlIiwibG9jYWxlQ29kZSIsImNvZGUiLCJwdXNoIl0sInNvdXJjZXMiOlsic3JjL2Jyb3dzZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIENvcHlyaWdodCAoYykgMjAxOCBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG4vKiBlc2xpbnQtZW52IGJyb3dzZXIgKi9cblxuaW1wb3J0IHtjcmVhdGVQbHVnaW4sIG1lbW9pemUsIHR5cGUgQ29udGV4dH0gZnJvbSAnZnVzaW9uLWNvcmUnO1xuaW1wb3J0IHtVbml2ZXJzYWxFdmVudHNUb2tlbn0gZnJvbSAnZnVzaW9uLXBsdWdpbi11bml2ZXJzYWwtZXZlbnRzJztcbmltcG9ydCB7STE4blRva2VufSBmcm9tICdmdXNpb24tcGx1Z2luLWkxOG4nO1xuaW1wb3J0IHtGZXRjaFRva2VufSBmcm9tICdmdXNpb24tdG9rZW5zJztcbmltcG9ydCB0eXBlIHtGZXRjaH0gZnJvbSAnZnVzaW9uLXRva2Vucyc7XG5cbmltcG9ydCB7XG4gIHR5cGUgSGFuZGxlclR5cGUsXG4gIFJQQ0hhbmRsZXJzQ29uZmlnVG9rZW4sXG4gIFJQQ1F1ZXJ5UGFyYW1zVG9rZW4sXG59IGZyb20gJy4vdG9rZW5zJztcbmltcG9ydCB0eXBlIHtSUENQbHVnaW5UeXBlLCBJRW1pdHRlciwgUlBDQ29uZmlnVHlwZX0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge2Zvcm1hdEFwaVBhdGh9IGZyb20gJy4vdXRpbHMnO1xuXG50eXBlIEluaXRpYWxpemF0aW9uT3B0cyA9IHtcbiAgZmV0Y2g6IEZldGNoO1xuICBlbWl0dGVyOiBJRW1pdHRlcjtcbiAgcXVlcnlQYXJhbXM6IEFycmF5PFtzdHJpbmcsIHN0cmluZ10+O1xuICBycGNDb25maWc6IFJQQ0NvbmZpZ1R5cGUgfCB1bmRlZmluZWQgfCBudWxsO1xufTtcblxuY29uc3Qgc3RhdEtleSA9ICdycGM6bWV0aG9kLWNsaWVudCc7XG5cbmNsYXNzIFJQQyB7XG4gIGN0eDogQ29udGV4dCB8IHVuZGVmaW5lZCB8IG51bGw7XG4gIGVtaXR0ZXI6IElFbWl0dGVyIHwgdW5kZWZpbmVkIHwgbnVsbDtcbiAgaGFuZGxlcnM6IEhhbmRsZXJUeXBlIHwgdW5kZWZpbmVkIHwgbnVsbDtcbiAgcXVlcnlQYXJhbXM6IEFycmF5PFtzdHJpbmcsIHN0cmluZ10+O1xuICBmZXRjaDogRmV0Y2ggfCB1bmRlZmluZWQgfCBudWxsO1xuICBjb25maWc6IFJQQ0NvbmZpZ1R5cGUgfCB1bmRlZmluZWQgfCBudWxsO1xuICBhcGlQYXRoOiBzdHJpbmc7XG4gIGNvbnN0cnVjdG9yKHtmZXRjaCwgZW1pdHRlciwgcnBjQ29uZmlnLCBxdWVyeVBhcmFtc306IEluaXRpYWxpemF0aW9uT3B0cykge1xuICAgIHRoaXMuZmV0Y2ggPSBmZXRjaDtcbiAgICB0aGlzLmNvbmZpZyA9IHJwY0NvbmZpZyB8fCB7fTtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICAgIHRoaXMucXVlcnlQYXJhbXMgPSBxdWVyeVBhcmFtcztcblxuICAgIHRoaXMuYXBpUGF0aCA9IGZvcm1hdEFwaVBhdGgoXG4gICAgICBycGNDb25maWcgJiYgcnBjQ29uZmlnLmFwaVBhdGggPyBycGNDb25maWcuYXBpUGF0aCA6ICdhcGknXG4gICAgKTtcbiAgfVxuXG4gIHJlcXVlc3Q8VEFyZ3MsIFRSZXN1bHQ+KFxuICAgIHJwY0lkOiBzdHJpbmcsXG4gICAgYXJnczogVEFyZ3MsXG4gICAgaGVhZGVycz86IHtcbiAgICAgIFt4OiBzdHJpbmddOiBzdHJpbmc7XG4gICAgfSB8IG51bGwsXG4gICAgb3B0aW9ucz86IFJlcXVlc3RJbml0IHwgbnVsbFxuICApOiBQcm9taXNlPFRSZXN1bHQ+IHtcbiAgICBpZiAoIXRoaXMuZmV0Y2gpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZnVzaW9uLXBsdWdpbi1ycGMgcmVxdWlyZXMgYGZldGNoYCcpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuZW1pdHRlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGVtaXR0ZXIgcmVnaXN0ZXJlZCB0byBVbml2ZXJzYWxFdmVudHNUb2tlbicpO1xuICAgIH1cbiAgICBjb25zdCBmZXRjaCA9IHRoaXMuZmV0Y2g7XG4gICAgY29uc3QgZW1pdHRlciA9IHRoaXMuZW1pdHRlcjtcbiAgICBjb25zdCBhcGlQYXRoID0gdGhpcy5hcGlQYXRoO1xuXG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBxdWVyeVBhcmFtcyA9XG4gICAgICB0aGlzLnF1ZXJ5UGFyYW1zLmxlbmd0aCA+IDBcbiAgICAgICAgPyBgPyR7dGhpcy5xdWVyeVBhcmFtc1xuICAgICAgICAgICAgLm1hcChcbiAgICAgICAgICAgICAgKFtrLCB2XSkgPT4gYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGspfT0ke2VuY29kZVVSSUNvbXBvbmVudCh2KX1gXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuam9pbignJicpfWBcbiAgICAgICAgOiAnJztcblxuICAgIHJldHVybiBmZXRjaChcbiAgICAgIGAke2FwaVBhdGh9JHtycGNJZH0ke3F1ZXJ5UGFyYW1zfWAsXG4gICAgICBhcmdzIGluc3RhbmNlb2YgRm9ybURhdGFcbiAgICAgICAgPyB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgIC8vIENvbnRlbnQtVHlwZSB3aWxsIGJlIHNldCBhdXRvbWF0aWNhbGx5XG4gICAgICAgICAgICAgIC4uLihoZWFkZXJzIHx8IHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiBhcmdzLFxuICAgICAgICAgIH1cbiAgICAgICAgOiB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAgIC4uLihoZWFkZXJzIHx8IHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShhcmdzIHx8IHt9KSxcbiAgICAgICAgICB9XG4gICAgKVxuICAgICAgLnRoZW4oKHIpID0+IHIuanNvbigpKVxuICAgICAgLnRoZW4oKGFyZ3MpID0+IHtcbiAgICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhcmdzO1xuICAgICAgICBpZiAoc3RhdHVzID09PSAnc3VjY2VzcycpIHtcbiAgICAgICAgICBlbWl0dGVyLmVtaXQoc3RhdEtleSwge1xuICAgICAgICAgICAgbWV0aG9kOiBycGNJZCxcbiAgICAgICAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxuICAgICAgICAgICAgdGltaW5nOiBEYXRlLm5vdygpIC0gc3RhcnRUaW1lLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVtaXR0ZXIuZW1pdChzdGF0S2V5LCB7XG4gICAgICAgICAgICBtZXRob2Q6IHJwY0lkLFxuICAgICAgICAgICAgZXJyb3I6IGRhdGEsXG4gICAgICAgICAgICBzdGF0dXM6ICdmYWlsdXJlJyxcbiAgICAgICAgICAgIHRpbWluZzogRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZGF0YSA/IGRhdGEgOiB7fSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG59XG5cbmNvbnN0IHBsdWdpbkZhY3Rvcnk6ICgpID0+IFJQQ1BsdWdpblR5cGUgPSAoKSA9PlxuICBjcmVhdGVQbHVnaW4oe1xuICAgIGRlcHM6IHtcbiAgICAgIGZldGNoOiBGZXRjaFRva2VuLFxuICAgICAgZW1pdHRlcjogVW5pdmVyc2FsRXZlbnRzVG9rZW4sXG4gICAgICBpMThuOiBJMThuVG9rZW4ub3B0aW9uYWwsXG4gICAgICBycGNDb25maWc6IFJQQ0hhbmRsZXJzQ29uZmlnVG9rZW4ub3B0aW9uYWwsXG4gICAgICBxdWVyeVBhcmFtczogUlBDUXVlcnlQYXJhbXNUb2tlbi5vcHRpb25hbCxcbiAgICB9LFxuICAgIHByb3ZpZGVzOiAoZGVwcykgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBmZXRjaCA9IHdpbmRvdy5mZXRjaCxcbiAgICAgICAgZW1pdHRlcixcbiAgICAgICAgcnBjQ29uZmlnLFxuICAgICAgICBpMThuLFxuICAgICAgICBxdWVyeVBhcmFtcyxcbiAgICAgIH0gPSBkZXBzO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBmcm9tOiBtZW1vaXplKChjdHgpID0+IHtcbiAgICAgICAgICBjb25zdCBxdWVyeVBhcmFtc1ZhbHVlID0gKHF1ZXJ5UGFyYW1zICYmIHF1ZXJ5UGFyYW1zLmZyb20oY3R4KSkgfHwgW107XG4gICAgICAgICAgY29uc3QgbG9jYWxlID0gKGkxOG4gJiYgaTE4bi5mcm9tKGN0eCkubG9jYWxlKSB8fCAnJztcbiAgICAgICAgICBjb25zdCBsb2NhbGVDb2RlID0gdHlwZW9mIGxvY2FsZSA9PT0gJ3N0cmluZycgPyBsb2NhbGUgOiBsb2NhbGUuY29kZTtcbiAgICAgICAgICBpZiAobG9jYWxlQ29kZSkge1xuICAgICAgICAgICAgcXVlcnlQYXJhbXNWYWx1ZS5wdXNoKFsnbG9jYWxlQ29kZScsIGxvY2FsZUNvZGVdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBSUEMoe1xuICAgICAgICAgICAgZmV0Y2gsXG4gICAgICAgICAgICBlbWl0dGVyLFxuICAgICAgICAgICAgcnBjQ29uZmlnLFxuICAgICAgICAgICAgcXVlcnlQYXJhbXM6IHF1ZXJ5UGFyYW1zVmFsdWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9LFxuICB9KTtcblxuZXhwb3J0IGRlZmF1bHQgX19CUk9XU0VSX18gJiYgKHBsdWdpbkZhY3RvcnkoKSBhcyBhbnkgYXMgUlBDUGx1Z2luVHlwZSk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFNQTtBQXJCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBdUJBLE1BQU1BLE9BQU8sR0FBRyxtQkFBbUI7QUFFbkMsTUFBTUMsR0FBRyxDQUFDO0VBUVJDLFdBQVcsQ0FBQztJQUFDQyxLQUFLO0lBQUVDLE9BQU87SUFBRUMsU0FBUztJQUFFQztFQUErQixDQUFDLEVBQUU7SUFDeEUsSUFBSSxDQUFDSCxLQUFLLEdBQUdBLEtBQUs7SUFDbEIsSUFBSSxDQUFDSSxNQUFNLEdBQUdGLFNBQVMsSUFBSSxDQUFDLENBQUM7SUFDN0IsSUFBSSxDQUFDRCxPQUFPLEdBQUdBLE9BQU87SUFDdEIsSUFBSSxDQUFDRSxXQUFXLEdBQUdBLFdBQVc7SUFFOUIsSUFBSSxDQUFDRSxPQUFPLEdBQUcsSUFBQUMsb0JBQWEsRUFDMUJKLFNBQVMsSUFBSUEsU0FBUyxDQUFDRyxPQUFPLEdBQUdILFNBQVMsQ0FBQ0csT0FBTyxHQUFHLEtBQUssQ0FDM0Q7RUFDSDtFQUVBRSxPQUFPLENBQ0xDLEtBQWEsRUFDYkMsSUFBVyxFQUNYQyxPQUVRLEVBQ1JDLE9BQTRCLEVBQ1Y7SUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQ1gsS0FBSyxFQUFFO01BQ2YsTUFBTSxJQUFJWSxLQUFLLENBQUMsb0NBQW9DLENBQUM7SUFDdkQ7SUFDQSxJQUFJLENBQUMsSUFBSSxDQUFDWCxPQUFPLEVBQUU7TUFDakIsTUFBTSxJQUFJVyxLQUFLLENBQUMsb0RBQW9ELENBQUM7SUFDdkU7SUFDQSxNQUFNWixLQUFLLEdBQUcsSUFBSSxDQUFDQSxLQUFLO0lBQ3hCLE1BQU1DLE9BQU8sR0FBRyxJQUFJLENBQUNBLE9BQU87SUFDNUIsTUFBTUksT0FBTyxHQUFHLElBQUksQ0FBQ0EsT0FBTztJQUU1QixNQUFNUSxTQUFTLEdBQUdDLElBQUksQ0FBQ0MsR0FBRyxFQUFFO0lBQzVCLE1BQU1aLFdBQVcsR0FDZixJQUFJLENBQUNBLFdBQVcsQ0FBQ2EsTUFBTSxHQUFHLENBQUMsR0FDdEIsSUFBRyxJQUFJLENBQUNiLFdBQVcsQ0FDakJjLEdBQUcsQ0FDRixDQUFDLENBQUNDLENBQUMsRUFBRUMsQ0FBQyxDQUFDLEtBQU0sR0FBRUMsa0JBQWtCLENBQUNGLENBQUMsQ0FBRSxJQUFHRSxrQkFBa0IsQ0FBQ0QsQ0FBQyxDQUFFLEVBQUMsQ0FDaEUsQ0FDQUUsSUFBSSxDQUFDLEdBQUcsQ0FBRSxFQUFDLEdBQ2QsRUFBRTtJQUVSLE9BQU9yQixLQUFLLENBQ1QsR0FBRUssT0FBUSxHQUFFRyxLQUFNLEdBQUVMLFdBQVksRUFBQyxFQUNsQ00sSUFBSSxZQUFZYSxRQUFRLEdBQ3BCO01BQ0UsR0FBR1gsT0FBTztNQUNWWSxNQUFNLEVBQUUsTUFBTTtNQUNkYixPQUFPLEVBQUU7UUFDUDtRQUNBLElBQUlBLE9BQU8sSUFBSSxDQUFDLENBQUM7TUFDbkIsQ0FBQztNQUNEYyxJQUFJLEVBQUVmO0lBQ1IsQ0FBQyxHQUNEO01BQ0UsR0FBR0UsT0FBTztNQUNWWSxNQUFNLEVBQUUsTUFBTTtNQUNkO01BQ0FiLE9BQU8sRUFBRTtRQUNQLGNBQWMsRUFBRSxrQkFBa0I7UUFDbEMsSUFBSUEsT0FBTyxJQUFJLENBQUMsQ0FBQztNQUNuQixDQUFDO01BQ0RjLElBQUksRUFBRUMsSUFBSSxDQUFDQyxTQUFTLENBQUNqQixJQUFJLElBQUksQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FDTixDQUNFa0IsSUFBSSxDQUFFQyxDQUFDLElBQUtBLENBQUMsQ0FBQ0MsSUFBSSxFQUFFLENBQUMsQ0FDckJGLElBQUksQ0FBRWxCLElBQUksSUFBSztNQUNkLE1BQU07UUFBQ3FCLE1BQU07UUFBRUM7TUFBSSxDQUFDLEdBQUd0QixJQUFJO01BQzNCLElBQUlxQixNQUFNLEtBQUssU0FBUyxFQUFFO1FBQ3hCN0IsT0FBTyxDQUFDK0IsSUFBSSxDQUFDbkMsT0FBTyxFQUFFO1VBQ3BCMEIsTUFBTSxFQUFFZixLQUFLO1VBQ2JzQixNQUFNLEVBQUUsU0FBUztVQUNqQkcsTUFBTSxFQUFFbkIsSUFBSSxDQUFDQyxHQUFHLEVBQUUsR0FBR0Y7UUFDdkIsQ0FBQyxDQUFDO1FBQ0YsT0FBT2tCLElBQUk7TUFDYixDQUFDLE1BQU07UUFDTDlCLE9BQU8sQ0FBQytCLElBQUksQ0FBQ25DLE9BQU8sRUFBRTtVQUNwQjBCLE1BQU0sRUFBRWYsS0FBSztVQUNiMEIsS0FBSyxFQUFFSCxJQUFJO1VBQ1hELE1BQU0sRUFBRSxTQUFTO1VBQ2pCRyxNQUFNLEVBQUVuQixJQUFJLENBQUNDLEdBQUcsRUFBRSxHQUFHRjtRQUN2QixDQUFDLENBQUM7UUFDRixPQUFPc0IsT0FBTyxDQUFDQyxNQUFNLENBQUNMLElBQUksR0FBR0EsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO01BQ3pDO0lBQ0YsQ0FBQyxDQUFDO0VBQ047QUFDRjtBQUVBLE1BQU1NLGFBQWtDLEdBQUcsTUFDekMsSUFBQUMsd0JBQVksRUFBQztFQUNYQyxJQUFJLEVBQUU7SUFDSnZDLEtBQUssRUFBRXdDLHdCQUFVO0lBQ2pCdkMsT0FBTyxFQUFFd0MsaURBQW9CO0lBQzdCQyxJQUFJLEVBQUVDLDJCQUFTLENBQUNDLFFBQVE7SUFDeEIxQyxTQUFTLEVBQUUyQyw4QkFBc0IsQ0FBQ0QsUUFBUTtJQUMxQ3pDLFdBQVcsRUFBRTJDLDJCQUFtQixDQUFDRjtFQUNuQyxDQUFDO0VBQ0RHLFFBQVEsRUFBR1IsSUFBSSxJQUFLO0lBQ2xCLE1BQU07TUFDSnZDLEtBQUssR0FBR2dELE1BQU0sQ0FBQ2hELEtBQUs7TUFDcEJDLE9BQU87TUFDUEMsU0FBUztNQUNUd0MsSUFBSTtNQUNKdkM7SUFDRixDQUFDLEdBQUdvQyxJQUFJO0lBRVIsT0FBTztNQUNMVSxJQUFJLEVBQUUsSUFBQUMsbUJBQU8sRUFBRUMsR0FBRyxJQUFLO1FBQ3JCLE1BQU1DLGdCQUFnQixHQUFJakQsV0FBVyxJQUFJQSxXQUFXLENBQUM4QyxJQUFJLENBQUNFLEdBQUcsQ0FBQyxJQUFLLEVBQUU7UUFDckUsTUFBTUUsTUFBTSxHQUFJWCxJQUFJLElBQUlBLElBQUksQ0FBQ08sSUFBSSxDQUFDRSxHQUFHLENBQUMsQ0FBQ0UsTUFBTSxJQUFLLEVBQUU7UUFDcEQsTUFBTUMsVUFBVSxHQUFHLE9BQU9ELE1BQU0sS0FBSyxRQUFRLEdBQUdBLE1BQU0sR0FBR0EsTUFBTSxDQUFDRSxJQUFJO1FBQ3BFLElBQUlELFVBQVUsRUFBRTtVQUNkRixnQkFBZ0IsQ0FBQ0ksSUFBSSxDQUFDLENBQUMsWUFBWSxFQUFFRixVQUFVLENBQUMsQ0FBQztRQUNuRDtRQUNBLE9BQU8sSUFBSXhELEdBQUcsQ0FBQztVQUNiRSxLQUFLO1VBQ0xDLE9BQU87VUFDUEMsU0FBUztVQUNUQyxXQUFXLEVBQUVpRDtRQUNmLENBQUMsQ0FBQztNQUNKLENBQUM7SUFDSCxDQUFDO0VBQ0g7QUFDRixDQUFDLENBQUM7QUFBQyxlQUVVLFFBQWdCZixhQUFhLEVBQTJCO0FBQUEifQ==