UNPKG

@ngtools/webpack

Version:

Webpack plugin that AoT compiles your Angular components and modules.

567 lines • 94.7 kB
"use strict"; /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AngularWebpackPlugin = void 0; const assert_1 = require("assert"); const ts = __importStar(require("typescript")); const ngcc_processor_1 = require("../ngcc_processor"); const paths_plugin_1 = require("../paths-plugin"); const resource_loader_1 = require("../resource_loader"); const cache_1 = require("./cache"); const diagnostics_1 = require("./diagnostics"); const host_1 = require("./host"); const paths_1 = require("./paths"); const symbol_1 = require("./symbol"); const system_1 = require("./system"); const transformation_1 = require("./transformation"); /** * The threshold used to determine whether Angular file diagnostics should optimize for full programs * or single files. If the number of affected files for a build is more than the threshold, full * program optimization will be used. */ const DIAGNOSTICS_AFFECTED_THRESHOLD = 1; function initializeNgccProcessor(compiler, tsconfig, compilerNgccModule) { var _a, _b, _c; const { inputFileSystem, options: webpackOptions } = compiler; const mainFields = (_c = (_b = (_a = webpackOptions.resolve) === null || _a === void 0 ? void 0 : _a.mainFields) === null || _b === void 0 ? void 0 : _b.flat()) !== null && _c !== void 0 ? _c : []; const errors = []; const warnings = []; const resolver = compiler.resolverFactory.get('normal', { // Caching must be disabled because it causes the resolver to become async after a rebuild cache: false, extensions: ['.json'], useSyncFileSystemCalls: true, }); // The compilerNgccModule field is guaranteed to be defined during a compilation // due to the `beforeCompile` hook. Usage of this property accessor prior to the // hook execution is an implementation error. assert_1.strict.ok(compilerNgccModule, `'@angular/compiler-cli/ngcc' used prior to Webpack compilation.`); const processor = new ngcc_processor_1.NgccProcessor(compilerNgccModule, mainFields, warnings, errors, compiler.context, tsconfig, inputFileSystem, resolver); return { processor, errors, warnings }; } const PLUGIN_NAME = 'angular-compiler'; const compilationFileEmitters = new WeakMap(); class AngularWebpackPlugin { constructor(options = {}) { this.fileDependencies = new Map(); this.requiredFilesToEmit = new Set(); this.requiredFilesToEmitCache = new Map(); this.fileEmitHistory = new Map(); this.pluginOptions = { emitClassMetadata: false, emitNgModuleScope: false, jitMode: false, fileReplacements: {}, substitutions: {}, directTemplateLoading: true, tsconfig: 'tsconfig.json', ...options, }; } get compilerCli() { // The compilerCliModule field is guaranteed to be defined during a compilation // due to the `beforeCompile` hook. Usage of this property accessor prior to the // hook execution is an implementation error. assert_1.strict.ok(this.compilerCliModule, `'@angular/compiler-cli' used prior to Webpack compilation.`); return this.compilerCliModule; } get options() { return this.pluginOptions; } apply(compiler) { const { NormalModuleReplacementPlugin, WebpackError, util } = compiler.webpack; this.webpackCreateHash = util.createHash; // Setup file replacements with webpack for (const [key, value] of Object.entries(this.pluginOptions.fileReplacements)) { new NormalModuleReplacementPlugin(new RegExp('^' + key.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&') + '$'), value).apply(compiler); } // Set resolver options const pathsPlugin = new paths_plugin_1.TypeScriptPathsPlugin(); compiler.hooks.afterResolvers.tap(PLUGIN_NAME, (compiler) => { // When Ivy is enabled we need to add the fields added by NGCC // to take precedence over the provided mainFields. // NGCC adds fields in package.json suffixed with '_ivy_ngcc' // Example: module -> module__ivy_ngcc compiler.resolverFactory.hooks.resolveOptions .for('normal') .tap(PLUGIN_NAME, (resolveOptions) => { var _a, _b; const originalMainFields = resolveOptions.mainFields; const ivyMainFields = (_a = originalMainFields === null || originalMainFields === void 0 ? void 0 : originalMainFields.flat().map((f) => `${f}_ivy_ngcc`)) !== null && _a !== void 0 ? _a : []; (_b = resolveOptions.plugins) !== null && _b !== void 0 ? _b : (resolveOptions.plugins = []); resolveOptions.plugins.push(pathsPlugin); // https://github.com/webpack/webpack/issues/11635#issuecomment-707016779 return util.cleverMerge(resolveOptions, { mainFields: [...ivyMainFields, '...'] }); }); }); // Load the compiler-cli if not already available compiler.hooks.beforeCompile.tapPromise(PLUGIN_NAME, () => this.initializeCompilerCli()); const compilationState = { pathsPlugin }; compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => { try { this.setupCompilation(compilation, compilationState); } catch (error) { (0, diagnostics_1.addError)(compilation, `Failed to initialize Angular compilation - ${error instanceof Error ? error.message : error}`); } }); } setupCompilation(compilation, state) { const compiler = compilation.compiler; // Register plugin to ensure deterministic emit order in multi-plugin usage const emitRegistration = this.registerWithCompilation(compilation); this.watchMode = compiler.watchMode; // Initialize webpack cache if (!this.webpackCache && compilation.options.cache) { this.webpackCache = compilation.getCache(PLUGIN_NAME); } // Initialize the resource loader if not already setup if (!state.resourceLoader) { state.resourceLoader = new resource_loader_1.WebpackResourceLoader(this.watchMode); } // Initialize and process eager ngcc if not already setup if (!state.ngccProcessor) { const { processor, errors, warnings } = initializeNgccProcessor(compiler, this.pluginOptions.tsconfig, this.compilerNgccModule); processor.process(); warnings.forEach((warning) => (0, diagnostics_1.addWarning)(compilation, warning)); errors.forEach((error) => (0, diagnostics_1.addError)(compilation, error)); state.ngccProcessor = processor; } // Setup and read TypeScript and Angular compiler configuration const { compilerOptions, rootNames, errors } = this.loadConfiguration(); // Create diagnostics reporter and report configuration file errors const diagnosticsReporter = (0, diagnostics_1.createDiagnosticsReporter)(compilation, (diagnostic) => this.compilerCli.formatDiagnostics([diagnostic])); diagnosticsReporter(errors); // Update TypeScript path mapping plugin with new configuration state.pathsPlugin.update(compilerOptions); // Create a Webpack-based TypeScript compiler host const system = (0, system_1.createWebpackSystem)( // Webpack lacks an InputFileSytem type definition with sync functions compiler.inputFileSystem, (0, paths_1.normalizePath)(compiler.context)); const host = ts.createIncrementalCompilerHost(compilerOptions, system); // Setup source file caching and reuse cache from previous compilation if present let cache = this.sourceFileCache; let changedFiles; if (cache) { changedFiles = new Set(); for (const changedFile of [...compiler.modifiedFiles, ...compiler.removedFiles]) { const normalizedChangedFile = (0, paths_1.normalizePath)(changedFile); // Invalidate file dependencies this.fileDependencies.delete(normalizedChangedFile); // Invalidate existing cache cache.invalidate(normalizedChangedFile); changedFiles.add(normalizedChangedFile); } } else { // Initialize a new cache cache = new cache_1.SourceFileCache(); // Only store cache if in watch mode if (this.watchMode) { this.sourceFileCache = cache; } } (0, host_1.augmentHostWithCaching)(host, cache); const moduleResolutionCache = ts.createModuleResolutionCache(host.getCurrentDirectory(), host.getCanonicalFileName.bind(host), compilerOptions); // Setup source file dependency collection (0, host_1.augmentHostWithDependencyCollection)(host, this.fileDependencies, moduleResolutionCache); // Setup on demand ngcc (0, host_1.augmentHostWithNgcc)(host, state.ngccProcessor, moduleResolutionCache); // Setup resource loading state.resourceLoader.update(compilation, changedFiles); (0, host_1.augmentHostWithResources)(host, state.resourceLoader, { directTemplateLoading: this.pluginOptions.directTemplateLoading, inlineStyleFileExtension: this.pluginOptions.inlineStyleFileExtension, }); // Setup source file adjustment options (0, host_1.augmentHostWithReplacements)(host, this.pluginOptions.fileReplacements, moduleResolutionCache); (0, host_1.augmentHostWithSubstitutions)(host, this.pluginOptions.substitutions); // Create the file emitter used by the webpack loader const { fileEmitter, builder, internalFiles } = this.pluginOptions.jitMode ? this.updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter) : this.updateAotProgram(compilerOptions, rootNames, host, diagnosticsReporter, state.resourceLoader); // Set of files used during the unused TypeScript file analysis const currentUnused = new Set(); for (const sourceFile of builder.getSourceFiles()) { if (internalFiles === null || internalFiles === void 0 ? void 0 : internalFiles.has(sourceFile)) { continue; } // Ensure all program files are considered part of the compilation and will be watched. // Webpack does not normalize paths. Therefore, we need to normalize the path with FS seperators. compilation.fileDependencies.add((0, paths_1.externalizePath)(sourceFile.fileName)); // Add all non-declaration files to the initial set of unused files. The set will be // analyzed and pruned after all Webpack modules are finished building. if (!sourceFile.isDeclarationFile) { currentUnused.add((0, paths_1.normalizePath)(sourceFile.fileName)); } } compilation.hooks.finishModules.tapPromise(PLUGIN_NAME, async (modules) => { var _a, _b; // Rebuild any remaining AOT required modules await this.rebuildRequiredFiles(modules, compilation, fileEmitter); // Clear out the Webpack compilation to avoid an extra retaining reference (_a = state.resourceLoader) === null || _a === void 0 ? void 0 : _a.clearParentCompilation(); // Analyze program for unused files if (compilation.errors.length > 0) { return; } for (const webpackModule of modules) { const resource = webpackModule.resource; if (resource) { this.markResourceUsed((0, paths_1.normalizePath)(resource), currentUnused); } } for (const unused of currentUnused) { if ((_b = state.previousUnused) === null || _b === void 0 ? void 0 : _b.has(unused)) { continue; } (0, diagnostics_1.addWarning)(compilation, `${unused} is part of the TypeScript compilation but it's unused.\n` + `Add only entry points to the 'files' or 'include' properties in your tsconfig.`); } state.previousUnused = currentUnused; }); // Store file emitter for loader usage emitRegistration.update(fileEmitter); } registerWithCompilation(compilation) { let fileEmitters = compilationFileEmitters.get(compilation); if (!fileEmitters) { fileEmitters = new symbol_1.FileEmitterCollection(); compilationFileEmitters.set(compilation, fileEmitters); compilation.compiler.webpack.NormalModule.getCompilationHooks(compilation).loader.tap(PLUGIN_NAME, (loaderContext) => { loaderContext[symbol_1.AngularPluginSymbol] = fileEmitters; }); } const emitRegistration = fileEmitters.register(); return emitRegistration; } markResourceUsed(normalizedResourcePath, currentUnused) { if (!currentUnused.has(normalizedResourcePath)) { return; } currentUnused.delete(normalizedResourcePath); const dependencies = this.fileDependencies.get(normalizedResourcePath); if (!dependencies) { return; } for (const dependency of dependencies) { this.markResourceUsed((0, paths_1.normalizePath)(dependency), currentUnused); } } async rebuildRequiredFiles(modules, compilation, fileEmitter) { if (this.requiredFilesToEmit.size === 0) { return; } const filesToRebuild = new Set(); for (const requiredFile of this.requiredFilesToEmit) { const history = await this.getFileEmitHistory(requiredFile); if (history) { const emitResult = await fileEmitter(requiredFile); if ((emitResult === null || emitResult === void 0 ? void 0 : emitResult.content) === undefined || history.length !== emitResult.content.length || emitResult.hash === undefined || Buffer.compare(history.hash, emitResult.hash) !== 0) { // New emit result is different so rebuild using new emit result this.requiredFilesToEmitCache.set(requiredFile, emitResult); filesToRebuild.add(requiredFile); } } else { // No emit history so rebuild filesToRebuild.add(requiredFile); } } if (filesToRebuild.size > 0) { const rebuild = (webpackModule) => new Promise((resolve) => compilation.rebuildModule(webpackModule, () => resolve())); const modulesToRebuild = []; for (const webpackModule of modules) { const resource = webpackModule.resource; if (resource && filesToRebuild.has((0, paths_1.normalizePath)(resource))) { modulesToRebuild.push(webpackModule); } } await Promise.all(modulesToRebuild.map((webpackModule) => rebuild(webpackModule))); } this.requiredFilesToEmit.clear(); this.requiredFilesToEmitCache.clear(); } loadConfiguration() { const { options: compilerOptions, rootNames, errors, } = this.compilerCli.readConfiguration(this.pluginOptions.tsconfig, this.pluginOptions.compilerOptions); compilerOptions.noEmitOnError = false; compilerOptions.suppressOutputPathCheck = true; compilerOptions.outDir = undefined; compilerOptions.inlineSources = compilerOptions.sourceMap; compilerOptions.inlineSourceMap = false; compilerOptions.mapRoot = undefined; compilerOptions.sourceRoot = undefined; compilerOptions.allowEmptyCodegenFiles = false; compilerOptions.annotationsAs = 'decorators'; compilerOptions.enableResourceInlining = false; return { compilerOptions, rootNames, errors }; } updateAotProgram(compilerOptions, rootNames, host, diagnosticsReporter, resourceLoader) { // Create the Angular specific program that contains the Angular compiler const angularProgram = new this.compilerCli.NgtscProgram(rootNames, compilerOptions, host, this.ngtscNextProgram); const angularCompiler = angularProgram.compiler; // The `ignoreForEmit` return value can be safely ignored when emitting. Only files // that will be bundled (requested by Webpack) will be emitted. Combined with TypeScript's // eliding of type only imports, this will cause type only files to be automatically ignored. // Internal Angular type check files are also not resolvable by the bundler. Even if they // were somehow errantly imported, the bundler would error before an emit was attempted. // Diagnostics are still collected for all files which requires using `ignoreForDiagnostics`. const { ignoreForDiagnostics, ignoreForEmit } = angularCompiler; // SourceFile versions are required for builder programs. // The wrapped host inside NgtscProgram adds additional files that will not have versions. const typeScriptProgram = angularProgram.getTsProgram(); (0, host_1.augmentProgramWithVersioning)(typeScriptProgram); let builder; if (this.watchMode) { builder = this.builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(typeScriptProgram, host, this.builder); this.ngtscNextProgram = angularProgram; } else { // When not in watch mode, the startup cost of the incremental analysis can be avoided by // using an abstract builder that only wraps a TypeScript program. builder = ts.createAbstractBuilder(typeScriptProgram, host); } // Update semantic diagnostics cache const affectedFiles = new Set(); // Analyze affected files when in watch mode for incremental type checking if ('getSemanticDiagnosticsOfNextAffectedFile' in builder) { // eslint-disable-next-line no-constant-condition while (true) { const result = builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, (sourceFile) => { // If the affected file is a TTC shim, add the shim's original source file. // This ensures that changes that affect TTC are typechecked even when the changes // are otherwise unrelated from a TS perspective and do not result in Ivy codegen changes. // For example, changing @Input property types of a directive used in another component's // template. if (ignoreForDiagnostics.has(sourceFile) && sourceFile.fileName.endsWith('.ngtypecheck.ts')) { // This file name conversion relies on internal compiler logic and should be converted // to an official method when available. 15 is length of `.ngtypecheck.ts` const originalFilename = sourceFile.fileName.slice(0, -15) + '.ts'; const originalSourceFile = builder.getSourceFile(originalFilename); if (originalSourceFile) { affectedFiles.add(originalSourceFile); } return true; } return false; }); if (!result) { break; } affectedFiles.add(result.affected); } } // Collect program level diagnostics const diagnostics = [ ...angularCompiler.getOptionDiagnostics(), ...builder.getOptionsDiagnostics(), ...builder.getGlobalDiagnostics(), ]; diagnosticsReporter(diagnostics); // Collect source file specific diagnostics for (const sourceFile of builder.getSourceFiles()) { if (!ignoreForDiagnostics.has(sourceFile)) { diagnosticsReporter(builder.getSyntacticDiagnostics(sourceFile)); diagnosticsReporter(builder.getSemanticDiagnostics(sourceFile)); } } const transformers = (0, transformation_1.createAotTransformers)(builder, this.pluginOptions); const getDependencies = (sourceFile) => { const dependencies = []; for (const resourcePath of angularCompiler.getResourceDependencies(sourceFile)) { dependencies.push(resourcePath, // Retrieve all dependencies of the resource (stylesheet imports, etc.) ...resourceLoader.getResourceDependencies(resourcePath)); } return dependencies; }; // Required to support asynchronous resource loading // Must be done before creating transformers or getting template diagnostics const pendingAnalysis = angularCompiler .analyzeAsync() .then(() => { var _a; this.requiredFilesToEmit.clear(); for (const sourceFile of builder.getSourceFiles()) { if (sourceFile.isDeclarationFile) { continue; } // Collect sources that are required to be emitted if (!ignoreForEmit.has(sourceFile) && !angularCompiler.incrementalCompilation.safeToSkipEmit(sourceFile)) { this.requiredFilesToEmit.add((0, paths_1.normalizePath)(sourceFile.fileName)); // If required to emit, diagnostics may have also changed if (!ignoreForDiagnostics.has(sourceFile)) { affectedFiles.add(sourceFile); } } else if (this.sourceFileCache && !affectedFiles.has(sourceFile) && !ignoreForDiagnostics.has(sourceFile)) { // Use cached Angular diagnostics for unchanged and unaffected files const angularDiagnostics = this.sourceFileCache.getAngularDiagnostics(sourceFile); if (angularDiagnostics) { diagnosticsReporter(angularDiagnostics); } } } // Collect new Angular diagnostics for files affected by changes const OptimizeFor = this.compilerCli.OptimizeFor; const optimizeDiagnosticsFor = affectedFiles.size <= DIAGNOSTICS_AFFECTED_THRESHOLD ? OptimizeFor.SingleFile : OptimizeFor.WholeProgram; for (const affectedFile of affectedFiles) { const angularDiagnostics = angularCompiler.getDiagnosticsForFile(affectedFile, optimizeDiagnosticsFor); diagnosticsReporter(angularDiagnostics); (_a = this.sourceFileCache) === null || _a === void 0 ? void 0 : _a.updateAngularDiagnostics(affectedFile, angularDiagnostics); } return { emitter: this.createFileEmitter(builder, (0, transformation_1.mergeTransformers)(angularCompiler.prepareEmit().transformers, transformers), getDependencies, (sourceFile) => { this.requiredFilesToEmit.delete((0, paths_1.normalizePath)(sourceFile.fileName)); angularCompiler.incrementalCompilation.recordSuccessfulEmit(sourceFile); }), }; }) .catch((err) => ({ errorMessage: err instanceof Error ? err.message : `${err}` })); const analyzingFileEmitter = async (file) => { const analysis = await pendingAnalysis; if ('errorMessage' in analysis) { throw new Error(analysis.errorMessage); } return analysis.emitter(file); }; return { fileEmitter: analyzingFileEmitter, builder, internalFiles: ignoreForEmit, }; } updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter) { let builder; if (this.watchMode) { builder = this.builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(rootNames, compilerOptions, host, this.builder); } else { // When not in watch mode, the startup cost of the incremental analysis can be avoided by // using an abstract builder that only wraps a TypeScript program. builder = ts.createAbstractBuilder(rootNames, compilerOptions, host); } const diagnostics = [ ...builder.getOptionsDiagnostics(), ...builder.getGlobalDiagnostics(), ...builder.getSyntacticDiagnostics(), // Gather incremental semantic diagnostics ...builder.getSemanticDiagnostics(), ]; diagnosticsReporter(diagnostics); const transformers = (0, transformation_1.createJitTransformers)(builder, this.compilerCli, this.pluginOptions); return { fileEmitter: this.createFileEmitter(builder, transformers, () => []), builder, internalFiles: undefined, }; } createFileEmitter(program, transformers = {}, getExtraDependencies, onAfterEmit) { return async (file) => { const filePath = (0, paths_1.normalizePath)(file); if (this.requiredFilesToEmitCache.has(filePath)) { return this.requiredFilesToEmitCache.get(filePath); } const sourceFile = program.getSourceFile(filePath); if (!sourceFile) { return undefined; } let content; let map; program.emit(sourceFile, (filename, data) => { if (filename.endsWith('.map')) { map = data; } else if (filename.endsWith('.js')) { content = data; } }, undefined, undefined, transformers); onAfterEmit === null || onAfterEmit === void 0 ? void 0 : onAfterEmit(sourceFile); // Capture emit history info for Angular rebuild analysis const hash = content ? (await this.addFileEmitHistory(filePath, content)).hash : undefined; const dependencies = [ ...(this.fileDependencies.get(filePath) || []), ...getExtraDependencies(sourceFile), ].map(paths_1.externalizePath); return { content, map, dependencies, hash }; }; } async initializeCompilerCli() { if (this.compilerCliModule) { return; } // This uses a dynamic import to load `@angular/compiler-cli` which may be ESM. // CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript // will currently, unconditionally downlevel dynamic import into a require call. // require calls cannot load ESM code and will result in a runtime error. To workaround // this, a Function constructor is used to prevent TypeScript from changing the dynamic import. // Once TypeScript provides support for keeping the dynamic import this workaround can // be dropped. this.compilerCliModule = await new Function(`return import('@angular/compiler-cli');`)(); this.compilerNgccModule = await new Function(`return import('@angular/compiler-cli/ngcc');`)(); } async addFileEmitHistory(filePath, content) { assert_1.strict.ok(this.webpackCreateHash, 'File emitter is used prior to Webpack compilation'); const historyData = { length: content.length, hash: this.webpackCreateHash('xxhash64').update(content).digest(), }; if (this.webpackCache) { const history = await this.getFileEmitHistory(filePath); if (!history || Buffer.compare(history.hash, historyData.hash) !== 0) { // Hash doesn't match or item doesn't exist. await this.webpackCache.storePromise(filePath, null, historyData); } } else if (this.watchMode) { // The in memory file emit history is only required during watch mode. this.fileEmitHistory.set(filePath, historyData); } return historyData; } async getFileEmitHistory(filePath) { return this.webpackCache ? this.webpackCache.getPromise(filePath, null) : this.fileEmitHistory.get(filePath); } } exports.AngularWebpackPlugin = AngularWebpackPlugin; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbmd0b29scy93ZWJwYWNrL3NyYy9pdnkvcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0gsbUNBQTBDO0FBQzFDLCtDQUFpQztBQUVqQyxzREFBa0Q7QUFDbEQsa0RBQXdEO0FBQ3hELHdEQUEyRDtBQUMzRCxtQ0FBMEM7QUFDMUMsK0NBS3VCO0FBQ3ZCLGlDQVFnQjtBQUNoQixtQ0FBeUQ7QUFDekQscUNBQW1HO0FBQ25HLHFDQUFvRTtBQUNwRSxxREFBbUc7QUFFbkc7Ozs7R0FJRztBQUNILE1BQU0sOEJBQThCLEdBQUcsQ0FBQyxDQUFDO0FBd0J6QyxTQUFTLHVCQUF1QixDQUM5QixRQUFrQixFQUNsQixRQUFnQixFQUNoQixrQkFBMkU7O0lBRTNFLE1BQU0sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxHQUFHLFFBQVEsQ0FBQztJQUM5RCxNQUFNLFVBQVUsR0FBRyxNQUFBLE1BQUEsTUFBQSxjQUFjLENBQUMsT0FBTywwQ0FBRSxVQUFVLDBDQUFFLElBQUksRUFBRSxtQ0FBSSxFQUFFLENBQUM7SUFFcEUsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO0lBQzVCLE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUM5QixNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUU7UUFDdEQsMEZBQTBGO1FBQzFGLEtBQUssRUFBRSxLQUFLO1FBQ1osVUFBVSxFQUFFLENBQUMsT0FBTyxDQUFDO1FBQ3JCLHNCQUFzQixFQUFFLElBQUk7S0FDN0IsQ0FBQyxDQUFDO0lBRUgsZ0ZBQWdGO0lBQ2hGLGdGQUFnRjtJQUNoRiw2Q0FBNkM7SUFDN0MsZUFBTSxDQUFDLEVBQUUsQ0FBQyxrQkFB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