@cloudbase/storage
Version:
cloudbase js sdk storage module
706 lines • 84.3 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SupabaseFileAPILikeStorage = void 0;
var utilities_1 = require("@cloudbase/utilities");
var storage_1 = require("../storage");
var errors_1 = require("./errors");
var ERRORS = utilities_1.constants.ERRORS;
var SupabaseFileAPILikeStorage = (function (_super) {
__extends(SupabaseFileAPILikeStorage, _super);
function SupabaseFileAPILikeStorage(context) {
var _this = _super.call(this) || this;
_this.shouldThrowOnError = false;
_this.bucketId = '';
_this.context = context;
return _this;
}
Object.defineProperty(SupabaseFileAPILikeStorage.prototype, "config", {
get: function () {
var _a;
return (_a = this.context) === null || _a === void 0 ? void 0 : _a.config;
},
enumerable: false,
configurable: true
});
Object.defineProperty(SupabaseFileAPILikeStorage.prototype, "request", {
get: function () {
var _a;
return (_a = this.context) === null || _a === void 0 ? void 0 : _a.request;
},
enumerable: false,
configurable: true
});
SupabaseFileAPILikeStorage.prototype.throwOnError = function () {
this.shouldThrowOnError = true;
return this;
};
SupabaseFileAPILikeStorage.prototype.from = function (bucket) {
this.bucketId = bucket || '';
return this;
};
SupabaseFileAPILikeStorage.prototype.upload = function (path, fileBody, fileOptions) {
return __awaiter(this, void 0, void 0, function () {
var options, cacheControl, contentType, metadata, cloudPath, uploadFileParams, headers, result, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
options = __assign({ upsert: true }, fileOptions);
cacheControl = options.cacheControl, contentType = options.contentType, metadata = options.metadata;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
cloudPath = this._getCloudPath(path);
uploadFileParams = {
cloudPath: cloudPath,
filePath: fileBody,
};
if (cacheControl || contentType || metadata) {
headers = {};
if (cacheControl) {
headers['cache-control'] = cacheControl;
}
if (contentType) {
headers['content-type'] = contentType;
}
if (metadata) {
headers['x-cos-metadata-metadata'] = this.toBase64(JSON.stringify(metadata));
}
uploadFileParams.headers = headers;
}
return [4, this.uploadFile(uploadFileParams)];
case 2:
result = _a.sent();
if (!result.fileID) {
throw new Error(JSON.stringify({
code: ERRORS.OPERATION_FAIL,
msg: "[".concat(storage_1.COMPONENT_NAME, ".update] no fileID returned"),
}));
}
return [2, {
data: {
id: result.fileID,
path: path,
fullPath: path,
},
error: null,
}];
case 3:
error_1 = _a.sent();
if (this.shouldThrowOnError)
throw error_1;
if ((0, errors_1.isStorageError)(error_1)) {
return [2, {
data: null,
error: error_1,
}];
}
throw error_1;
case 4: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.uploadToSignedUrl = function (path, _token, fileBody, fileOptions) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.upload(path, fileBody, fileOptions)];
});
});
};
SupabaseFileAPILikeStorage.prototype.createSignedUploadUrl = function (path) {
return __awaiter(this, void 0, void 0, function () {
var cloudPath, metadata, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
cloudPath = this._getCloudPath(path);
return [4, this.getUploadMetadata({ cloudPath: cloudPath })];
case 1:
metadata = (_a.sent()).data;
return [2, {
data: {
signedUrl: metadata.url,
token: metadata.token,
path: path,
authorization: metadata.authorization,
id: metadata.fileId,
cosFileId: metadata.cosFileId,
downloadUrl: metadata.download_url,
},
error: null,
}];
case 2:
error_2 = _a.sent();
if (this.shouldThrowOnError)
throw error_2;
return [2, {
data: null,
error: error_2 instanceof errors_1.StorageError ? error_2 : new errors_1.StorageError(error_2.message),
}];
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.update = function (path, fileBody, fileOptions) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.upload(path, fileBody, __assign(__assign({}, fileOptions), { upsert: true }))];
});
});
};
SupabaseFileAPILikeStorage.prototype.move = function (fromPath, toPath) {
return __awaiter(this, void 0, void 0, function () {
var result, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.copyFile({
fileList: [
{
srcPath: this._getCloudPath(fromPath),
dstPath: this._getCloudPath(toPath),
overwrite: true,
removeOriginal: true,
},
],
})];
case 1:
result = _a.sent();
if (result.fileList[0].code && result.fileList[0].code !== 'SUCCESS') {
throw new errors_1.StorageError(result.fileList[0].message || 'Move failed');
}
return [2, {
data: { message: "File moved from ".concat(fromPath, " to ").concat(toPath) },
error: null,
}];
case 2:
error_3 = _a.sent();
if (this.shouldThrowOnError)
throw error_3;
if ((0, errors_1.isStorageError)(error_3)) {
return [2, {
data: null,
error: error_3,
}];
}
throw error_3;
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.copy = function (fromPath, toPath) {
return __awaiter(this, void 0, void 0, function () {
var result, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.copyFile({
fileList: [
{
srcPath: this._getCloudPath(fromPath),
dstPath: this._getCloudPath(toPath),
overwrite: true,
removeOriginal: false,
},
],
})];
case 1:
result = _a.sent();
if (result.fileList[0].code && result.fileList[0].code !== 'SUCCESS') {
throw new errors_1.StorageError(result.fileList[0].message || 'Copy failed');
}
return [2, {
data: { path: this._getCloudPath(toPath) },
error: null,
}];
case 2:
error_4 = _a.sent();
if (this.shouldThrowOnError)
throw error_4;
if ((0, errors_1.isStorageError)(error_4)) {
return [2, { data: null, error: error_4 }];
}
throw error_4;
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.createSignedUrl = function (path, expiresIn, options) {
return __awaiter(this, void 0, void 0, function () {
var cloudPath, result, signedUrl, queryParams, transformQuery, separator, error_5;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
cloudPath = this._normalizeCloudId(path);
return [4, this.getTempFileURL({
fileList: [
{
fileID: cloudPath,
maxAge: expiresIn,
},
],
})];
case 1:
result = _a.sent();
if (result.fileList[0].code !== 'SUCCESS') {
throw new errors_1.StorageError("Failed to create signed URL: [".concat(result.fileList[0].code, "] ").concat(result.fileList[0].fileID));
}
signedUrl = result.fileList[0].download_url;
queryParams = [];
if ((options === null || options === void 0 ? void 0 : options.download) !== undefined) {
if (typeof options.download === 'string') {
queryParams.push("download=".concat(encodeURIComponent(options.download)));
}
else if (options.download === true) {
queryParams.push('download=true');
}
}
if (options === null || options === void 0 ? void 0 : options.transform) {
transformQuery = this._transformOptsToQueryString(options.transform);
if (transformQuery) {
queryParams.push(transformQuery);
}
}
if (queryParams.length > 0) {
separator = signedUrl.includes('?') ? '&' : '?';
signedUrl = "".concat(signedUrl).concat(separator).concat(queryParams.join('&'));
}
return [2, {
data: { signedUrl: signedUrl },
error: null,
}];
case 2:
error_5 = _a.sent();
if (this.shouldThrowOnError)
throw error_5;
if ((0, errors_1.isStorageError)(error_5)) {
return [2, {
data: null,
error: error_5,
}];
}
throw error_5;
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.createSignedUrls = function (paths, expiresIn) {
return __awaiter(this, void 0, void 0, function () {
var fileList, result, error_6;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
fileList = paths.map(function (p) { return ({
fileID: _this._normalizeCloudId(p),
maxAge: expiresIn,
}); });
return [4, this.getTempFileURL({ fileList: fileList })];
case 1:
result = _a.sent();
return [2, {
data: result.fileList.map(function (item, index) { return ({
path: paths[index],
signedUrl: item.tempFileURL || '',
error: item.code === 'SUCCESS' ? null : item.message,
}); }),
error: null,
}];
case 2:
error_6 = _a.sent();
if (this.shouldThrowOnError)
throw error_6;
if ((0, errors_1.isStorageError)(error_6)) {
return [2, {
data: null,
error: error_6,
}];
}
throw error_6;
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.download = function (path, options) {
return __awaiter(this, void 0, void 0, function () {
var error_7;
var _a;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
_a = {};
return [4, (function () { return __awaiter(_this, void 0, void 0, function () {
var signedUrlResult, tmpUrl, data;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4, this.createSignedUrl(path, 600, { transform: options })];
case 1:
signedUrlResult = _b.sent();
if (signedUrlResult.error) {
throw signedUrlResult.error;
}
tmpUrl = encodeURI((_a = signedUrlResult.data) === null || _a === void 0 ? void 0 : _a.signedUrl);
return [4, this.request.reqClass.get({
url: tmpUrl,
headers: {},
responseType: 'blob',
})];
case 2:
data = (_b.sent()).data;
if (!data) {
throw new errors_1.StorageError('Download failed: no file content');
}
return [2, new Blob([data])];
}
});
}); })()];
case 1: return [2, (_a.data = _b.sent(),
_a.error = null,
_a)];
case 2:
error_7 = _b.sent();
if (this.shouldThrowOnError)
throw error_7;
if ((0, errors_1.isStorageError)(error_7)) {
return [2, {
data: null,
error: error_7,
}];
}
throw error_7;
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.info = function (pathOrFileId) {
return __awaiter(this, void 0, void 0, function () {
var isFileId, displayName, bucketId, fileInfo, item, now, lastModified, error_8;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
isFileId = pathOrFileId.startsWith('cloud://');
displayName = isFileId ? this._extractPathFromFileId(pathOrFileId) : pathOrFileId;
bucketId = isFileId ? this._extractBucketFromFileId(pathOrFileId) : this.bucketId;
return [4, this.getFileInfo({
fileList: [this._normalizeCloudId(pathOrFileId)],
})];
case 1:
fileInfo = _a.sent();
item = fileInfo.fileList[0];
if (item.code !== 'SUCCESS') {
throw new errors_1.StorageError(item.message);
}
now = new Date().toISOString();
lastModified = (item.lastModified ? new Date(item.lastModified) : new Date()).toISOString();
return [2, {
data: {
id: item.fileID,
version: '1',
name: displayName,
bucketId: bucketId,
updatedAt: lastModified,
createdAt: lastModified,
lastAccessedAt: now,
size: item.size,
cacheControl: item.cacheControl,
contentType: item.contentType,
etag: item.etag,
lastModified: lastModified,
metadata: {},
},
error: null,
}];
case 2:
error_8 = _a.sent();
if (this.shouldThrowOnError)
throw error_8;
return [2, {
data: null,
error: error_8 instanceof errors_1.StorageError ? error_8 : new errors_1.StorageError(error_8.message),
}];
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.exists = function (pathOrFileId) {
return __awaiter(this, void 0, void 0, function () {
var fileInfo, item, error_9;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.getFileInfo({
fileList: [this._normalizeCloudId(pathOrFileId)],
})];
case 1:
fileInfo = _a.sent();
item = fileInfo.fileList[0];
if (item.code === 'FILE_NOT_FOUND') {
return [2, {
data: false,
error: null,
}];
}
if (item.code !== 'SUCCESS') {
throw new errors_1.StorageError(item.message);
}
return [2, { data: true, error: null }];
case 2:
error_9 = _a.sent();
if (this.shouldThrowOnError)
throw error_9;
throw error_9;
case 3: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.getPublicUrl = function (path, options) {
return __awaiter(this, void 0, void 0, function () {
var res;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.createSignedUrl(path, 600, options)];
case 1:
res = _a.sent();
if (res.data) {
return [2, {
data: { publicUrl: res.data.signedUrl },
}];
}
return [2, { data: null, error: res.error }];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.remove = function (paths) {
return __awaiter(this, void 0, void 0, function () {
var chunkSize_1, pathChunks, i, fileInfoResults, fileInfoMap_1, fileList, result, failedFiles, now_1, error_10;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
chunkSize_1 = 10;
pathChunks = [];
for (i = 0; i < paths.length; i += chunkSize_1) {
pathChunks.push(paths.slice(i, i + chunkSize_1));
}
return [4, Promise.all(pathChunks.map(function (chunk) { return Promise.all(chunk.map(function (path) { return _this.info(path); })); }))];
case 1:
fileInfoResults = _a.sent();
fileInfoMap_1 = new Map();
fileInfoResults.flat().forEach(function (result, index) {
if (result.data) {
fileInfoMap_1.set(paths[Math.floor(index / chunkSize_1) * chunkSize_1 + (index % chunkSize_1)], result.data);
}
});
fileList = paths.map(function (p) { return _this._normalizeCloudId(p); });
return [4, this.deleteFile({ fileList: fileList })];
case 2:
result = _a.sent();
failedFiles = result.fileList.filter(function (item) { return item.code !== 'SUCCESS'; });
if (failedFiles.length > 0) {
throw new errors_1.StorageError("Delete failed for ".concat(failedFiles.length, " file(s)"));
}
now_1 = new Date().toISOString();
return [2, {
data: paths.map(function (p) {
var info = fileInfoMap_1.get(p);
return {
name: info === null || info === void 0 ? void 0 : info.name,
id: info === null || info === void 0 ? void 0 : info.id,
bucket_id: info === null || info === void 0 ? void 0 : info.bucketId,
owner: undefined,
updated_at: (info === null || info === void 0 ? void 0 : info.updatedAt) || now_1,
created_at: info === null || info === void 0 ? void 0 : info.createdAt,
last_accessed_at: (info === null || info === void 0 ? void 0 : info.lastAccessedAt) || now_1,
metadata: (info === null || info === void 0 ? void 0 : info.metadata) || {},
buckets: {
id: info === null || info === void 0 ? void 0 : info.bucketId,
name: info === null || info === void 0 ? void 0 : info.bucketId,
owner: undefined,
public: false,
created_at: '',
updated_at: now_1,
},
};
}),
error: null,
}];
case 3:
error_10 = _a.sent();
if (this.shouldThrowOnError)
throw error_10;
if ((0, errors_1.isStorageError)(error_10)) {
return [2, {
data: null,
error: error_10,
}];
}
throw error_10;
case 4: return [2];
}
});
});
};
SupabaseFileAPILikeStorage.prototype.list = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
throw new errors_1.StorageError('Not implemented');
});
});
};
SupabaseFileAPILikeStorage.prototype._getCloudPath = function (path) {
var cleanPath = path.replace(/^\/|\/$/g, '').replace(/\/+/g, '/');
return cleanPath;
};
SupabaseFileAPILikeStorage.prototype._normalizeCloudId = function (path) {
var _a;
if (/^cloud:\/\//.test(path)) {
return path;
}
var cleanPath = this._getCloudPath(path);
if (this.bucketId) {
var envId = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.env) || '';
if (envId) {
return "cloud://".concat(envId, ".").concat(this.bucketId, "/").concat(cleanPath);
}
}
else {
throw new errors_1.StorageError('bucketId is not set');
}
};
SupabaseFileAPILikeStorage.prototype.toBase64 = function (data) {
if (typeof Buffer !== 'undefined') {
return Buffer.from(data).toString('base64');
}
return btoa(data);
};
SupabaseFileAPILikeStorage.prototype._transformOptsToQueryString = function (transform) {
var params = ['imageMogr2'];
if (transform.width || transform.height) {
var width = transform.width || '';
var height = transform.height || '';
if (transform.resize === 'fill') {
params.push("thumbnail/".concat(width, "x").concat(height, "!"));
}
else if (transform.resize === 'contain') {
params.push("thumbnail/".concat(width, "x").concat(height));
}
else {
params.push("thumbnail/".concat(width, "x").concat(height, "^"));
}
}
if (transform.format && transform.format !== 'origin') {
params.push("format/".concat(transform.format));
}
if (transform.quality !== undefined) {
var quality = Math.max(1, Math.min(100, transform.quality));
params.push("quality/".concat(quality));
}
return params.join('/');
};
SupabaseFileAPILikeStorage.prototype._extractPathFromFileId = function (fileId) {
var withoutProtocol = fileId.replace(/^cloud:\/\//, '');
var parts = withoutProtocol.split('/');
if (parts.length < 2) {
return fileId;
}
return parts.slice(1).join('/');
};
SupabaseFileAPILikeStorage.prototype._extractBucketFromFileId = function (fileId) {
var withoutProtocol = fileId.replace(/^cloud:\/\//, '');
var parts = withoutProtocol.split('/');
if (parts.length < 1) {
return '';
}
var envAndBucket = parts[0];
var dotIndex = envAndBucket.indexOf('.');
if (dotIndex === -1) {
return envAndBucket;
}
return envAndBucket.substring(dotIndex + 1);
};
return SupabaseFileAPILikeStorage;
}(storage_1.CloudbaseStorage));
exports.SupabaseFileAPILikeStorage = SupabaseFileAPILikeStorage;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3VwYWJhc2UvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxrREFBZ0Q7QUFFaEQsc0NBQWdGO0FBR2hGLG1DQUF1RDtBQUUvQyxJQUFBLE1BQU0sR0FBSyxxQkFBUyxPQUFkLENBQWM7QUFFNUI7SUFBZ0QsOENBQWdCO0lBSzlELG9DQUFZLE9BQTJCO1FBQXZDLFlBQ0UsaUJBQU8sU0FFUjtRQVBPLHdCQUFrQixHQUFHLEtBQUssQ0FBQTtRQUMxQixjQUFRLEdBQUcsRUFBRSxDQUFBO1FBS25CLEtBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBOztJQUN4QixDQUFDO0lBRUQsc0JBQUksOENBQU07YUFBVjs7WUFFRSxPQUFPLE1BQUEsSUFBSSxDQUFDLE9BQU8sMENBQUUsTUFBTSxDQUFBO1FBQzdCLENBQUM7OztPQUFBO0lBRUQsc0JBQUksK0NBQU87YUFBWDs7WUFFRSxPQUFPLE1BQUEsSUFBSSxDQUFDLE9BQU8sMENBQUUsT0FBTyxDQUFBO1FBQzlCLENBQUM7OztPQUFBO0lBRUQsaURBQVksR0FBWjtRQUNFLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUE7UUFDOUIsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQseUNBQUksR0FBSixVQUFLLE1BQWU7UUFDbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLElBQUksRUFBRSxDQUFBO1FBQzVCLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztJQUVLLDJDQUFNLEdBQVosVUFDRSxJQUFZLEVBQ1osUUFBa0IsRUFDbEIsV0FBeUI7Ozs7Ozt3QkFJbkIsT0FBTyxjQUFLLE1BQU0sRUFBRSxJQUFJLElBQUssV0FBVyxDQUFFLENBQUE7d0JBQ3hDLFlBQVksR0FBNEIsT0FBTyxhQUFuQyxFQUFFLFdBQVcsR0FBZSxPQUFPLFlBQXRCLEVBQUUsUUFBUSxHQUFLLE9BQU8sU0FBWixDQUFZOzs7O3dCQUUvQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQTt3QkFDcEMsZ0JBQWdCLEdBQWtEOzRCQUN0RSxTQUFTLFdBQUE7NEJBQ1QsUUFBUSxFQUFFLFFBQWU7eUJBQzFCLENBQUE7d0JBRUQsSUFBSSxZQUFZLElBQUksV0FBVyxJQUFJLFFBQVEsRUFBRTs0QkFDckMsT0FBTyxHQUFHLEVBQUUsQ0FBQTs0QkFDbEIsSUFBSSxZQUFZLEVBQUU7Z0NBQ2hCLE9BQU8sQ0FBQyxlQUFlLENBQUMsR0FBRyxZQUFZLENBQUE7NkJBQ3hDOzRCQUNELElBQUksV0FBVyxFQUFFO2dDQUNmLE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxXQUFXLENBQUE7NkJBQ3RDOzRCQUVELElBQUksUUFBUSxFQUFFO2dDQUNaLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBOzZCQUM3RTs0QkFFRCxnQkFBZ0IsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO3lCQUNuQzt3QkFFYyxXQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsRUFBQTs7d0JBQWhELE1BQU0sR0FBRyxTQUF1Qzt3QkFHdEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7NEJBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztnQ0FDN0IsSUFBSSxFQUFFLE1BQU0sQ0FBQyxjQUFjO2dDQUMzQixHQUFHLEVBQUUsV0FBSSx3QkFBYyxnQ0FBNkI7NkJBQ3JELENBQUMsQ0FBRSxDQUFBO3lCQUNMO3dCQUVELFdBQU87Z0NBQ0wsSUFBSSxFQUFFO29DQUNKLEVBQUUsRUFBRSxNQUFNLENBQUMsTUFBTTtvQ0FDakIsSUFBSSxNQUFBO29DQUNKLFFBQVEsRUFBRSxJQUFJO2lDQUNmO2dDQUNELEtBQUssRUFBRSxJQUFJOzZCQUNaLEVBQUE7Ozt3QkFFRCxJQUFJLElBQUksQ0FBQyxrQkFBa0I7NEJBQUUsTUFBTSxPQUFLLENBQUE7d0JBQ3hDLElBQUksSUFBQSx1QkFBYyxFQUFDLE9BQUssQ0FBQyxFQUFFOzRCQUN6QixXQUFPO29DQUNMLElBQUksRUFBRSxJQUFJO29DQUNWLEtBQUssU0FBQTtpQ0FDTixFQUFBO3lCQUNGO3dCQUNELE1BQU0sT0FBSyxDQUFBOzs7OztLQUVkO0lBRUssc0RBQWlCLEdBQXZCLFVBQ0UsSUFBWSxFQUNaLE1BQWMsRUFDZCxRQUFrQixFQUNsQixXQUF5Qjs7O2dCQUl6QixXQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxXQUFXLENBQUMsRUFBQTs7O0tBQ2hEO0lBRUssMERBQXFCLEdBQTNCLFVBQTRCLElBQVk7Ozs7Ozs7d0JBaUI5QixTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQTt3QkFFZixXQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFNBQVMsV0FBQSxFQUFFLENBQUMsRUFBQTs7d0JBQXhELFFBQVEsR0FBSyxDQUFBLFNBQTJDLENBQUEsS0FBaEQ7d0JBRXRCLFdBQU87Z0NBQ0wsSUFBSSxFQUFFO29DQUNKLFNBQVMsRUFBRSxRQUFRLENBQUMsR0FBRztvQ0FDdkIsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO29DQUNyQixJQUFJLE1BQUE7b0NBRUosYUFBYSxFQUFFLFFBQVEsQ0FBQyxhQUFhO29DQUNyQyxFQUFFLEVBQUUsUUFBUSxDQUFDLE1BQU07b0NBQ25CLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztvQ0FDN0IsV0FBVyxFQUFFLFFBQVEsQ0FBQyxZQUFZO2lDQUNuQztnQ0FDRCxLQUFLLEVBQUUsSUFBSTs2QkFDWixFQUFBOzs7d0JBRUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCOzRCQUFFLE1BQU0sT0FBSyxDQUFBO3dCQUN4QyxXQUFPO2dDQUNMLElBQUksRUFBRSxJQUFJO2dDQUNWLEtBQUssRUFBRSxPQUFLLFlBQVkscUJBQVksQ0FBQyxDQUFDLENBQUMsT0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLHFCQUFZLENBQUMsT0FBSyxDQUFDLE9BQU8sQ0FBQzs2QkFDL0UsRUFBQTs7Ozs7S0FFSjtJQUVLLDJDQUFNLEdBQVosVUFDRSxJQUFZLEVBQ1osUUFBa0IsRUFDbEIsV0FBeUI7OztnQkFJekIsV0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLHdCQUFPLFdBQVcsS0FBRSxNQUFNLEVBQUUsSUFBSSxJQUFHLEVBQUE7OztLQUNyRTtJQUVLLHlDQUFJLEdBQVYsVUFDRSxRQUFnQixFQUNoQixNQUFjOzs7Ozs7O3dCQUlHLFdBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQztnQ0FDakMsUUFBUSxFQUFFO29DQUNSO3dDQUNFLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQzt3Q0FDckMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO3dDQUNuQyxTQUFTLEVBQUUsSUFBSTt3Q0FDZixjQUFjLEVBQUUsSUFBSTtxQ0FDckI7aUNBQ0Y7NkJBQ0YsQ0FBQyxFQUFBOzt3QkFUSSxNQUFNLEdBQUcsU0FTYjt3QkFFRixJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTs0QkFDcEUsTUFBTSxJQUFJLHFCQUFZLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksYUFBYSxDQUFDLENBQUE7eUJBQ3BFO3dCQUVELFdBQU87Z0NBQ0wsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLDBCQUFtQixRQUFRLGlCQUFPLE1BQU0sQ0FBRSxFQUFFO2dDQUM3RCxLQUFLLEVBQUUsSUFBSTs2QkFDWixFQUFBOzs7d0JBRUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCOzRCQUFFLE1BQU0sT0FBSyxDQUFBO3dCQUN4QyxJQUFJLElBQUEsdUJBQWMsRUFBQyxPQUFLLENBQUMsRUFBRTs0QkFDekIsV0FBTztvQ0FDTCxJQUFJLEVBQUUsSUFBSTtvQ0FDVixLQUFLLFNBQUE7aUNBQ04sRUFBQTt5QkFDRjt3QkFDRCxNQUFNLE9BQUssQ0FBQTs7Ozs7S0FFZDtJQUVLLHlDQUFJLEdBQVYsVUFDRSxRQUFnQixFQUNoQixNQUFjOzs7Ozs7O3dCQUlHLFdBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQztnQ0FDakMsUUFBUSxFQUFFO29DQUNSO3dDQUNFLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQzt3Q0FDckMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO3dDQUNuQyxTQUFTLEVBQUUsSUFBSTt3Q0FDZixjQUFjLEVBQUUsS0FBSztxQ0FDdEI7aUNBQ0Y7NkJBQ0YsQ0FBQyxFQUFBOzt3QkFUSSxNQUFNLEdBQUcsU0FTYjt3QkFFRixJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTs0QkFDcEUsTUFBTSxJQUFJLHFCQUFZLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksYUFBYSxDQUFDLENBQUE7eUJBQ3BFO3dCQUVELFdBQU87Z0NBQ0wsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0NBQzFDLEtBQUssRUFBRSxJQUFJOzZCQUNaLEVBQUE7Ozt3QkFFRCxJQUFJLElBQUksQ0FBQyxrQkFBa0I7NEJBQUUsTUFBTSxPQUFLLENBQUE7d0JBQ3hDLElBQUksSUFBQSx1QkFBYyxFQUFDLE9BQUssQ0FBQyxFQUFFOzRCQUN6QixXQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLFNBQUEsRUFBRSxFQUFBO3lCQUM3Qjt3QkFDRCxNQUFNLE9BQUssQ0FBQTs7Ozs7S0FFZDtJQUVLLG9EQUFlLEdBQXJCLFVBQ0UsSUFBWSxFQUNaLFNBQWlCLEVBQ2pCLE9BR0M7Ozs7Ozs7d0JBR08sU0FBUyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQTt3QkFDL0IsV0FBTSxJQUFJLENBQUMsY0FBYyxDQUFDO2dDQUN2QyxRQUFRLEVBQUU7b0NBQ1I7d0NBQ0UsTUFBTSxFQUFFLFNBQVM7d0NBQ2pCLE1BQU0sRUFBRSxTQUFTO3FDQUNsQjtpQ0FDRjs2QkFDRixDQUFDLEVBQUE7O3dCQVBJLE1BQU0sR0FBRyxTQU9iO3dCQUdGLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFOzRCQUN6QyxNQUFNLElBQUkscUJBQVksQ0FBQyx3Q0FBaUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLGVBQUssTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUUsQ0FBQyxDQUFBO3lCQUNqSDt3QkFFRyxTQUFTLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUE7d0JBR3pDLFdBQVcsR0FBYSxFQUFFLENBQUE7d0JBR2hDLElBQUksQ0FBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsUUFBUSxNQUFLLFNBQVMsRUFBRTs0QkFDbkMsSUFBSSxPQUFPLE9BQU8sQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFO2dDQUV4QyxXQUFXLENBQUMsSUFBSSxDQUFDLG1CQUFZLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBRSxDQUFDLENBQUE7NkJBQ3JFO2lDQUFNLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxJQUFJLEVBQUU7Z0NBRXBDLFdBQVcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUE7NkJBQ2xDO3lCQUNGO3dCQUdELElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFNBQVMsRUFBRTs0QkFDaEIsY0FBYyxHQUFHLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7NEJBQzFFLElBQUksY0FBYyxFQUFFO2dDQUNsQixXQUFXLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBOzZCQUNqQzt5QkFDRjt3QkFHRCxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFOzRCQUNwQixTQUFTLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUE7NEJBQ3JELFNBQVMsR0FBRyxVQUFHLFNBQVMsU0FBRyxTQUFTLFNBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBRSxDQUFBO3lCQUMvRDt3QkFFRCxXQUFPO2dDQUNMLElBQUksRUFBRSxFQUFFLFNBQVMsV0FBQSxFQUFFO2dDQUNuQixLQUFLLEVBQUUsSUFBSTs2QkFDWixFQUFBOzs7d0JBRUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCOzRCQUFFLE1BQU0sT0FBSyxDQUFBO3dCQUN4QyxJQUFJLElBQUEsdUJBQWMsRUFBQyxPQUFLLENBQUMsRUFBRTs0QkFDekIsV0FBTztvQ0FDTCxJQUFJLEVBQUUsSUFBSTtvQ0FDVixLQUFLLFNBQUE7aUNBQ04sRUFBQTt5QkFDRjt3QkFDRCxNQUFNLE9BQUssQ0FBQTs7Ozs7S0FFZDtJQUVLLHFEQUFnQixHQUF0QixVQUNFLEtBQWUsRUFDZixTQUFpQjs7Ozs7Ozs7d0JBU1QsUUFBUSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBQSxDQUFDLElBQUksT0FBQSxDQUFDOzRCQUMvQixNQUFNLEVBQUUsS0FBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQzs0QkFDakMsTUFBTSxFQUFFLFNBQVM7eUJBQ2xCLENBQUMsRUFIOEIsQ0FHOUIsQ0FBQyxDQUFBO3dCQUVZLFdBQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLFFBQVEsVUFBQSxFQUFFLENBQUMsRUFBQTs7d0JBQWhELE1BQU0sR0FBRyxTQUF1Qzt3QkFFdEQsV0FBTztnQ0FDTCxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBQyxJQUFTLEVBQUUsS0FBYSxJQUFLLE9BQUEsQ0FBQztvQ0FDdkQsSUFBSSxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUM7b0NBQ2xCLFNBQVMsRUFBRSxJQUFJLENBQUMsV0FBVyxJQUFJLEVBQUU7b0NBQ2pDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTztpQ0FDckQsQ0FBQyxFQUpzRCxDQUl0RCxDQUFDO2dDQUNILEtBQUssRUFBRSxJQUFJOzZCQUNaLEVBQUE7Ozt3QkFFRCxJQUFJLElBQUksQ0FBQyxrQkFBa0I7NEJBQUUsTUFBTSxPQUFLLENBQUE7d0JBQ3hDLElBQUksSUFBQSx1QkFBYyxFQUFDLE9BQUssQ0FBQyxFQUFFOzRCQUN6QixXQUFPO29DQUNMLElBQUksRUFBRSxJQUFJO29DQUNWLEtBQUssU0FBQTtpQ0FDTixFQUFBO3lCQUNGO3dCQUNELE1BQU0sT0FBSyxDQUFBOzs7OztLQUVkO0lBRUssNkNBQVEsR0FBZCxVQUNFLElBQVksRUFDWixPQUEwQjs7Ozs7Ozs7Ozt3QkFPaEIsV0FBTSxDQUFDOzs7OztnREFDYSxXQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFBOzs0Q0FBL0UsZUFBZSxHQUFHLFNBQTZEOzRDQUNyRixJQUFJLGVBQWUsQ0FBQyxLQUFLLEVBQUU7Z0RBQ3pCLE1BQU0sZUFBZSxDQUFDLEtBQUssQ0FBQTs2Q0FDNUI7NENBQ0ssTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFBLGVBQWUsQ0FBQyxJQUFJLDBDQUFFLFNBQVMsQ0FBQyxDQUFBOzRDQUV4QyxXQUFPLElBQVksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztvREFDeEQsR0FBRyxFQUFFLE1BQU07b0RBQ1gsT0FBTyxFQUFFLEVBQUU7b0RBQ1gsWUFBWSxFQUFFLE1BQU07aURBQ3JCLENBQUMsRUFBQTs7NENBSk0sSUFBSSxHQUFLLENBQUEsU0FJZixDQUFBLEtBSlU7NENBTVosSUFBSSxDQUFDLElBQUksRUFBRTtnREFDVCxNQUFNLElBQUkscUJBQVksQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFBOzZDQUMzRDs0Q0FHRCxXQUFPLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBQTs7O2lDQUN4QixDQUFDLEVBQUUsRUFBQTs0QkFwQk4sWUFDRSxPQUFJLEdBQUUsU0FtQkY7NEJBQ0osUUFBSyxHQUFFLElBQUk7aUNBQ1o7Ozt3QkFFRCxJQUFJLElBQUksQ0FBQyxrQkFBa0I7NEJBQUUsTUFBTSxPQUFLLENBQUE7d0JBQ3hDLElBQUksSUFBQSx1QkFBYyxFQUFDLE9BQUssQ0FBQyxFQUFFOzRCQUN6QixXQUFPO29DQUNMLElBQUksRUFBRSxJQUFJO29DQUNWLEtBQUssU0FBQTtpQ0FDTixFQUFBO3lCQUNGO3dCQUNELE1BQU0sT0FBSyxDQUFBOzs7OztLQUVkO0lBaUJLLHlDQUFJLEdBQVYsVUFBVyxZQUFvQjs7Ozs7Ozt3QkFHckIsUUFBUSxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUE7d0JBQzlDLFdBQVcsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFBO3dCQUNqRixRQUFRLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUE7d0JBRXRFLFdBQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQztnQ0FDdEMsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDOzZCQUNqRCxDQUFDLEVBQUE7O3dCQUZJLFFBQVEsR0FBRyxTQUVmO3dCQUVJLElBQUksR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO3dCQUVqQyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFOzRCQUMzQixNQUFNLElBQUkscUJBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7eUJBQ3JDO3dCQUVLLEdBQUcsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFBO3dCQUM5QixZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQTt3QkFDakcsV0FBTztnQ0FDTCxJQUFJLEVBQUU7b0NBQ0osRUFBRSxFQUFFLElBQUksQ0FBQyxNQUFNO29DQUNmLE9BQU8sRUFBRSxHQUFHO29DQUNaLElBQUksRUFBRSxXQUFXO29DQUNqQixRQUFRLFVBQUE7b0NBQ1IsU0FBUyxFQUFFLFlBQVk7b0NBQ3ZCLFNBQVMsRUFBRSxZQUFZO29DQUN2QixjQUFjLEVBQUUsR0FBRztvQ0FDbkIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO29DQUNmLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtvQ0FDL0IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO29DQUM3QixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7b0NBQ2YsWUFBWSxjQUFBO29DQUNaLFFBQVEsRUFBRSxFQUFFO2lDQUNiO2dDQUNELEtBQUssRUFBRSxJQUFJOzZCQUNaLEVBQUE7Ozt3QkFFRCxJQUFJLElBQUksQ0FBQyxrQkFBa0I7NEJBQUUsTUFBTSxPQUFLLENBQUE7d0JBQ3hDLFdBQU87Z0NBQ0wsSUFBSSxFQUFFLElBQUk7Z0NBQ1YsS0FBSyxFQUFFLE9BQUssWUFBWSxxQkFBWSxDQUFDLENBQUMsQ0FBQyxPQUFLLENBQUMsQ0FBQyxDQUFDLElBQUkscUJBQVksQ0FBQyxPQUFLLENBQUMsT0FBTyxDQUFDOzZCQUMvRSxFQUFBOzs7OztLQUVKO0lBRUssMkNBQU0sR0FBWixVQUFhLFlBQW9COzs7Ozs7O3dCQUdaLFdBQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQztnQ0FDdEMsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDOzZCQUNqRCxDQUFDLEVBQUE7O3dCQUZJLFFBQVEsR0FBRyxTQUVmO3dCQUVJLElBQUksR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO3dCQUVqQyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssZ0JBQWdCLEVBQUU7NEJBQ2xDLFdBQU87b0NBQ0wsSUFBSSxFQUFFLEtBQUs7b0NBQ1gsS0FBSyxFQUFFLElBQUk7aUNBQ1osRUFBQTt5QkFDRjt3QkFFRCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFOzRCQUMzQixNQUFNLElBQUkscUJBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7eUJBQ3JDO3dCQUVELFdBQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBQTs7O3dCQUVsQyxJQUFJLElBQUksQ0FBQyxrQkFBa0I7NEJBQUUsTUFBTSxPQUFLLENBQUE7d0JBQ3hDLE1BQU0sT0FBSyxDQUFBOzs7OztLQUVkO0lBRUssaURBQVksR0FBbEIsVUFDRSxJQUFZLEVBQ1osT0FHQzs7Ozs7NEJBT1csV0FBTSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxDQUFDLEVBQUE7O3dCQUFwRCxHQUFHLEdBQUcsU0FBOEM7d0JBRTFELElBQUksR0FBRyxDQUFDLElBQUksRUFBRTs0QkFDWixXQUFPO29DQUNMLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtpQ0FDeEMsRUFBQTt5QkFDRjt3QkFFRCxXQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQXFCLEVBQUUsRUFBQTs7OztLQUN4RDtJQUVLLDJDQUFNLEdBQVosVUFBYSxLQUFlOzs7Ozs7Ozt3QkFHbEIsY0FBWSxFQUFFLENBQUE7d0JBQ2QsVUFBVSxHQUFlLEVBQUUsQ0FBQTt3QkFDakMsS0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxXQUFTLEVBQUU7NEJBQ2hELFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVMsQ0FBQyxDQUFDLENBQUE7eUJBQy9DO3dCQUd1QixXQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxVQUFBLEtBQUssSUFBSSxPQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxVQUFBLElBQUksSUFBSSxPQUFBLEtBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQWYsQ0FBZSxDQUFDLENBQUMsRUFBL0MsQ0FBK0MsQ0FBQyxDQUFFLEVBQUE7O3dCQUE5RyxlQUFlLEdBQUcsU0FBNEY7d0JBRzlHLGdCQUFjLElBQUksR0FBRyxFQUFrQyxDQUFBO3dCQUM3RCxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsTUFBTSxFQUFFLEtBQUs7NEJBQzNDLElBQUksTUFBTSxDQUFDLElBQUksRUFBRTtnQ0FDZixhQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxXQUFTLENBQUMsR0FBRyxXQUFTLEdBQUcsQ0FBQyxLQUFLLEdBQUcsV0FBUyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7NkJBQ3JHO3dCQUNILENBQUMsQ0FBQyxDQUFBO3dCQUdJLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsS0FBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxFQUF6QixDQUF5QixDQUFDLENBQUE7d0JBQzNDLFdBQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFFBQVEsVUFBQSxFQUFFLENBQUMsRUFBQTs7d0JBQTVDLE1BQU0sR0FBRyxTQUFtQzt3QkFHNUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQUEsSUFBSSxJQUFJLE9BQUEsSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQXZCLENBQXVCLENBQUMsQ0FBQTt3QkFDM0UsSUFBSSxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTs0QkFDMUIsTUFBTSxJQUFJLHFCQUFZLENBQUMsNEJBQXFCLFdBQVcsQ0FBQyxNQUFNLGFBQVUsQ0FBQyxDQUFBO3lCQUMxRTt3QkFFSyxRQUFNLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUE7d0JBR3BDLFdBQU87Z0NBQ0wsSUFBSSxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBQyxDQUFDO29DQUNoQixJQUFNLElBQUksR0FBRyxhQUFXLENBQUMsR0FBRyxDQU