UNPKG

@typegoose/typegoose

Version:

Define Mongoose models using TypeScript classes

324 lines 28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Passthrough = exports.getDiscriminatorModelForClass = exports.deleteModelWithClass = exports.deleteModel = exports.addModelToTypegoose = exports.buildSchema = exports.getModelWithString = exports.getModelForClass = exports.PropType = exports.Severity = exports.getName = exports.getClass = exports.types = exports.errors = exports.defaultClasses = exports.LogLevels = exports.setLogLevel = exports.setGlobalOptions = exports.mongoose = void 0; const tslib_1 = require("tslib"); /* imports */ const mongoose_1 = tslib_1.__importDefault(require("mongoose")); exports.mongoose = mongoose_1.default; require("reflect-metadata"); const semver = tslib_1.__importStar(require("semver")); const utils_1 = require("./internal/utils"); // using "typeof process", because somehow js gives a ReferenceError when using "process === undefined" in browser /* istanbul ignore next */ if (typeof process !== 'undefined' && !(0, utils_1.isNullOrUndefined)(process?.version) && !(0, utils_1.isNullOrUndefined)(mongoose_1.default?.version)) { // for usage on client side /* istanbul ignore next */ if (semver.lt(mongoose_1.default?.version, '8.10.0')) { throw new Error(`Please use mongoose 8.10.0 or higher (Current mongoose: ${mongoose_1.default.version}) [E001]`); } /* istanbul ignore next */ if (semver.lt(process.version.slice(1), '16.20.1')) { throw new Error('You are using a NodeJS Version below 16.20.1, Please Upgrade! [E002]'); } } const globalOptions_1 = require("./globalOptions"); Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return globalOptions_1.setGlobalOptions; } }); const constants_1 = require("./internal/constants"); const data_1 = require("./internal/data"); const schema_1 = require("./internal/schema"); const logSettings_1 = require("./logSettings"); const typeguards_1 = require("./typeguards"); const errors_1 = require("./internal/errors"); (0, globalOptions_1.parseENV)(); // call this before anything to ensure they are applied (including before defaultclasses) var logSettings_2 = require("./logSettings"); Object.defineProperty(exports, "setLogLevel", { enumerable: true, get: function () { return logSettings_2.setLogLevel; } }); Object.defineProperty(exports, "LogLevels", { enumerable: true, get: function () { return logSettings_2.LogLevels; } }); tslib_1.__exportStar(require("./prop"), exports); tslib_1.__exportStar(require("./hooks"), exports); tslib_1.__exportStar(require("./plugin"), exports); tslib_1.__exportStar(require("./indexes"), exports); tslib_1.__exportStar(require("./searchIndexes"), exports); tslib_1.__exportStar(require("./modelOptions"), exports); tslib_1.__exportStar(require("./queryMethod"), exports); tslib_1.__exportStar(require("./typeguards"), exports); exports.defaultClasses = tslib_1.__importStar(require("./defaultClasses")); exports.errors = tslib_1.__importStar(require("./internal/errors")); exports.types = tslib_1.__importStar(require("./types")); var utils_2 = require("./internal/utils"); Object.defineProperty(exports, "getClass", { enumerable: true, get: function () { return utils_2.getClass; } }); Object.defineProperty(exports, "getName", { enumerable: true, get: function () { return utils_2.getName; } }); var constants_2 = require("./internal/constants"); Object.defineProperty(exports, "Severity", { enumerable: true, get: function () { return constants_2.Severity; } }); Object.defineProperty(exports, "PropType", { enumerable: true, get: function () { return constants_2.PropType; } }); /** * Build a Model From a Class * @param cl The Class to build a Model from * @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with * @returns The finished Model * @public * @example * ```ts * class ClassName {} * * const NameModel = getModelForClass(ClassName); * ``` */ function getModelForClass(cl, options) { (0, utils_1.assertionIsClass)(cl); const rawOptions = typeof options === 'object' ? options : {}; const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models const mergedOptions = (0, utils_1.getMergedModelOptions)(rawOptions, cl); const name = (0, utils_1.getName)(cl, overwriteNaming); if ((0, utils_1.isCachingEnabled)(mergedOptions.options?.disableCaching) && data_1.models.has(name)) { return data_1.models.get(name); } const modelFn = mergedOptions?.existingConnection?.model.bind(mergedOptions.existingConnection) ?? mergedOptions?.existingMongoose?.model.bind(mergedOptions.existingMongoose) ?? mongoose_1.default.model.bind(mongoose_1.default); const compiledModel = modelFn(name, buildSchema(cl, mergedOptions)); return addModelToTypegoose(compiledModel, cl, { existingMongoose: mergedOptions?.existingMongoose, existingConnection: mergedOptions?.existingConnection, disableCaching: mergedOptions.options?.disableCaching, }); } exports.getModelForClass = getModelForClass; /** * Get Model from internal cache * @param key Model's name key * @example * ```ts * class ClassName {} * getModelForClass(ClassName); // build the model * const NameModel = getModelWithString<typeof ClassName>("ClassName"); * ``` */ function getModelWithString(key) { (0, utils_1.assertion)(typeof key === 'string', () => new errors_1.ExpectedTypeError('key', 'string', key)); (0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('getModelWithString')); return data_1.models.get(key); } exports.getModelWithString = getModelWithString; /** * Generates a Mongoose schema out of class props, iterating through all parents * @param cl The Class to build a Schema from * @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with * @returns Returns the Build Schema * @example * ```ts * class ClassName {} * const NameSchema = buildSchema(ClassName); * const NameModel = mongoose.model("Name", NameSchema); * ``` */ function buildSchema(cl, options) { (0, utils_1.assertionIsClass)(cl); const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(options); logSettings_1.logger.debug('buildSchema called for "%s"', (0, utils_1.getName)(cl, overwriteNaming)); // dont re-run the merging if already done so before (like in getModelForClass) const mergedOptions = (0, utils_1.getMergedModelOptions)(options, cl); let sch = undefined; /** Parent Constructor */ let parentCtor = Object.getPrototypeOf(cl.prototype).constructor; /* This array is to execute from lowest class to highest (when extending) */ const parentClasses = []; /** Options for the next lower class that gets unshifted to {@link parentClasses} (ie the super-class) */ let superOptions = {}; // first run for some options based on input class options (if any), because the while-loop is for the prototypes (if any) { // get new options because "mergedOptions" is merged with lower options, but "upperOptions" requires the "own" version, if any const mergedOwnOptions = (0, utils_1.getMergedModelOptions)(options, cl, true); applySuperOptions(superOptions, mergedOwnOptions); } // iterate trough all parents to the lowest class while (parentCtor?.name !== 'Object') { // add lower classes (when extending) to the front of the array to be processed first parentClasses.unshift([parentCtor, superOptions]); // clone object, because otherwise it will affect the upper classes too because the same reference is used superOptions = { ...superOptions }; { // only get the own metadata, possible because "upperOptions" at the moment only requires the "own" metadata const ropt = Reflect.getOwnMetadata(constants_1.DecoratorKeys.ModelOptions, parentCtor) ?? {}; applySuperOptions(superOptions, ropt); } // set next parent parentCtor = Object.getPrototypeOf(parentCtor.prototype).constructor; } // iterate and build class schemas from lowest to highest (when extending classes, the lower class will get build first) see https://github.com/typegoose/typegoose/pull/243 for (const [parentClass, extraOptions] of parentClasses) { // extend schema sch = (0, schema_1._buildSchema)(parentClass, sch, mergedOptions, false, undefined, extraOptions); } // get schema of current model sch = (0, schema_1._buildSchema)(cl, sch, mergedOptions, true, overwriteNaming); return sch; } exports.buildSchema = buildSchema; /** * Apply options to "superOptions" object, based on "modelOptions" * @param superOptions The "superOptions" object * @param modelOptions The Model Options of the current class */ function applySuperOptions(superOptions, modelOptions) { // only affect options of lower classes, not the class the options are from if (modelOptions.options?.disableLowerIndexes) { superOptions.buildIndexes = false; } } /** * Add a Class-Model Pair to the Typegoose Cache * This can be used to add custom Models to Typegoose, with the type information of "cl" * Note: no guarrantee that the type information is fully correct when used manually * @param model The Model to store * @param cl The Class to store * @param options Overwrite existingMongoose or existingConnection * @example * ```ts * class ClassName {} * * const schema = buildSchema(ClassName); * // modifications to the schema can be done * const model = addModelToTypegoose(mongoose.model("Name", schema), ClassName); * ``` */ function addModelToTypegoose(model, cl, options) { const mongooseModel = options?.existingMongoose?.Model || options?.existingConnection?.base?.Model || mongoose_1.default.Model; (0, utils_1.assertion)(model.prototype instanceof mongooseModel, new errors_1.NotValidModelError(model, 'addModelToTypegoose.model')); (0, utils_1.assertionIsClass)(cl); // only check cache after the above checks, just to make sure they run if (!(0, utils_1.isCachingEnabled)(options?.disableCaching)) { logSettings_1.logger.info('Caching is not enabled, skipping adding'); return model; } const name = model.modelName; (0, utils_1.assertion)(!data_1.models.has(name), new errors_1.FunctionCalledMoreThanSupportedError('addModelToTypegoose', 1, `This was caused because the model name "${name}" already exists in the typegoose-internal "models" cache`)); if (data_1.constructors.get(name)) { logSettings_1.logger.info('Class "%s" already existed in the constructors Map', name); } data_1.models.set(name, model); data_1.constructors.set(name, cl); return data_1.models.get(name); } exports.addModelToTypegoose = addModelToTypegoose; /** * Deletes a existing model so that it can be overwritten with another model * (deletes from mongoose.connection and typegoose models cache and typegoose constructors cache) * @param name The Model's mongoose name * @example * ```ts * class ClassName {} * const NameModel = getModelForClass(ClassName); * deleteModel("ClassName"); * ``` */ function deleteModel(name) { (0, utils_1.assertion)(typeof name === 'string', () => new errors_1.ExpectedTypeError('name', 'string', name)); (0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('deleteModelWithClass')); logSettings_1.logger.debug('Deleting Model "%s"', name); const model = data_1.models.get(name); if (!(0, utils_1.isNullOrUndefined)(model)) { model.db.deleteModel(name); } data_1.models.delete(name); data_1.constructors.delete(name); } exports.deleteModel = deleteModel; /** * Delete a model, with the given class * Same as "deleteModel", only that it can be done with the class instead of the name * @param cl The Class to delete the model from * @example * ```ts * class ClassName {} * const NameModel = getModelForClass(ClassName); * deleteModelWithClass(ClassName); * ``` */ function deleteModelWithClass(cl) { (0, utils_1.assertionIsClass)(cl); (0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('deleteModelWithClass')); let name = (0, utils_1.getName)(cl); if (!data_1.models.has(name)) { logSettings_1.logger.debug(`Class "${name}" is not in "models", trying to find in "constructors"`); let found = false; // type "Map" does not have a "find" function, and using "get" would maybe result in the incorrect values for (const [cname, constructor] of data_1.constructors) { if (constructor === cl) { logSettings_1.logger.debug(`Found Class in "constructors" with class name "${name}" and entered name "${cname}""`); name = cname; found = true; } } if (!found) { logSettings_1.logger.debug(`Could not find class "${name}" in constructors`); return; } } return deleteModel(name); } exports.deleteModelWithClass = deleteModelWithClass; function getDiscriminatorModelForClass(from, cl, value_or_options, options) { (0, utils_1.assertion)((0, typeguards_1.isModel)(from), new errors_1.NotValidModelError(from, 'getDiscriminatorModelForClass.from')); (0, utils_1.assertionIsClass)(cl); const value = typeof value_or_options === 'string' ? value_or_options : undefined; const rawOptions = typeof value_or_options !== 'string' ? value_or_options : typeof options === 'object' ? options : {}; const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models const mergedOptions = (0, utils_1.getMergedModelOptions)(rawOptions, cl); const name = (0, utils_1.getName)(cl, overwriteNaming); if ((0, utils_1.isCachingEnabled)(mergedOptions.options?.disableCaching) && data_1.models.has(name)) { return data_1.models.get(name); } if (mergedOptions.existingConnection && mergedOptions.existingConnection !== from.db) { (0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingConnection'); } if (mergedOptions.existingMongoose && mergedOptions.existingMongoose !== from.base) { (0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingMongoose'); } const sch = buildSchema(cl, mergedOptions); const mergeHooks = mergedOptions.options?.enableMergeHooks ?? false; // Note: this option is not actually for "merging plugins", but if "true" it will *overwrite* all plugins with the base-schema's const mergePlugins = mergedOptions.options?.enableMergePlugins ?? false; const discriminatorKey = sch.get('discriminatorKey'); if (!!discriminatorKey && sch.path(discriminatorKey)) { sch.paths[discriminatorKey].options.$skipDiscriminatorCheck = true; } const compiledModel = from.discriminator(name, sch, { value: value ? value : name, mergeHooks, mergePlugins, }); return addModelToTypegoose(compiledModel, cl, { disableCaching: mergedOptions.options?.disableCaching, }); } exports.getDiscriminatorModelForClass = getDiscriminatorModelForClass; /** * Use this class if raw mongoose for a path is wanted * It is still recommended to use the typegoose classes directly * @see Using `Passthrough`, the paths created will also result as an `Schema` (since mongoose 6.0), see {@link https://github.com/Automattic/mongoose/issues/7181 Mongoose#7181} * @example * ```ts * class Dummy { * @prop({ type: () => new Passthrough({ somePath: String }) }) * public somepath: { somePath: string }; * } * * class Dummy { * @prop({ type: () => new Passthrough({ somePath: String }, true) }) * public somepath: { somePath: string }; * } * ``` */ class Passthrough { /** * Use this like `new mongoose.Schema()` * @param raw The Schema definition * @param direct Directly insert "raw", instead of using "type" (this will not apply any other inner options) */ constructor(raw, direct) { this.raw = raw; this.direct = direct ?? false; } } exports.Passthrough = Passthrough; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWdvb3NlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3R5cGVnb29zZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsYUFBYTtBQUNiLGdFQUFnQztBQXFEdkIsbUJBckRGLGtCQUFRLENBcURFO0FBcERqQiw0QkFBMEI7QUFDMUIsdURBQWlDO0FBQ2pDLDRDQVUwQjtBQUUxQixrSEFBa0g7QUFDbEgsMEJBQTBCO0FBQzFCLElBQUksT0FBTyxPQUFPLEtBQUssV0FBVyxJQUFJLENBQUMsSUFBQSx5QkFBaUIsRUFBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFBLHlCQUFpQixFQUFDLGtCQUFRLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQztJQUNwSCwyQkFBMkI7SUFDM0IsMEJBQTBCO0lBQzFCLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQyxrQkFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQzNDLE1BQU0sSUFBSSxLQUFLLENBQUMsMkRBQTJELGtCQUFRLENBQUMsT0FBTyxVQUFVLENBQUMsQ0FBQztJQUN6RyxDQUFDO0lBRUQsMEJBQTBCO0lBQzFCLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ25ELE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztJQUMxRixDQUFDO0FBQ0gsQ0FBQztBQUVELG1EQUE2RDtBQXVCMUMsaUdBdkJBLGdDQUFnQixPQXVCQTtBQXRCbkMsb0RBQXFEO0FBQ3JELDBDQUF1RDtBQUN2RCw4Q0FBaUQ7QUFDakQsK0NBQXVDO0FBQ3ZDLDZDQUF1QztBQVl2Qyw4Q0FBb0k7QUFFcEksSUFBQSx3QkFBUSxHQUFFLENBQUMsQ0FBQyx5RkFBeUY7QUFLckcsNkNBQXVEO0FBQTlDLDBHQUFBLFdBQVcsT0FBQTtBQUFFLHdHQUFBLFNBQVMsT0FBQTtBQUMvQixpREFBdUI7QUFDdkIsa0RBQXdCO0FBQ3hCLG1EQUF5QjtBQUN6QixvREFBMEI7QUFDMUIsMERBQWdDO0FBQ2hDLHlEQUErQjtBQUMvQix3REFBOEI7QUFDOUIsdURBQTZCO0FBQzdCLDJFQUFtRDtBQUNuRCxvRUFBNEM7QUFDNUMseURBQWlDO0FBR2pDLDBDQUFxRDtBQUE1QyxpR0FBQSxRQUFRLE9BQUE7QUFBRSxnR0FBQSxPQUFPLE9BQUE7QUFDMUIsa0RBQTBEO0FBQWpELHFHQUFBLFFBQVEsT0FBQTtBQUFFLHFHQUFBLFFBQVEsT0FBQTtBQUUzQjs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBZ0UsRUFBSyxFQUFFLE9BQXVCO0lBQzVILElBQUEsd0JBQWdCLEVBQUMsRUFBRSxDQUFDLENBQUM7SUFDckIsTUFBTSxVQUFVLEdBQUcsT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM5RCxNQUFNLGVBQWUsR0FBRyxJQUFBLCtCQUF1QixFQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMscUdBQXFHO0lBRWxLLE1BQU0sYUFBYSxHQUFHLElBQUEsNkJBQXFCLEVBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVELE1BQU0sSUFBSSxHQUFHLElBQUEsZUFBTyxFQUFDLEVBQUUsRUFBRSxlQUFlLENBQUMsQ0FBQztJQUUxQyxJQUFJLElBQUEsd0JBQWdCLEVBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUMsSUFBSSxhQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDaEYsT0FBTyxhQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBcUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQ1gsYUFBYSxFQUFFLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDO1FBQy9FLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQztRQUMzRSxrQkFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQVEsQ0FBQyxDQUFDO0lBRWhDLE1BQU0sYUFBYSxHQUF3QixPQUFPLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztJQUV6RixPQUFPLG1CQUFtQixDQUFrQixhQUFhLEVBQUUsRUFBRSxFQUFFO1FBQzdELGdCQUFnQixFQUFFLGFBQWEsRUFBRSxnQkFBZ0I7UUFDakQsa0JBQWtCLEVBQUUsYUFBYSxFQUFFLGtCQUFrQjtRQUNyRCxjQUFjLEVBQUUsYUFBYSxDQUFDLE9BQU8sRUFBRSxjQUFjO0tBQ3RELENBQUMsQ0FBQztBQUNMLENBQUM7QUF4QkQsNENBd0JDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBZ0Isa0JBQWtCLENBQ2hDLEdBQVc7SUFFWCxJQUFBLGlCQUFTLEVBQUMsT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksMEJBQWlCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3RGLElBQUEsaUJBQVMsRUFBQyxJQUFBLDhCQUFzQixHQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSwyQkFBa0IsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7SUFFeEYsT0FBTyxhQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBUSxDQUFDO0FBQ2hDLENBQUM7QUFQRCxnREFPQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsU0FBZ0IsV0FBVyxDQUN6QixFQUFLLEVBQ0wsT0FBdUI7SUFFdkIsSUFBQSx3QkFBZ0IsRUFBQyxFQUFFLENBQUMsQ0FBQztJQUVyQixNQUFNLGVBQWUsR0FBRyxJQUFBLCtCQUF1QixFQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pELG9CQUFNLENBQUMsS0FBSyxDQUFDLDZCQUE2QixFQUFFLElBQUEsZUFBTyxFQUFDLEVBQUUsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO0lBRTFFLCtFQUErRTtJQUMvRSxNQUFNLGFBQWEsR0FBRyxJQUFBLDZCQUFxQixFQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV6RCxJQUFJLEdBQUcsR0FBK0QsU0FBUyxDQUFDO0lBQ2hGLHlCQUF5QjtJQUN6QixJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxXQUFXLENBQUM7SUFDakUsNEVBQTRFO0lBQzVFLE1BQU0sYUFBYSxHQUFzRCxFQUFFLENBQUM7SUFDNUUseUdBQXlHO0lBQ3pHLElBQUksWUFBWSxHQUF3QixFQUFFLENBQUM7SUFFM0MsMEhBQTBIO0lBQzFILENBQUM7UUFDQyw4SEFBOEg7UUFDOUgsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLDZCQUFxQixFQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDbEUsaUJBQWlCLENBQUMsWUFBWSxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELGlEQUFpRDtJQUNqRCxPQUFPLFVBQVUsRUFBRSxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDckMscUZBQXFGO1FBQ3JGLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUVsRCwwR0FBMEc7UUFDMUcsWUFBWSxHQUFHLEVBQUUsR0FBRyxZQUFZLEVBQUUsQ0FBQztRQUVuQyxDQUFDO1lBQ0MsNEdBQTRHO1lBQzVHLE1BQU0sSUFBSSxHQUFrQixPQUFPLENBQUMsY0FBYyxDQUFDLHlCQUFhLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUVqRyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUVELGtCQUFrQjtRQUNsQixVQUFVLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsV0FBVyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCw0S0FBNEs7SUFDNUssS0FBSyxNQUFNLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ3hELGdCQUFnQjtRQUNoQixHQUFHLEdBQUcsSUFBQSxxQkFBWSxFQUFDLFdBQVcsRUFBRSxHQUFJLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDdkYsQ0FBQztJQUVELDhCQUE4QjtJQUM5QixHQUFHLEdBQUcsSUFBQSxxQkFBWSxFQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztJQUVsRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUF4REQsa0NBd0RDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsaUJBQWlCLENBQUMsWUFBaUMsRUFBRSxZQUEyQjtJQUN2RiwyRUFBMkU7SUFDM0UsSUFBSSxZQUFZLENBQUMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLENBQUM7UUFDOUMsWUFBWSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7SUFDcEMsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FDakMsS0FBMEIsRUFDMUIsRUFBSyxFQUNMLE9BQXNHO0lBRXRHLE1BQU0sYUFBYSxHQUFHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLElBQUksT0FBTyxFQUFFLGtCQUFrQixFQUFFLElBQUksRUFBRSxLQUFLLElBQUksa0JBQVEsQ0FBQyxLQUFLLENBQUM7SUFFckgsSUFBQSxpQkFBUyxFQUFDLEtBQUssQ0FBQyxTQUFTLFlBQVksYUFBYSxFQUFFLElBQUksMkJBQWtCLENBQUMsS0FBSyxFQUFFLDJCQUEyQixDQUFDLENBQUMsQ0FBQztJQUNoSCxJQUFBLHdCQUFnQixFQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRXJCLHNFQUFzRTtJQUN0RSxJQUFJLENBQUMsSUFBQSx3QkFBZ0IsRUFBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUMvQyxvQkFBTSxDQUFDLElBQUksQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1FBRXZELE9BQU8sS0FBeUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztJQUU3QixJQUFBLGlCQUFTLEVBQ1AsQ0FBQyxhQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUNqQixJQUFJLDZDQUFvQyxDQUN0QyxxQkFBcUIsRUFDckIsQ0FBQyxFQUNELDJDQUEyQyxJQUFJLDJEQUEyRCxDQUMzRyxDQUNGLENBQUM7SUFFRixJQUFJLG1CQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDM0Isb0JBQU0sQ0FBQyxJQUFJLENBQUMsb0RBQW9ELEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUVELGFBQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3hCLG1CQUFZLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUUzQixPQUFPLGFBQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFxQyxDQUFDO0FBQzlELENBQUM7QUFwQ0Qsa0RBb0NDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQWdCLFdBQVcsQ0FBQyxJQUFZO0lBQ3RDLElBQUEsaUJBQVMsRUFBQyxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSwwQkFBaUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDekYsSUFBQSxpQkFBUyxFQUFDLElBQUEsOEJBQXNCLEdBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLDJCQUFrQixDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQztJQUUxRixvQkFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUUxQyxNQUFNLEtBQUssR0FBRyxhQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRS9CLElBQUksQ0FBQyxJQUFBLHlCQUFpQixFQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDOUIsS0FBSyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELGFBQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEIsbUJBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQWRELGtDQWNDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQWdCLG9CQUFvQixDQUFxQyxFQUFLO0lBQzVFLElBQUEsd0JBQWdCLEVBQUMsRUFBRSxDQUFDLENBQUM7SUFDckIsSUFBQSxpQkFBUyxFQUFDLElBQUEsOEJBQXNCLEdBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLDJCQUFrQixDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQztJQUUxRixJQUFJLElBQUksR0FBRyxJQUFBLGVBQU8sRUFBQyxFQUFFLENBQUMsQ0FBQztJQUV2QixJQUFJLENBQUMsYUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3RCLG9CQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsSUFBSSx3REFBd0QsQ0FBQyxDQUFDO1FBQ3JGLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztRQUVsQix5R0FBeUc7UUFDekcsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxJQUFJLG1CQUFZLEVBQUUsQ0FBQztZQUNoRCxJQUFJLFdBQVcsS0FBSyxFQUFFLEVBQUUsQ0FBQztnQkFDdkIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsa0RBQWtELElBQUksdUJBQXVCLEtBQUssSUFBSSxDQUFDLENBQUM7Z0JBQ3JHLElBQUksR0FBRyxLQUFLLENBQUM7Z0JBQ2IsS0FBSyxHQUFHLElBQUksQ0FBQztZQUNmLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsb0JBQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLElBQUksbUJBQW1CLENBQUMsQ0FBQztZQUUvRCxPQUFPO1FBQ1QsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMzQixDQUFDO0FBM0JELG9EQTJCQztBQTBHRCxTQUFnQiw2QkFBNkIsQ0FDM0MsSUFBd0MsRUFDeEMsRUFBSyxFQUNMLGdCQUF5QyxFQUN6QyxPQUF1QjtJQUV2QixJQUFBLGlCQUFTLEVBQUMsSUFBQSxvQkFBTyxFQUFDLElBQUksQ0FBQyxFQUFFLElBQUksMkJBQWtCLENBQUMsSUFBSSxFQUFFLG9DQUFvQyxDQUFDLENBQUMsQ0FBQztJQUM3RixJQUFBLHdCQUFnQixFQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRXJCLE1BQU0sS0FBSyxHQUFHLE9BQU8sZ0JBQWdCLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2xGLE1BQU0sVUFBVSxHQUFHLE9BQU8sZ0JBQWdCLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUN4SCxNQUFNLGVBQWUsR0FBRyxJQUFBLCtCQUF1QixFQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMscUdBQXFHO0lBQ2xLLE1BQU0sYUFBYSxHQUFHLElBQUEsNkJBQXFCLEVBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVELE1BQU0sSUFBSSxHQUFHLElBQUEsZUFBTyxFQUFDLEVBQUUsRUFBRSxlQUFlLENBQUMsQ0FBQztJQUUxQyxJQUFJLElBQUEsd0JBQWdCLEVBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUMsSUFBSSxhQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDaEYsT0FBTyxhQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBcUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsSUFBSSxhQUFhLENBQUMsa0JBQWtCLElBQUksYUFBYSxDQUFDLGtCQUFrQixLQUFLLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNyRixJQUFBLCtCQUF1QixFQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBQSxlQUFPLEVBQUMsRUFBRSxDQUFDLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBQ0QsSUFBSSxhQUFhLENBQUMsZ0JBQWdCLElBQUksYUFBYSxDQUFDLGdCQUFnQixLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuRixJQUFBLCtCQUF1QixFQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBQSxlQUFPLEVBQUMsRUFBRSxDQUFDLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQsTUFBTSxHQUFHLEdBQXlCLFdBQVcsQ0FBQyxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFFakUsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxnQkFBZ0IsSUFBSSxLQUFLLENBQUM7SUFDcEUsZ0lBQWdJO0lBQ2hJLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQyxPQUFPLEVBQUUsa0JBQWtCLElBQUksS0FBSyxDQUFDO0lBRXhFLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBRXJELElBQUksQ0FBQyxDQUFDLGdCQUFnQixJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO1FBQ3BELEdBQUcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQVMsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDO0lBQzlFLENBQUM7SUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUU7UUFDbEQsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO1FBQzNCLFVBQVU7UUFDVixZQUFZO0tBQ2IsQ0FBQyxDQUFDO0lBRUgsT0FBTyxtQkFBbUIsQ0FBa0IsYUFBYSxFQUFFLEVBQUUsRUFBRTtRQUM3RCxjQUFjLEVBQUUsYUFBYSxDQUFDLE9BQU8sRUFBRSxjQUFjO0tBQ3RELENBQUMsQ0FBQztBQUNMLENBQUM7QUEvQ0Qsc0VBK0NDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFDSCxNQUFhLFdBQVc7SUFLdEI7Ozs7T0FJRztJQUNILFlBQVksR0FBUSxFQUFFLE1BQWdCO1FBQ3BDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2YsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDO0lBQ2hDLENBQUM7Q0FDRjtBQWRELGtDQWNDIn0=