cnpmcore
Version:
256 lines • 21.9 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PackageSyncController = void 0;
const tegg_1 = require("@eggjs/tegg");
const egg_errors_1 = require("egg-errors");
const AbstractController_1 = require("./AbstractController");
const PackageUtil_1 = require("../../common/PackageUtil");
const PackageSyncerService_1 = require("../../core/service/PackageSyncerService");
const RegistryManagerService_1 = require("../../core/service/RegistryManagerService");
const Task_1 = require("../../common/enum/Task");
const typebox_1 = require("../typebox");
const constants_1 = require("../../common/constants");
let PackageSyncController = class PackageSyncController extends AbstractController_1.AbstractController {
async _executeTaskAsync(task) {
const startTime = Date.now();
this.logger.info('[PackageSyncController:executeTask:start] taskId: %s, targetName: %s, attempts: %s, params: %j, updatedAt: %s, delay %sms', task.taskId, task.targetName, task.attempts, task.data, task.updatedAt, startTime - task.updatedAt.getTime());
let result = 'success';
try {
await this.packageSyncerService.executeTask(task);
}
catch (err) {
result = 'error';
this.logger.error(err);
}
finally {
const use = Date.now() - startTime;
this.logger.info('[PackageSyncController:executeTask:%s] taskId: %s, targetName: %s, use %sms', result, task.taskId, task.targetName, use);
}
}
async createSyncTask(ctx, fullname, data) {
if (!this.enableSync) {
throw new egg_errors_1.ForbiddenError('Not allow to sync package');
}
const tips = data.tips || `Sync cause by "${ctx.href}", parent traceId: ${ctx.tracer.traceId}`;
const isAdmin = await this.userRoleManager.isAdmin(ctx);
if (this.config.cnpmcore.syncMode === constants_1.SyncMode.admin && !isAdmin) {
throw new egg_errors_1.ForbiddenError('Only admin allow to sync package');
}
const params = {
fullname,
tips,
skipDependencies: !!data.skipDependencies,
syncDownloadData: !!data.syncDownloadData,
force: !!data.force,
// only admin allow to sync history version
forceSyncHistory: !!data.forceSyncHistory && isAdmin,
specificVersions: data.specificVersions,
};
ctx.tValidate(typebox_1.SyncPackageTaskRule, params);
const [scope, name] = (0, PackageUtil_1.getScopeAndName)(params.fullname);
const packageEntity = await this.packageRepository.findPackage(scope, name);
const registry = await this.registryManagerService.findByRegistryName(data?.registryName);
if (!registry && data.registryName) {
throw new egg_errors_1.ForbiddenError(`Can\'t find target registry "${data.registryName}"`);
}
if (packageEntity?.isPrivate && !registry) {
throw new egg_errors_1.ForbiddenError(`Can\'t sync private package "${params.fullname}"`);
}
if (params.syncDownloadData && !this.packageSyncerService.allowSyncDownloadData) {
throw new egg_errors_1.ForbiddenError('Not allow to sync package download data');
}
if (registry && packageEntity?.registryId && packageEntity.registryId !== registry.registryId) {
throw new egg_errors_1.ForbiddenError(`The package is synced from ${packageEntity.registryId}`);
}
const authorized = await this.userRoleManager.getAuthorizedUserAndToken(ctx);
const task = await this.packageSyncerService.createTask(params.fullname, {
authorIp: ctx.ip,
authorId: authorized?.user.userId,
tips: params.tips,
skipDependencies: params.skipDependencies,
syncDownloadData: params.syncDownloadData,
forceSyncHistory: params.forceSyncHistory,
registryId: registry?.registryId,
specificVersions: params.specificVersions && JSON.parse(params.specificVersions),
});
ctx.logger.info('[PackageSyncController.createSyncTask:success] taskId: %s, fullname: %s', task.taskId, fullname);
if (data.force) {
if (isAdmin) {
// set background task timeout to 5min
this.backgroundTaskHelper.timeout = 1000 * 60 * 5;
this.backgroundTaskHelper.run(async () => {
ctx.logger.info('[PackageSyncController.createSyncTask:execute-immediately] taskId: %s', task.taskId);
// execute task in background
await this._executeTaskAsync(task);
});
}
}
ctx.status = 201;
return {
ok: true,
id: task.taskId,
type: task.type,
state: task.state,
};
}
// TODO: no-cache for CDN if task state is processing or timeout
async showSyncTask(fullname, taskId) {
const task = await this.packageSyncerService.findTask(taskId);
if (!task)
throw new egg_errors_1.NotFoundError(`Package "${fullname}" sync task "${taskId}" not found`);
let logUrl;
if (task.state !== Task_1.TaskState.Waiting) {
logUrl = `${this.config.cnpmcore.registry}/-/package/${fullname}/syncs/${taskId}/log`;
}
const error = task.error || undefined;
return {
ok: true,
id: task.taskId,
type: task.type,
state: task.state,
logUrl,
error,
};
}
// TODO: no-cache for CDN if task state is processing or timeout
async showSyncTaskLog(ctx, fullname, taskId) {
const task = await this.packageSyncerService.findTask(taskId);
if (!task)
throw new egg_errors_1.NotFoundError(`Package "${fullname}" sync task "${taskId}" not found`);
if (task.state === Task_1.TaskState.Waiting)
throw new egg_errors_1.NotFoundError(`Package "${fullname}" sync task "${taskId}" log not found`);
const logUrlOrStream = await this.packageSyncerService.findTaskLog(task);
if (!logUrlOrStream)
throw new egg_errors_1.NotFoundError(`Package "${fullname}" sync task "${taskId}" log not found`);
if (typeof logUrlOrStream === 'string') {
ctx.redirect(logUrlOrStream);
return;
}
ctx.type = 'log';
return logUrlOrStream;
}
// deprecate create sync task api for cnpmjs.org
// https://github.com/cnpm/cnpmjs.org/blob/master/controllers/sync.js
async deprecatedCreateSyncTask(ctx, fullname, nodeps) {
const options = {
fullname,
tips: `Sync cause by "${ctx.href}", parent traceId: ${ctx.tracer.traceId}`,
skipDependencies: nodeps === 'true',
syncDownloadData: false,
force: false,
forceSyncHistory: false,
};
const task = await this.createSyncTask(ctx, fullname, options);
return {
ok: true,
logId: task.id,
};
}
// https://github.com/cnpm/cnpmjs.org/blob/master/controllers/sync.js#L55
async deprecatedShowSyncTask(fullname, taskId) {
const task = await this.showSyncTask(fullname, taskId);
const syncDone = task.state !== Task_1.TaskState.Waiting && task.state !== Task_1.TaskState.Processing;
const stateMessage = syncDone ? '[done]' : '[processing]';
// https://github.com/cnpm/cnpm/blob/cadd3cd54c22b1a157810a43ab10febdb2410ca6/bin/cnpm-sync#L82
const log = `[${new Date().toISOString()}] ${stateMessage} Sync ${fullname} data: ${JSON.stringify(task)}`;
return {
ok: true,
syncDone,
log,
logUrl: task.logUrl,
error: task.error,
};
}
};
exports.PackageSyncController = PackageSyncController;
__decorate([
(0, tegg_1.Inject)(),
__metadata("design:type", PackageSyncerService_1.PackageSyncerService)
], PackageSyncController.prototype, "packageSyncerService", void 0);
__decorate([
(0, tegg_1.Inject)(),
__metadata("design:type", tegg_1.BackgroundTaskHelper)
], PackageSyncController.prototype, "backgroundTaskHelper", void 0);
__decorate([
(0, tegg_1.Inject)(),
__metadata("design:type", RegistryManagerService_1.RegistryManagerService)
], PackageSyncController.prototype, "registryManagerService", void 0);
__decorate([
(0, tegg_1.HTTPMethod)({
// PUT /-/package/:fullname/syncs
path: `/-/package/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/syncs`,
method: tegg_1.HTTPMethodEnum.PUT,
}),
__param(0, (0, tegg_1.Context)()),
__param(1, (0, tegg_1.HTTPParam)()),
__param(2, (0, tegg_1.HTTPBody)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String, Object]),
__metadata("design:returntype", Promise)
], PackageSyncController.prototype, "createSyncTask", null);
__decorate([
(0, tegg_1.HTTPMethod)({
// GET /-/package/:fullname/syncs/:syncId
path: `/-/package/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/syncs/:taskId`,
method: tegg_1.HTTPMethodEnum.GET,
}),
__param(0, (0, tegg_1.HTTPParam)()),
__param(1, (0, tegg_1.HTTPParam)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String]),
__metadata("design:returntype", Promise)
], PackageSyncController.prototype, "showSyncTask", null);
__decorate([
(0, tegg_1.HTTPMethod)({
// GET /-/package/:fullname/syncs/:syncId/log
path: `/-/package/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/syncs/:taskId/log`,
method: tegg_1.HTTPMethodEnum.GET,
}),
__param(0, (0, tegg_1.Context)()),
__param(1, (0, tegg_1.HTTPParam)()),
__param(2, (0, tegg_1.HTTPParam)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String, String]),
__metadata("design:returntype", Promise)
], PackageSyncController.prototype, "showSyncTaskLog", null);
__decorate([
(0, tegg_1.HTTPMethod)({
// PUT /:fullname/sync
path: `/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/sync`,
method: tegg_1.HTTPMethodEnum.PUT,
}),
__param(0, (0, tegg_1.Context)()),
__param(1, (0, tegg_1.HTTPParam)()),
__param(2, (0, tegg_1.HTTPQuery)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String, String]),
__metadata("design:returntype", Promise)
], PackageSyncController.prototype, "deprecatedCreateSyncTask", null);
__decorate([
(0, tegg_1.HTTPMethod)({
// GET /:fullname/sync/log/:taskId
path: `/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/sync/log/:taskId`,
method: tegg_1.HTTPMethodEnum.GET,
}),
__param(0, (0, tegg_1.HTTPParam)()),
__param(1, (0, tegg_1.HTTPParam)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String]),
__metadata("design:returntype", Promise)
], PackageSyncController.prototype, "deprecatedShowSyncTask", null);
exports.PackageSyncController = PackageSyncController = __decorate([
(0, tegg_1.HTTPController)()
], PackageSyncController);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFja2FnZVN5bmNDb250cm9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vYXBwL3BvcnQvY29udHJvbGxlci9QYWNrYWdlU3luY0NvbnRyb2xsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsc0NBV3FCO0FBQ3JCLDJDQUEyRDtBQUMzRCw2REFBMEQ7QUFDMUQsMERBQWdGO0FBRWhGLGtGQUErRTtBQUMvRSxzRkFBbUY7QUFDbkYsaURBQW1EO0FBQ25ELHdDQUFzRTtBQUN0RSxzREFBa0Q7QUFHM0MsSUFBTSxxQkFBcUIsR0FBM0IsTUFBTSxxQkFBc0IsU0FBUSx1Q0FBa0I7SUFVbkQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQVU7UUFDeEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDJIQUEySCxFQUMxSSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQ3RFLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDeEMsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDO1FBQ3ZCLElBQUk7WUFDRixNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDbkQ7UUFBQyxPQUFPLEdBQUcsRUFBRTtZQUNaLE1BQU0sR0FBRyxPQUFPLENBQUM7WUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDeEI7Z0JBQVM7WUFDUixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDO1lBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDZFQUE2RSxFQUM1RixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQzlDO0lBQ0gsQ0FBQztJQU9LLEFBQU4sS0FBSyxDQUFDLGNBQWMsQ0FBWSxHQUFlLEVBQWUsUUFBZ0IsRUFBYyxJQUF5QjtRQUNuSCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNwQixNQUFNLElBQUksMkJBQWMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1NBQ3ZEO1FBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxrQkFBa0IsR0FBRyxDQUFDLElBQUksc0JBQXNCLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0YsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV4RCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsS0FBSyxvQkFBUSxDQUFDLEtBQUssSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoRSxNQUFNLElBQUksMkJBQWMsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1NBQzlEO1FBRUQsTUFBTSxNQUFNLEdBQUc7WUFDYixRQUFRO1lBQ1IsSUFBSTtZQUNKLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCO1lBQ3pDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCO1lBQ3pDLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUs7WUFDbkIsMkNBQTJDO1lBQzNDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLElBQUksT0FBTztZQUNwRCxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1NBQ3hDLENBQUM7UUFDRixHQUFHLENBQUMsU0FBUyxDQUFDLDZCQUFtQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzNDLE1BQU0sQ0FBRSxLQUFLLEVBQUUsSUFBSSxDQUFFLEdBQUcsSUFBQSw2QkFBZSxFQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6RCxNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVFLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUUxRixJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDbEMsTUFBTSxJQUFJLDJCQUFjLENBQUMsZ0NBQWdDLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1NBQ2hGO1FBQ0QsSUFBSSxhQUFhLEVBQUUsU0FBUyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ3pDLE1BQU0sSUFBSSwyQkFBYyxDQUFDLGdDQUFnQyxNQUFNLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztTQUM5RTtRQUNELElBQUksTUFBTSxDQUFDLGdCQUFnQixJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLHFCQUFxQixFQUFFO1lBQy9FLE1BQU0sSUFBSSwyQkFBYyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7U0FDckU7UUFDRCxJQUFJLFFBQVEsSUFBSSxhQUFhLEVBQUUsVUFBVSxJQUFJLGFBQWEsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLFVBQVUsRUFBRTtZQUM3RixNQUFNLElBQUksMkJBQWMsQ0FBQyw4QkFBOEIsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7U0FDcEY7UUFDRCxNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMseUJBQXlCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0UsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7WUFDdkUsUUFBUSxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQ2hCLFFBQVEsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDakMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1lBQ2pCLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxnQkFBZ0I7WUFDekMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjtZQUN6QyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsZ0JBQWdCO1lBQ3pDLFVBQVUsRUFBRSxRQUFRLEVBQUUsVUFBVTtZQUNoQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7U0FDakYsQ0FBQyxDQUFDO1FBQ0gsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMseUVBQXlFLEVBQ3ZGLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDekIsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ2QsSUFBSSxPQUFPLEVBQUU7Z0JBQ1gsc0NBQXNDO2dCQUN0QyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUNsRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFO29CQUN2QyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx1RUFBdUUsRUFDckYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUNmLDZCQUE2QjtvQkFDN0IsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3JDLENBQUMsQ0FBQyxDQUFDO2FBQ0o7U0FDRjtRQUNELEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDO1FBQ2pCLE9BQU87WUFDTCxFQUFFLEVBQUUsSUFBSTtZQUNSLEVBQUUsRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNmLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtZQUNmLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztTQUNsQixDQUFDO0lBQ0osQ0FBQztJQUVELGdFQUFnRTtJQU0xRCxBQUFOLEtBQUssQ0FBQyxZQUFZLENBQWMsUUFBZ0IsRUFBZSxNQUFjO1FBQzNFLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSwwQkFBYSxDQUFDLFlBQVksUUFBUSxnQkFBZ0IsTUFBTSxhQUFhLENBQUMsQ0FBQztRQUM1RixJQUFJLE1BQTBCLENBQUM7UUFDL0IsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLGdCQUFTLENBQUMsT0FBTyxFQUFFO1lBQ3BDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsY0FBYyxRQUFRLFVBQVUsTUFBTSxNQUFNLENBQUM7U0FDdkY7UUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLFNBQVMsQ0FBQztRQUN0QyxPQUFPO1lBQ0wsRUFBRSxFQUFFLElBQUk7WUFDUixFQUFFLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDZixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7WUFDakIsTUFBTTtZQUNOLEtBQUs7U0FDTixDQUFDO0lBQ0osQ0FBQztJQUVELGdFQUFnRTtJQU0xRCxBQUFOLEtBQUssQ0FBQyxlQUFlLENBQVksR0FBZSxFQUFlLFFBQWdCLEVBQWUsTUFBYztRQUMxRyxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksMEJBQWEsQ0FBQyxZQUFZLFFBQVEsZ0JBQWdCLE1BQU0sYUFBYSxDQUFDLENBQUM7UUFDNUYsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLGdCQUFTLENBQUMsT0FBTztZQUFFLE1BQU0sSUFBSSwwQkFBYSxDQUFDLFlBQVksUUFBUSxnQkFBZ0IsTUFBTSxpQkFBaUIsQ0FBQyxDQUFDO1FBRTNILE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsY0FBYztZQUFFLE1BQU0sSUFBSSwwQkFBYSxDQUFDLFlBQVksUUFBUSxnQkFBZ0IsTUFBTSxpQkFBaUIsQ0FBQyxDQUFDO1FBQzFHLElBQUksT0FBTyxjQUFjLEtBQUssUUFBUSxFQUFFO1lBQ3RDLEdBQUcsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDN0IsT0FBTztTQUNSO1FBQ0QsR0FBRyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7UUFDakIsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVELGdEQUFnRDtJQUNoRCxxRUFBcUU7SUFNL0QsQUFBTixLQUFLLENBQUMsd0JBQXdCLENBQVksR0FBZSxFQUFlLFFBQWdCLEVBQWUsTUFBYztRQUNuSCxNQUFNLE9BQU8sR0FBd0I7WUFDbkMsUUFBUTtZQUNSLElBQUksRUFBRSxrQkFBa0IsR0FBRyxDQUFDLElBQUksc0JBQXNCLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO1lBQzFFLGdCQUFnQixFQUFFLE1BQU0sS0FBSyxNQUFNO1lBQ25DLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsS0FBSyxFQUFFLEtBQUs7WUFDWixnQkFBZ0IsRUFBRSxLQUFLO1NBQ3hCLENBQUM7UUFDRixNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMvRCxPQUFPO1lBQ0wsRUFBRSxFQUFFLElBQUk7WUFDUixLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUU7U0FDZixDQUFDO0lBQ0osQ0FBQztJQUVELHlFQUF5RTtJQU1uRSxBQUFOLEtBQUssQ0FBQyxzQkFBc0IsQ0FBYyxRQUFnQixFQUFlLE1BQWM7UUFDckYsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN2RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxLQUFLLGdCQUFTLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssZ0JBQVMsQ0FBQyxVQUFVLENBQUM7UUFDekYsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztRQUMxRCwrRkFBK0Y7UUFDL0YsTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLFlBQVksU0FBUyxRQUFRLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzNHLE9BQU87WUFDTCxFQUFFLEVBQUUsSUFBSTtZQUNSLFFBQVE7WUFDUixHQUFHO1lBQ0gsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztTQUNsQixDQUFDO0lBQ0osQ0FBQztDQUNGLENBQUE7QUFqTVksc0RBQXFCO0FBRXhCO0lBRFAsSUFBQSxhQUFNLEdBQUU7OEJBQ3FCLDJDQUFvQjttRUFBQztBQUczQztJQURQLElBQUEsYUFBTSxHQUFFOzhCQUNxQiwyQkFBb0I7bUVBQUM7QUFHM0M7SUFEUCxJQUFBLGFBQU0sR0FBRTs4QkFDdUIsK0NBQXNCO3FFQUFDO0FBeUJqRDtJQUxMLElBQUEsaUJBQVUsRUFBQztRQUNWLGlDQUFpQztRQUNqQyxJQUFJLEVBQUUsd0JBQXdCLGlDQUFtQixTQUFTO1FBQzFELE1BQU0sRUFBRSxxQkFBYyxDQUFDLEdBQUc7S0FDM0IsQ0FBQztJQUNvQixXQUFBLElBQUEsY0FBTyxHQUFFLENBQUE7SUFBbUIsV0FBQSxJQUFBLGdCQUFTLEdBQUUsQ0FBQTtJQUFvQixXQUFBLElBQUEsZUFBUSxHQUFFLENBQUE7Ozs7MkRBc0UxRjtBQVFLO0lBTEwsSUFBQSxpQkFBVSxFQUFDO1FBQ1YseUNBQXlDO1FBQ3pDLElBQUksRUFBRSx3QkFBd0IsaUNBQW1CLGlCQUFpQjtRQUNsRSxNQUFNLEVBQUUscUJBQWMsQ0FBQyxHQUFHO0tBQzNCLENBQUM7SUFDa0IsV0FBQSxJQUFBLGdCQUFTLEdBQUUsQ0FBQTtJQUFvQixXQUFBLElBQUEsZ0JBQVMsR0FBRSxDQUFBOzs7O3lEQWdCN0Q7QUFRSztJQUxMLElBQUEsaUJBQVUsRUFBQztRQUNWLDZDQUE2QztRQUM3QyxJQUFJLEVBQUUsd0JBQXdCLGlDQUFtQixxQkFBcUI7UUFDdEUsTUFBTSxFQUFFLHFCQUFjLENBQUMsR0FBRztLQUMzQixDQUFDO0lBQ3FCLFdBQUEsSUFBQSxjQUFPLEdBQUUsQ0FBQTtJQUFtQixXQUFBLElBQUEsZ0JBQVMsR0FBRSxDQUFBO0lBQW9CLFdBQUEsSUFBQSxnQkFBUyxHQUFFLENBQUE7Ozs7NERBYTVGO0FBU0s7SUFMTCxJQUFBLGlCQUFVLEVBQUM7UUFDVixzQkFBc0I7UUFDdEIsSUFBSSxFQUFFLGNBQWMsaUNBQW1CLFFBQVE7UUFDL0MsTUFBTSxFQUFFLHFCQUFjLENBQUMsR0FBRztLQUMzQixDQUFDO0lBQzhCLFdBQUEsSUFBQSxjQUFPLEdBQUUsQ0FBQTtJQUFtQixXQUFBLElBQUEsZ0JBQVMsR0FBRSxDQUFBO0lBQW9CLFdBQUEsSUFBQSxnQkFBUyxHQUFFLENBQUE7Ozs7cUVBY3JHO0FBUUs7SUFMTCxJQUFBLGlCQUFVLEVBQUM7UUFDVixrQ0FBa0M7UUFDbEMsSUFBSSxFQUFFLGNBQWMsaUNBQW1CLG9CQUFvQjtRQUMzRCxNQUFNLEVBQUUscUJBQWMsQ0FBQyxHQUFHO0tBQzNCLENBQUM7SUFDNEIsV0FBQSxJQUFBLGdCQUFTLEdBQUUsQ0FBQTtJQUFvQixXQUFBLElBQUEsZ0JBQVMsR0FBRSxDQUFBOzs7O21FQWF2RTtnQ0FoTVUscUJBQXFCO0lBRGpDLElBQUEscUJBQWMsR0FBRTtHQUNKLHFCQUFxQixDQWlNakMifQ==