UNPKG

oidc-client

Version:

OpenID Connect (OIDC) & OAuth2 client library

663 lines 97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @license * Copyright Google Inc. 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 */ const core_1 = require("@angular-devkit/core"); const schematics_1 = require("@angular-devkit/schematics"); const tasks_1 = require("@angular-devkit/schematics/tasks"); const dependencies_1 = require("../../utility/dependencies"); const json_utils_1 = require("../../utility/json-utils"); const latest_versions_1 = require("../../utility/latest-versions"); const defaults = { appRoot: 'src', index: 'index.html', main: 'main.ts', polyfills: 'polyfills.ts', tsConfig: 'tsconfig.app.json', test: 'test.ts', outDir: 'dist/', karma: 'karma.conf.js', protractor: 'protractor.conf.js', testTsConfig: 'tsconfig.spec.json', serverOutDir: 'dist-server', serverMain: 'main.server.ts', serverTsConfig: 'tsconfig.server.json', }; function getConfigPath(tree) { let possiblePath = core_1.normalize('.angular-cli.json'); if (tree.exists(possiblePath)) { return possiblePath; } possiblePath = core_1.normalize('angular-cli.json'); if (tree.exists(possiblePath)) { return possiblePath; } throw new schematics_1.SchematicsException('Could not find configuration file'); } function migrateKarmaConfiguration(config) { return (host, context) => { context.logger.info(`Updating karma configuration`); try { const karmaPath = config && config.test && config.test.karma && config.test.karma.config ? config.test.karma.config : defaults.karma; const buffer = host.read(karmaPath); if (buffer !== null) { let content = buffer.toString(); // Replace the 1.0 files and preprocessor entries, with and without comma at the end. // If these remain, they will cause the `ng test` to fail. content = content.replace(`{ pattern: './src/test.ts', watched: false },`, ''); content = content.replace(`{ pattern: './src/test.ts', watched: false }`, ''); content = content.replace(`'./src/test.ts': ['@angular/cli'],`, ''); content = content.replace(`'./src/test.ts': ['@angular/cli']`, ''); content = content.replace(/angularCli[^}]*},?/, ''); // Replace 1.x plugin names. content = content.replace(/@angular\/cli/g, '@angular-devkit/build-angular'); // Replace code coverage output path. content = content.replace('reports', `dir: require('path').join(__dirname, 'coverage'), reports`); host.overwrite(karmaPath, content); } } catch (_a) { } return host; }; } function migrateConfiguration(oldConfig, logger) { return (host, context) => { const oldConfigPath = getConfigPath(host); const configPath = core_1.normalize('angular.json'); context.logger.info(`Updating configuration`); const config = { '$schema': './node_modules/@angular/cli/lib/config/schema.json', version: 1, newProjectRoot: 'projects', projects: extractProjectsConfig(oldConfig, host, logger), }; const defaultProject = extractDefaultProject(oldConfig); if (defaultProject !== null) { config.defaultProject = defaultProject; } const cliConfig = extractCliConfig(oldConfig); if (cliConfig !== null) { config.cli = cliConfig; } const schematicsConfig = extractSchematicsConfig(oldConfig); if (schematicsConfig !== null) { config.schematics = schematicsConfig; } const targetsConfig = extractTargetsConfig(oldConfig); if (targetsConfig !== null) { config.architect = targetsConfig; } context.logger.info(`Removing old config file (${oldConfigPath})`); host.delete(oldConfigPath); context.logger.info(`Writing config file (${configPath})`); host.create(configPath, JSON.stringify(config, null, 2)); return host; }; } function extractCliConfig(config) { const newConfig = {}; if (config.packageManager && config.packageManager !== 'default') { newConfig['packageManager'] = config.packageManager; } if (config.warnings) { if (config.warnings.versionMismatch !== undefined) { newConfig.warnings = Object.assign({}, (newConfig.warnings || {}), { versionMismatch: config.warnings.versionMismatch }); } if (config.warnings.typescriptMismatch !== undefined) { newConfig.warnings = Object.assign({}, (newConfig.warnings || {}), { typescriptMismatch: config.warnings.typescriptMismatch }); } } return Object.getOwnPropertyNames(newConfig).length == 0 ? null : newConfig; } function extractSchematicsConfig(config) { let collectionName = '@schematics/angular'; if (!config || !config.defaults) { return null; } // const configDefaults = config.defaults; if (config.defaults && config.defaults.schematics && config.defaults.schematics.collection) { collectionName = config.defaults.schematics.collection; } /** * For each schematic * - get the config * - filter one's without config * - combine them into an object */ // tslint:disable-next-line:no-any const schematicConfigs = ['class', 'component', 'directive', 'guard', 'interface', 'module', 'pipe', 'service'] .map(schematicName => { // tslint:disable-next-line:no-any const schematicDefaults = config.defaults[schematicName] || null; return { schematicName, config: schematicDefaults, }; }) .filter(schematic => schematic.config !== null) .reduce((all, schematic) => { all[collectionName + ':' + schematic.schematicName] = schematic.config; return all; }, {}); const componentUpdate = {}; componentUpdate.prefix = ''; const componentKey = collectionName + ':component'; const directiveKey = collectionName + ':directive'; if (!schematicConfigs[componentKey]) { schematicConfigs[componentKey] = {}; } if (!schematicConfigs[directiveKey]) { schematicConfigs[directiveKey] = {}; } if (config.apps && config.apps[0]) { schematicConfigs[componentKey].prefix = config.apps[0].prefix; schematicConfigs[directiveKey].prefix = config.apps[0].prefix; } if (config.defaults) { schematicConfigs[componentKey].styleext = config.defaults.styleExt; } return schematicConfigs; } function extractTargetsConfig(_config) { return null; } // This function is too big, but also really hard to refactor properly as the whole config // depends on all parts of the config. // tslint:disable-next-line:no-big-function function extractProjectsConfig(config, tree, logger) { const builderPackage = '@angular-devkit/build-angular'; const defaultAppNamePrefix = getDefaultAppNamePrefix(config); const buildDefaults = config.defaults && config.defaults.build ? { sourceMap: config.defaults.build.sourcemaps, progress: config.defaults.build.progress, poll: config.defaults.build.poll, deleteOutputPath: config.defaults.build.deleteOutputPath, preserveSymlinks: config.defaults.build.preserveSymlinks, showCircularDependencies: config.defaults.build.showCircularDependencies, commonChunk: config.defaults.build.commonChunk, namedChunks: config.defaults.build.namedChunks, } : {}; const serveDefaults = config.defaults && config.defaults.serve ? { port: config.defaults.serve.port, host: config.defaults.serve.host, ssl: config.defaults.serve.ssl, sslKey: config.defaults.serve.sslKey, sslCert: config.defaults.serve.sslCert, proxyConfig: config.defaults.serve.proxyConfig, } : {}; const apps = config.apps || []; // convert the apps to projects const browserApps = apps.filter(app => app.platform !== 'server'); const serverApps = apps.filter(app => app.platform === 'server'); const projectMap = browserApps // This function is too big, but also really hard to refactor properly as the whole config // depends on all parts of the config. // tslint:disable-next-line:no-big-function .map((app, idx) => { const defaultAppName = idx === 0 ? defaultAppNamePrefix : `${defaultAppNamePrefix}${idx}`; const name = app.name || defaultAppName; const outDir = app.outDir || defaults.outDir; const appRoot = app.root || defaults.appRoot; function _mapAssets(asset) { if (typeof asset === 'string') { return core_1.normalize(appRoot + '/' + asset); } else { if (asset.allowOutsideOutDir) { logger.warn(core_1.tags.oneLine ` Asset with input '${asset.input}' was not migrated because it uses the 'allowOutsideOutDir' option which is not supported in Angular CLI 6. `); return null; } else if (asset.output) { return { glob: asset.glob, input: core_1.normalize(appRoot + '/' + asset.input), output: core_1.normalize('/' + asset.output), }; } else { return { glob: asset.glob, input: core_1.normalize(appRoot + '/' + asset.input), output: '/', }; } } } function _buildConfigurations() { const source = app.environmentSource; const environments = app.environments; const serviceWorker = app.serviceWorker; const productionPartial = Object.assign({ optimization: true, outputHashing: 'all', sourceMap: false, extractCss: true, namedChunks: false, aot: true, extractLicenses: true, vendorChunk: false, buildOptimizer: true }, (serviceWorker ? { serviceWorker: true, ngswConfigPath: 'src/ngsw-config.json' } : {}), (app.budgets ? { budgets: app.budgets } : {})); if (!environments) { return { production: productionPartial }; } const configurations = Object.keys(environments).reduce((acc, environment) => { if (source === environments[environment]) { return acc; } let isProduction = false; const environmentContent = tree.read(app.root + '/' + environments[environment]); if (environmentContent) { isProduction = !!environmentContent.toString('utf-8') // Allow for `production: true` or `production = true`. Best we can do to guess. .match(/production['"]?\s*[:=]\s*true/); } let configurationName; // We used to use `prod` by default as the key, instead we now use the full word. // Try not to override the production key if it's there. if (environment == 'prod' && !environments['production'] && isProduction) { configurationName = 'production'; } else { configurationName = environment; } acc[configurationName] = Object.assign({}, (isProduction ? productionPartial : {}), { fileReplacements: [ { replace: `${app.root}/${source}`, with: `${app.root}/${environments[environment]}`, }, ] }); return acc; }, {}); if (!configurations['production']) { configurations['production'] = Object.assign({}, productionPartial); } return configurations; } function _serveConfigurations() { const environments = app.environments; if (!environments) { return {}; } if (!targets) { throw new Error(); } const configurations = targets.build.configurations; return Object.keys(configurations).reduce((acc, environment) => { acc[environment] = { browserTarget: `${name}:build:${environment}` }; return acc; }, {}); } function _extraEntryMapper(extraEntry) { let entry; if (typeof extraEntry === 'string') { entry = core_1.join(app.root, extraEntry); } else { const input = core_1.join(app.root, extraEntry.input || ''); entry = { input, lazy: extraEntry.lazy }; if (extraEntry.output) { entry.bundleName = extraEntry.output; } } return entry; } const projectRoot = core_1.join(core_1.normalize(appRoot), '..'); const project = { root: projectRoot, sourceRoot: appRoot, projectType: 'application', }; const targets = {}; project.architect = targets; // Browser target const buildOptions = Object.assign({ // Make outputPath relative to root. outputPath: outDir, index: `${appRoot}/${app.index || defaults.index}`, main: `${appRoot}/${app.main || defaults.main}`, tsConfig: `${appRoot}/${app.tsconfig || defaults.tsConfig}` }, (app.baseHref ? { baseHref: app.baseHref } : {}), buildDefaults); if (app.polyfills) { buildOptions.polyfills = appRoot + '/' + app.polyfills; } if (app.stylePreprocessorOptions && app.stylePreprocessorOptions.includePaths && Array.isArray(app.stylePreprocessorOptions.includePaths) && app.stylePreprocessorOptions.includePaths.length > 0) { buildOptions.stylePreprocessorOptions = { includePaths: app.stylePreprocessorOptions.includePaths .map(includePath => core_1.join(app.root, includePath)), }; } buildOptions.assets = (app.assets || []).map(_mapAssets).filter(x => !!x); buildOptions.styles = (app.styles || []).map(_extraEntryMapper); buildOptions.scripts = (app.scripts || []).map(_extraEntryMapper); targets.build = { builder: `${builderPackage}:browser`, options: buildOptions, configurations: _buildConfigurations(), }; // Serve target const serveOptions = Object.assign({ browserTarget: `${name}:build` }, serveDefaults); targets.serve = { builder: `${builderPackage}:dev-server`, options: serveOptions, configurations: _serveConfigurations(), }; // Extract target const extractI18nOptions = { browserTarget: `${name}:build` }; targets['extract-i18n'] = { builder: `${builderPackage}:extract-i18n`, options: extractI18nOptions, }; const karmaConfig = config.test && config.test.karma ? config.test.karma.config || '' : ''; // Test target const testOptions = { main: appRoot + '/' + app.test || defaults.test, // Make karmaConfig relative to root. karmaConfig, }; if (app.polyfills) { testOptions.polyfills = appRoot + '/' + app.polyfills; } if (app.testTsconfig) { testOptions.tsConfig = appRoot + '/' + app.testTsconfig; } const codeCoverageExclude = config.test && config.test.codeCoverage && config.test.codeCoverage.exclude; if (codeCoverageExclude) { testOptions.codeCoverageExclude = codeCoverageExclude; } testOptions.scripts = (app.scripts || []).map(_extraEntryMapper); testOptions.styles = (app.styles || []).map(_extraEntryMapper); testOptions.assets = (app.assets || []).map(_mapAssets).filter(x => !!x); if (karmaConfig) { targets.test = { builder: `${builderPackage}:karma`, options: testOptions, }; } const tsConfigs = []; const excludes = []; let warnForLint = false; if (config && config.lint && Array.isArray(config.lint)) { config.lint.forEach(lint => { if (lint.project) { tsConfigs.push(lint.project); } else { warnForLint = true; } if (lint.exclude) { if (typeof lint.exclude === 'string') { excludes.push(lint.exclude); } else { lint.exclude.forEach(ex => excludes.push(ex)); } } }); } if (warnForLint) { logger.warn(` Lint without 'project' was not migrated which is not supported in Angular CLI 6. `); } const removeDupes = (items) => items.reduce((newItems, item) => { if (newItems.indexOf(item) === -1) { newItems.push(item); } return newItems; }, []); // Tslint target const lintOptions = { tsConfig: removeDupes(tsConfigs).filter(t => t.indexOf('e2e') === -1), exclude: removeDupes(excludes), }; targets.lint = { builder: `${builderPackage}:tslint`, options: lintOptions, }; // server target const serverApp = serverApps .filter(serverApp => app.root === serverApp.root && app.index === serverApp.index)[0]; if (serverApp) { const serverOptions = { outputPath: serverApp.outDir || defaults.serverOutDir, main: `${appRoot}/${serverApp.main || defaults.serverMain}`, tsConfig: `${appRoot}/${serverApp.tsconfig || defaults.serverTsConfig}`, }; const serverTarget = { builder: '@angular-devkit/build-angular:server', options: serverOptions, }; targets.server = serverTarget; } const e2eProject = { root: core_1.join(projectRoot, 'e2e'), sourceRoot: core_1.join(projectRoot, 'e2e'), projectType: 'application', }; const e2eTargets = {}; // tslint:disable-next-line:max-line-length const protractorConfig = config && config.e2e && config.e2e.protractor && config.e2e.protractor.config ? config.e2e.protractor.config : ''; const e2eOptions = { protractorConfig: protractorConfig, devServerTarget: `${name}:serve`, }; const e2eTarget = { builder: `${builderPackage}:protractor`, options: e2eOptions, }; e2eTargets.e2e = e2eTarget; const e2eLintOptions = { tsConfig: removeDupes(tsConfigs).filter(t => t.indexOf('e2e') !== -1), exclude: removeDupes(excludes), }; const e2eLintTarget = { builder: `${builderPackage}:tslint`, options: e2eLintOptions, }; e2eTargets.lint = e2eLintTarget; if (protractorConfig) { e2eProject.architect = e2eTargets; } return { name, project, e2eProject }; }) .reduce((projects, mappedApp) => { const { name, project, e2eProject } = mappedApp; projects[name] = project; projects[name + '-e2e'] = e2eProject; return projects; }, {}); return projectMap; } function getDefaultAppNamePrefix(config) { let defaultAppNamePrefix = 'app'; if (config.project && config.project.name) { defaultAppNamePrefix = config.project.name; } return defaultAppNamePrefix; } function extractDefaultProject(config) { if (config.apps && config.apps[0]) { const app = config.apps[0]; const defaultAppName = getDefaultAppNamePrefix(config); const name = app.name || defaultAppName; return name; } return null; } function updateSpecTsConfig(config) { return (host, context) => { const apps = config.apps || []; apps.forEach((app, idx) => { const testTsConfig = app.testTsconfig || defaults.testTsConfig; const tsSpecConfigPath = core_1.join(core_1.normalize(app.root || ''), testTsConfig); const buffer = host.read(tsSpecConfigPath); if (!buffer) { return; } const tsCfgAst = core_1.parseJsonAst(buffer.toString(), core_1.JsonParseMode.Loose); if (tsCfgAst.kind != 'object') { throw new schematics_1.SchematicsException('Invalid tsconfig. Was expecting an object'); } const filesAstNode = json_utils_1.findPropertyInAstObject(tsCfgAst, 'files'); if (filesAstNode && filesAstNode.kind != 'array') { throw new schematics_1.SchematicsException('Invalid tsconfig "files" property; expected an array.'); } const recorder = host.beginUpdate(tsSpecConfigPath); const polyfills = app.polyfills || defaults.polyfills; if (!filesAstNode) { // Do nothing if the files array does not exist. This means exclude or include are // set and we shouldn't mess with that. } else { if (filesAstNode.value.indexOf(polyfills) == -1) { json_utils_1.appendValueInAstArray(recorder, filesAstNode, polyfills); } } host.commitUpdate(recorder); }); }; } function updatePackageJson(config) { return (host, context) => { const dependency = { type: dependencies_1.NodeDependencyType.Dev, name: '@angular-devkit/build-angular', version: latest_versions_1.latestVersions.DevkitBuildAngular, overwrite: true, }; dependencies_1.addPackageJsonDependency(host, dependency); context.addTask(new tasks_1.NodePackageInstallTask({ packageManager: config.packageManager === 'default' ? undefined : config.packageManager, })); return host; }; } function updateTsLintConfig() { return (host, context) => { const tsLintPath = '/tslint.json'; const buffer = host.read(tsLintPath); if (!buffer) { return host; } const tsCfgAst = core_1.parseJsonAst(buffer.toString(), core_1.JsonParseMode.Loose); if (tsCfgAst.kind != 'object') { return host; } const rulesNode = json_utils_1.findPropertyInAstObject(tsCfgAst, 'rules'); if (!rulesNode || rulesNode.kind != 'object') { return host; } const importBlacklistNode = json_utils_1.findPropertyInAstObject(rulesNode, 'import-blacklist'); if (!importBlacklistNode || importBlacklistNode.kind != 'array') { return host; } const recorder = host.beginUpdate(tsLintPath); for (let i = 0; i < importBlacklistNode.elements.length; i++) { const element = importBlacklistNode.elements[i]; if (element.kind == 'string' && element.value == 'rxjs') { const { start, end } = element; // Remove this element. if (i == importBlacklistNode.elements.length - 1) { // Last element. if (i > 0) { // Not first, there's a comma to remove before. const previous = importBlacklistNode.elements[i - 1]; recorder.remove(previous.end.offset, end.offset - previous.end.offset); } else { // Only element, just remove the whole rule. const { start, end } = importBlacklistNode; recorder.remove(start.offset, end.offset - start.offset); recorder.insertLeft(start.offset, '[]'); } } else { // Middle, just remove the whole node (up to next node start). const next = importBlacklistNode.elements[i + 1]; recorder.remove(start.offset, next.start.offset - start.offset); } } } host.commitUpdate(recorder); return host; }; } function updateRootTsConfig() { return (host, context) => { const tsConfigPath = '/tsconfig.json'; const buffer = host.read(tsConfigPath); if (!buffer) { return; } const tsCfgAst = core_1.parseJsonAst(buffer.toString(), core_1.JsonParseMode.Loose); if (tsCfgAst.kind !== 'object') { throw new schematics_1.SchematicsException('Invalid root tsconfig. Was expecting an object'); } const compilerOptionsAstNode = json_utils_1.findPropertyInAstObject(tsCfgAst, 'compilerOptions'); if (!compilerOptionsAstNode || compilerOptionsAstNode.kind != 'object') { throw new schematics_1.SchematicsException('Invalid root tsconfig "compilerOptions" property; expected an object.'); } if (json_utils_1.findPropertyInAstObject(compilerOptionsAstNode, 'baseUrl') && json_utils_1.findPropertyInAstObject(compilerOptionsAstNode, 'module')) { return host; } const compilerOptions = compilerOptionsAstNode.value; const { baseUrl = './', module = 'es2015' } = compilerOptions; const validBaseUrl = ['./', '', '.']; if (!validBaseUrl.includes(baseUrl)) { const formattedBaseUrl = validBaseUrl.map(x => `'${x}'`).join(', '); context.logger.warn(core_1.tags.oneLine `Root tsconfig option 'baseUrl' is not one of: ${formattedBaseUrl}. This might cause unexpected behaviour when generating libraries.`); } if (module !== 'es2015') { context.logger.warn(`Root tsconfig option 'module' is not 'es2015'. This might cause unexpected behaviour.`); } compilerOptions.module = module; compilerOptions.baseUrl = baseUrl; host.overwrite(tsConfigPath, JSON.stringify(tsCfgAst.value, null, 2)); return host; }; } function default_1() { return (host, context) => { if (host.exists('/.angular.json') || host.exists('/angular.json')) { context.logger.info('Found a modern configuration file. Nothing to be done.'); return host; } const configPath = getConfigPath(host); const configBuffer = host.read(core_1.normalize(configPath)); if (configBuffer == null) { throw new schematics_1.SchematicsException(`Could not find configuration file (${configPath})`); } const config = core_1.parseJson(configBuffer.toString(), core_1.JsonParseMode.Loose); if (typeof config != 'object' || Array.isArray(config) || config === null) { throw new schematics_1.SchematicsException('Invalid angular-cli.json configuration; expected an object.'); } return schematics_1.chain([ migrateKarmaConfiguration(config), migrateConfiguration(config, context.logger), updateSpecTsConfig(config), updatePackageJson(config), updateRootTsConfig(), updateTsLintConfig(), (host, context) => { context.logger.warn(core_1.tags.oneLine `Some configuration options have been changed, please make sure to update any npm scripts which you may have modified.`); return host; }, ]); }; } exports.default = default_1; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiLi8iLCJzb3VyY2VzIjpbInBhY2thZ2VzL3NjaGVtYXRpY3MvYW5ndWxhci9taWdyYXRpb25zL3VwZGF0ZS02L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7OztHQU1HO0FBQ0gsK0NBVzhCO0FBQzlCLDJEQU1vQztBQUNwQyw0REFBMEU7QUFFMUUsNkRBSW9DO0FBQ3BDLHlEQUdrQztBQUNsQyxtRUFBK0Q7QUFFL0QsTUFBTSxRQUFRLEdBQUc7SUFDZixPQUFPLEVBQUUsS0FBSztJQUNkLEtBQUssRUFBRSxZQUFZO0lBQ25CLElBQUksRUFBRSxTQUFTO0lBQ2YsU0FBUyxFQUFFLGNBQWM7SUFDekIsUUFBUSxFQUFFLG1CQUFtQjtJQUM3QixJQUFJLEVBQUUsU0FBUztJQUNmLE1BQU0sRUFBRSxPQUFPO0lBQ2YsS0FBSyxFQUFFLGVBQWU7SUFDdEIsVUFBVSxFQUFFLG9CQUFvQjtJQUNoQyxZQUFZLEVBQUUsb0JBQW9CO0lBQ2xDLFlBQVksRUFBRSxhQUFhO0lBQzNCLFVBQVUsRUFBRSxnQkFBZ0I7SUFDNUIsY0FBYyxFQUFFLHNCQUFzQjtDQUN2QyxDQUFDO0FBRUYsU0FBUyxhQUFhLENBQUMsSUFBVTtJQUMvQixJQUFJLFlBQVksR0FBRyxnQkFBUyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbEQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFO1FBQzdCLE9BQU8sWUFBWSxDQUFDO0tBQ3JCO0lBQ0QsWUFBWSxHQUFHLGdCQUFTLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUM3QyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUU7UUFDN0IsT0FBTyxZQUFZLENBQUM7S0FDckI7SUFFRCxNQUFNLElBQUksZ0NBQW1CLENBQUMsbUNBQW1DLENBQUMsQ0FBQztBQUNyRSxDQUFDO0FBRUQsU0FBUyx5QkFBeUIsQ0FBQyxNQUFpQjtJQUNsRCxP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