@tsclean/core
Version:
Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.
98 lines • 17.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RoutesResolver = void 0;
const helpers_1 = require("../helpers");
const route_path_factory_1 = require("./route-path-factory");
const router_exception_filters_1 = require("./router-exception-filters");
const router_explorer_1 = require("./router-explorer");
const router_proxy_1 = require("./router-proxy");
const app_1 = require("../app");
const exceptions_1 = require("../exceptions");
const services_1 = require("../services");
class RoutesResolver {
constructor(container, applicationConfig, injector, graphInspector) {
this.container = container;
this.applicationConfig = applicationConfig;
this.injector = injector;
this.logger = new services_1.Logger(RoutesResolver.name, {
timestamp: true,
});
this.routerProxy = new router_proxy_1.RouterProxy();
const httpAdapterRef = container.getHttpAdapterRef();
this.routerExceptionsFilter = new router_exception_filters_1.RouterExceptionFilters(container, applicationConfig, httpAdapterRef);
this.routePathFactory = new route_path_factory_1.RoutePathFactory(this.applicationConfig);
const metadataScanner = new app_1.MetadataScanner();
this.routerExplorer = new router_explorer_1.RouterExplorer(metadataScanner, this.container, graphInspector, this.injector, this.routerProxy, this.routerExceptionsFilter, this.applicationConfig, this.routePathFactory);
}
resolve(applicationRef, globalPrefix) {
const modules = this.container.getModules();
modules.forEach(({ controllers, metaType }, moduleName) => {
const modulePath = this.getModulePathMetadata(metaType);
this.registerRouters(controllers, moduleName, globalPrefix, modulePath, applicationRef);
});
}
registerRouters(routes, moduleName, globalPrefix, modulePath, applicationRef) {
routes.forEach((instanceWrapper) => {
const { metaType } = instanceWrapper;
const host = RoutesResolver.getHostMetadata(metaType);
const routerPaths = this.routerExplorer.extractRouterPath(metaType);
const controllerName = metaType.name;
routerPaths.forEach((path) => {
const pathsToLog = this.routePathFactory.create({
ctrlPath: path,
modulePath,
globalPrefix,
});
pathsToLog.forEach((path) => {
const logMessage = (0, helpers_1.CONTROLLER_MAPPING_MESSAGE)(controllerName, path);
});
const routePathMetadata = {
ctrlPath: path,
modulePath,
globalPrefix,
};
this.routerExplorer.explore(instanceWrapper, moduleName, applicationRef, host, routePathMetadata);
});
});
}
registerNotFoundHandler() {
const applicationRef = this.container.getHttpAdapterRef();
const callback = (req, res) => {
const method = applicationRef.getRequestMethod(req);
const url = applicationRef.getRequestUrl(req);
throw new exceptions_1.NotFoundException(`Cannot ${method} ${url}`);
};
const handler = this.routerExceptionsFilter.create({}, callback, "");
const proxy = this.routerProxy.createProxy(callback, handler);
applicationRef.setNotFoundHandler &&
applicationRef.setNotFoundHandler(proxy, this.applicationConfig.getGlobalPrefix());
}
registerExceptionHandler() {
const callback = (err, req, res, next) => {
throw this.mapExternalException(err);
};
const handler = this.routerExceptionsFilter.create({}, callback, "");
const proxy = this.routerProxy.createExceptionLayerProxy(callback, handler);
const applicationRef = this.container.getHttpAdapterRef();
applicationRef.setErrorHandler &&
applicationRef.setErrorHandler(proxy, this.applicationConfig.getGlobalPrefix());
}
mapExternalException(err) {
switch (true) {
case err instanceof SyntaxError:
return new exceptions_1.BadRequestException(err.message);
default:
return err;
}
}
getModulePathMetadata(metaType) {
const modulesContainer = this.container.getModules();
const modulePath = Reflect.getMetadata(helpers_1.MODULE_PATH + modulesContainer.applicationId, metaType);
return modulePath !== null && modulePath !== void 0 ? modulePath : Reflect.getMetadata(helpers_1.MODULE_PATH, metaType);
}
static getHostMetadata(metaType) {
return Reflect.getMetadata(helpers_1.HOST_METADATA, metaType);
}
}
exports.RoutesResolver = RoutesResolver;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVzLXJlc29sdmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JvdXRlci9yb3V0ZXMtcmVzb2x2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsd0NBSW9CO0FBQ3BCLDZEQUF3RDtBQUN4RCx5RUFBb0U7QUFDcEUsdURBQW1EO0FBQ25ELGlEQUE2QztBQUU3QyxnQ0FBNEQ7QUFRNUQsOENBQXVFO0FBRXZFLDBDQUFxQztBQUVyQyxNQUFhLGNBQWM7SUFVekIsWUFDbUIsU0FBdUIsRUFDdkIsaUJBQW9DLEVBQ3BDLFFBQWtCLEVBQ25DLGNBQThCO1FBSGIsY0FBUyxHQUFULFNBQVMsQ0FBYztRQUN2QixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLGFBQVEsR0FBUixRQUFRLENBQVU7UUFacEIsV0FBTSxHQUFHLElBQUksaUJBQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFO1lBQ3hELFNBQVMsRUFBRSxJQUFJO1NBQ2hCLENBQUMsQ0FBQztRQUVjLGdCQUFXLEdBQUcsSUFBSSwwQkFBVyxFQUFFLENBQUM7UUFXL0MsTUFBTSxjQUFjLEdBQUcsU0FBUyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDckQsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksaURBQXNCLENBQ3RELFNBQVMsRUFDVCxpQkFBaUIsRUFDakIsY0FBYyxDQUNmLENBQUM7UUFDRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxxQ0FBZ0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUVyRSxNQUFNLGVBQWUsR0FBRyxJQUFJLHFCQUFlLEVBQUUsQ0FBQztRQUM5QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksZ0NBQWMsQ0FDdEMsZUFBZSxFQUNmLElBQUksQ0FBQyxTQUFTLEVBQ2QsY0FBYyxFQUNkLElBQUksQ0FBQyxRQUFRLEVBQ2IsSUFBSSxDQUFDLFdBQVcsRUFDaEIsSUFBSSxDQUFDLHNCQUFz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QUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxxQkFBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFTyxNQUFNLENBQUMsZUFBZSxDQUM1QixRQUFrQztRQUVsQyxPQUFPLE9BQU8sQ0FBQyxXQUFXLENBQUMsdUJBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN0RCxDQUFDO0NBQ0Y7QUF2SkQsd0NBdUpDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ09OVFJPTExFUl9NQVBQSU5HX01FU1NBR0UsXG4gIEhPU1RfTUVUQURBVEEsXG4gIE1PRFVMRV9QQVRILFxufSBmcm9tIFwiLi4vaGVscGVyc1wiO1xuaW1wb3J0IHsgUm91dGVQYXRoRmFjdG9yeSB9IGZyb20gXCIuL3JvdXRlLXBhdGgtZmFjdG9yeVwiO1xuaW1wb3J0IHsgUm91dGVyRXhjZXB0aW9uRmlsdGVycyB9IGZyb20gXCIuL3JvdXRlci1leGNlcHRpb24tZmlsdGVyc1wiO1xuaW1wb3J0IHsgUm91dGVyRXhwbG9yZXIgfSBmcm9tIFwiLi9yb3V0ZXItZXhwbG9yZXJcIjtcbmltcG9ydCB7IFJvdXRlclByb3h5IH0gZnJvbSBcIi4vcm91dGVyLXByb3h5XCI7XG5pbXBvcnQgeyBJbmplY3RvciwgSW5zdGFuY2VXcmFwcGVyLCBDb250YWluZXJJb0MgfSBmcm9tIFwiLi4vY29yZVwiO1xuaW1wb3J0IHsgQXBwbGljYXRpb25Db25maWcsIE1ldGFkYXRhU2Nhbm5lciB9IGZyb20gXCIuLi9hcHBcIjtcbmltcG9ydCB7XG4gIEh0dHBTZXJ2ZXIsXG4gIFJlc29sdmVySW50ZXJmYWNlLFxuICBSb3V0ZVBhdGhNZXRhZGF0YUludGVyZmFjZSxcbiAgVHlwZSxcbn0gZnJvbSBcIi4uL2NvbnRyYWN0c1wiO1xuaW1wb3J0IHsgQ29udHJvbGxlclR5cGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IEJhZFJlcXVlc3RFeGNlcHRpb24sIE5vdEZvdW5kRXhjZXB0aW9uIH0gZnJvbSBcIi4uL2V4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IEdyYXBoSW5zcGVjdG9yIH0gZnJvbSBcIi4uL2luc3BlY3RvclwiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4uL3NlcnZpY2VzXCI7XG5cbmV4cG9ydCBjbGFzcyBSb3V0ZXNSZXNvbHZlciBpbXBsZW1lbnRzIFJlc29sdmVySW50ZXJmYWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXIgPSBuZXcgTG9nZ2VyKFJvdXRlc1Jlc29sdmVyLm5hbWUsIHtcbiAgICB0aW1lc3RhbXA6IHRydWUsXG4gIH0pO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyUHJveHkgPSBuZXcgUm91dGVyUHJveHkoKTtcbiAgcHJpdmF0ZSByZWFkb25seSByb3V0ZVBhdGhGYWN0b3J5OiBSb3V0ZVBhdGhGYWN0b3J5O1xuICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlckV4Y2VwdGlvbnNGaWx0ZXI6IFJvdXRlckV4Y2VwdGlvbkZpbHRlcnM7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyRXhwbG9yZXI6IFJvdXRlckV4cGxvcmVyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY29udGFpbmVyOiBDb250YWluZXJJb0MsXG4gICAgcHJpdmF0ZSByZWFkb25seSBhcHBsaWNhdGlvbkNvbmZpZzogQXBwbGljYXRpb25Db25maWcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgZ3JhcGhJbnNwZWN0b3I6IEdyYXBoSW5zcGVjdG9yLFxuICApIHtcbiAgICBjb25zdCBodHRwQWRhcHRlclJlZiA9IGNvbnRhaW5lci5nZXRIdHRwQWRhcHRlclJlZigpO1xuICAgIHRoaXMucm91dGVyRXhjZXB0aW9uc0ZpbHRlciA9IG5ldyBSb3V0ZXJFeGNlcHRpb25GaWx0ZXJzKFxuICAgICAgY29udGFpbmVyLFxuICAgICAgYXBwbGljYXRpb25Db25maWcsXG4gICAgICBodHRwQWRhcHRlclJlZlxuICAgICk7XG4gICAgdGhpcy5yb3V0ZVBhdGhGYWN0b3J5ID0gbmV3IFJvdXRlUGF0aEZhY3RvcnkodGhpcy5hcHBsaWNhdGlvbkNvbmZpZyk7XG5cbiAgICBjb25zdCBtZXRhZGF0YVNjYW5uZXIgPSBuZXcgTWV0YWRhdGFTY2FubmVyKCk7XG4gICAgdGhpcy5yb3V0ZXJFeHBsb3JlciA9IG5ldyBSb3V0ZXJFeHBsb3JlcihcbiAgICAgIG1ldGFkYXRhU2Nhbm5lcixcbiAgICAgIHRoaXMuY29udGFpbmVyLFxuICAgICAgZ3JhcGhJbnNwZWN0b3IsXG4gICAgICB0aGlzLmluamVjdG9yLFxuICAgICAgdGhpcy5yb3V0ZXJQcm94eSxcbiAgICAgIHRoaXMucm91dGVyRXhjZXB0aW9uc0ZpbHRlcixcbiAgICAgIHRoaXMuYXBwbGljYXRpb25Db25maWcsXG4gICAgICB0aGlzLnJvdXRlUGF0aEZhY3RvcnksXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyByZXNvbHZlPFQgZXh0ZW5kcyBIdHRwU2VydmVyPihcbiAgICBhcHBsaWNhdGlvblJlZjogVCxcbiAgICBnbG9iYWxQcmVmaXg6IHN0cmluZ1xuICApIHtcbiAgICBjb25zdCBtb2R1bGVzID0gdGhpcy5jb250YWluZXIuZ2V0TW9kdWxlcygpO1xuICAgIG1vZHVsZXMuZm9yRWFjaCgoeyBjb250cm9sbGVycywgbWV0YVR5cGUgfSwgbW9kdWxlTmFtZSkgPT4ge1xuICAgICAgY29uc3QgbW9kdWxlUGF0aCA9IHRoaXMuZ2V0TW9kdWxlUGF0aE1ldGFkYXRhKG1ldGFUeXBlKTtcbiAgICAgIHRoaXMucmVnaXN0ZXJSb3V0ZXJzKFxuICAgICAgICBjb250cm9sbGVycyxcbiAgICAgICAgbW9kdWxlTmFtZSxcbiAgICAgICAgZ2xvYmFsUHJlZml4LFxuICAgICAgICBtb2R1bGVQYXRoLFxuICAgICAgICBhcHBsaWNhdGlvblJlZlxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3RlclJvdXRlcnMoXG4gICAgcm91dGVzOiBNYXA8c3RyaW5nIHwgc3ltYm9sIHwgRnVuY3Rpb24sIEluc3RhbmNlV3JhcHBlcjxDb250cm9sbGVyVHlwZT4+LFxuICAgIG1vZHVsZU5hbWU6IHN0cmluZyxcbiAgICBnbG9iYWxQcmVmaXg6IHN0cmluZyxcbiAgICBtb2R1bGVQYXRoOiBzdHJpbmcsXG4gICAgYXBwbGljYXRpb25SZWY6IEh0dHBTZXJ2ZXJcbiAgKSB7XG4gICAgcm91dGVzLmZvckVhY2goKGluc3RhbmNlV3JhcHBlcikgPT4ge1xuICAgICAgY29uc3QgeyBtZXRhVHlwZSB9ID0gaW5zdGFuY2VXcmFwcGVyO1xuXG4gICAgICBjb25zdCBob3N0ID0gUm91dGVzUmVzb2x2ZXIuZ2V0SG9zdE1ldGFkYXRhKG1ldGFUeXBlKTtcbiAgICAgIGNvbnN0IHJvdXRlclBhdGhzID0gdGhpcy5yb3V0ZXJFeHBsb3Jlci5leHRyYWN0Um91dGVyUGF0aChcbiAgICAgICAgbWV0YVR5cGUgYXMgVHlwZTxhbnk+XG4gICAgICApO1xuXG4gICAgICBjb25zdCBjb250cm9sbGVyTmFtZSA9IG1ldGFUeXBlLm5hbWU7XG5cbiAgICAgIHJvdXRlclBhdGhzLmZvckVhY2goKHBhdGgpID0+IHtcbiAgICAgICAgY29uc3QgcGF0aHNUb0xvZyA9IHRoaXMucm91dGVQYXRoRmFjdG9yeS5jcmVhdGUoe1xuICAgICAgICAgIGN0cmxQYXRoOiBwYXRoLFxuICAgICAgICAgIG1vZHVsZVBhdGgsXG4gICAgICAgICAgZ2xvYmFsUHJlZml4LFxuICAgICAgICB9KTtcblxuICAgICAgICBwYXRoc1RvTG9nLmZvckVhY2goKHBhdGgpID0+IHtcbiAgICAgICAgICBjb25zdCBsb2dNZXNzYWdlID0gQ09OVFJPTExFUl9NQVBQSU5HX01FU1NBR0UoY29udHJvbGxlck5hbWUsIHBhdGgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByb3V0ZVBhdGhNZXRhZGF0YTogUm91dGVQYXRoTWV0YWRhdGFJbnRlcmZhY2UgPSB7XG4gICAgICAgICAgY3RybFBhdGg6IHBhdGgsXG4gICAgICAgICAgbW9kdWxlUGF0aCxcbiAgICAgICAgICBnbG9iYWxQcmVmaXgsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucm91dGVyRXhwbG9yZXIuZXhwbG9yZShcbiAgICAgICAgICBpbnN0YW5jZVdyYXBwZXIsXG4gICAgICAgICAgbW9kdWxlTmFtZSxcbiAgICAgICAgICBhcHBsaWNhdGlvblJlZixcbiAgICAgICAgICBob3N0LFxuICAgICAgICAgIHJvdXRlUGF0aE1ldGFkYXRhXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck5vdEZvdW5kSGFuZGxlcigpIHtcbiAgICBjb25zdCBhcHBsaWNhdGlvblJlZiA9IHRoaXMuY29udGFpbmVyLmdldEh0dHBBZGFwdGVyUmVmKCk7XG4gICAgY29uc3QgY2FsbGJhY2sgPSA8VCwgUj4ocmVxOiBULCByZXM6IFIpID0+IHtcbiAgICAgIGNvbnN0IG1ldGhvZCA9IGFwcGxpY2F0aW9uUmVmLmdldFJlcXVlc3RNZXRob2QocmVxKTtcbiAgICAgIGNvbnN0IHVybCA9IGFwcGxpY2F0aW9uUmVmLmdldFJlcXVlc3RVcmwocmVxKTtcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihgQ2Fubm90ICR7bWV0aG9kfSAke3VybH1gKTtcbiAgICB9O1xuICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLnJvdXRlckV4Y2VwdGlvbnNGaWx0ZXIuY3JlYXRlKHt9LCBjYWxsYmFjaywgXCJcIik7XG4gICAgY29uc3QgcHJveHkgPSB0aGlzLnJvdXRlclByb3h5LmNyZWF0ZVByb3h5KGNhbGxiYWNrLCBoYW5kbGVyKTtcbiAgICBhcHBsaWNhdGlvblJlZi5zZXROb3RGb3VuZEhhbmRsZXIgJiZcbiAgICAgIGFwcGxpY2F0aW9uUmVmLnNldE5vdEZvdW5kSGFuZGxlcihcbiAgICAgICAgcHJveHksXG4gICAgICAgIHRoaXMuYXBwbGljYXRpb25Db25maWcuZ2V0R2xvYmFsUHJlZml4KClcbiAgICAgICk7XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJFeGNlcHRpb25IYW5kbGVyKCkge1xuICAgIGNvbnN0IGNhbGxiYWNrID0gPEUsIFQsIFI+KGVycjogRSwgcmVxOiBULCByZXM6IFIsIG5leHQ6IEZ1bmN0aW9uKSA9PiB7XG4gICAgICB0aHJvdyB0aGlzLm1hcEV4dGVybmFsRXhjZXB0aW9uKGVycik7XG4gICAgfTtcbiAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5yb3V0ZXJFeGNlcHRpb25zRmlsdGVyLmNyZWF0ZSh7fSwgY2FsbGJhY2sgYXMgYW55LCBcIlwiKTtcbiAgICBjb25zdCBwcm94eSA9IHRoaXMucm91dGVyUHJveHkuY3JlYXRlRXhjZXB0aW9uTGF5ZXJQcm94eShjYWxsYmFjaywgaGFuZGxlcik7XG4gICAgY29uc3QgYXBwbGljYXRpb25SZWYgPSB0aGlzLmNvbnRhaW5lci5nZXRIdHRwQWRhcHRlclJlZigpO1xuICAgIGFwcGxpY2F0aW9uUmVmLnNldEVycm9ySGFuZGxlciAmJlxuICAgICAgYXBwbGljYXRpb25SZWYuc2V0RXJyb3JIYW5kbGVyKFxuICAgICAgICBwcm94eSxcbiAgICAgICAgdGhpcy5hcHBsaWNhdGlvbkNvbmZpZy5nZXRHbG9iYWxQcmVmaXgoKVxuICAgICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBtYXBFeHRlcm5hbEV4Y2VwdGlvbihlcnI6IGFueSkge1xuICAgIHN3aXRjaCAodHJ1ZSkge1xuICAgICAgY2FzZSBlcnIgaW5zdGFuY2VvZiBTeW50YXhFcnJvcjpcbiAgICAgICAgcmV0dXJuIG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKGVyci5tZXNzYWdlKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBlcnI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRNb2R1bGVQYXRoTWV0YWRhdGEobWV0YVR5cGU6IFR5cGU8dW5rbm93bj4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1vZHVsZXNDb250YWluZXIgPSB0aGlzLmNvbnRhaW5lci5nZXRNb2R1bGVzKCk7XG4gICAgY29uc3QgbW9kdWxlUGF0aCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBNT0RVTEVfUEFUSCArIG1vZHVsZXNDb250YWluZXIuYXBwbGljYXRpb25JZCxcbiAgICAgIG1ldGFUeXBlXG4gICAgKTtcbiAgICByZXR1cm4gbW9kdWxlUGF0aCA/PyBSZWZsZWN0LmdldE1ldGFkYXRhKE1PRFVMRV9QQVRILCBtZXRhVHlwZSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRIb3N0TWV0YWRhdGEoXG4gICAgbWV0YVR5cGU6IFR5cGU8dW5rbm93bj4gfCBGdW5jdGlvblxuICApOiBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIFJlZmxlY3QuZ2V0TWV0YWRhdGEoSE9TVF9NRVRBREFUQSwgbWV0YVR5cGUpO1xuICB9XG59XG4iXX0=