/*!
 * @nuxt/config v2.15.8 (c) 2016-2021
 * Released under the MIT License
 * Repository: https://github.com/nuxt/nuxt.js
 * Website: https://nuxtjs.org
*/
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const lodash = require('lodash');
const env = require('std-env');
const utils = require('@nuxt/utils');
const path = require('path');
const fs = require('fs');
const defu = require('defu');
const consola = require('consola');
const destr = require('destr');
const ufo = require('ufo');
const dotenv = require('dotenv');
const rc = require('rc9');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () {
            return e[k];
          }
        });
      }
    });
  }
  n['default'] = e;
  return Object.freeze(n);
}

const env__default = /*#__PURE__*/_interopDefaultLegacy(env);
const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
const defu__default = /*#__PURE__*/_interopDefaultLegacy(defu);
const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola);
const destr__default = /*#__PURE__*/_interopDefaultLegacy(destr);
const dotenv__default = /*#__PURE__*/_interopDefaultLegacy(dotenv);
const rc__namespace = /*#__PURE__*/_interopNamespace(rc);

const _app = () => ({
  vue: {
    config: {
      silent: undefined, // = !dev
      performance: undefined // = dev
    }
  },

  vueMeta: null,

  head: {
    meta: [],
    link: [],
    style: [],
    script: []
  },

  fetch: {
    server: true,
    client: true
  },

  plugins: [],

  extendPlugins: null,

  css: [],

  layouts: {},

  ErrorPage: null,

  loading: {
    color: 'black',
    failedColor: 'red',
    height: '2px',
    throttle: 200,
    duration: 5000,
    continuous: false,
    rtl: false,
    css: true
  },

  loadingIndicator: 'default',

  pageTransition: {
    name: 'page',
    mode: 'out-in',
    appear: false,
    appearClass: 'appear',
    appearActiveClass: 'appear-active',
    appearToClass: 'appear-to'
  },

  layoutTransition: {
    name: 'layout',
    mode: 'out-in'
  },

  features: {
    store: true,
    layouts: true,
    meta: true,
    middleware: true,
    transitions: true,
    deprecations: true,
    validate: true,
    asyncData: true,
    fetch: true,
    clientOnline: true,
    clientPrefetch: true,
    componentAliases: true,
    componentClientOnly: true
  }
});

const _common = () => ({
  // Env
  dev: Boolean(env__default['default'].dev),
  test: Boolean(env__default['default'].test),
  debug: undefined, // = dev
  env: {},

  createRequire: undefined,

  // Target
  target: utils.TARGETS.server,

  // Rendering
  ssr: true,

  // Mode (deprecated)
  mode: undefined,

  // Modern
  modern: undefined,

  // Modules
  modules: [],
  buildModules: [],
  _modules: [],

  globalName: undefined,
  globals: {
    id: globalName => `__${globalName}`,
    nuxt: globalName => `$${globalName}`,
    context: globalName => `__${globalName.toUpperCase()}__`,
    pluginPrefix: globalName => globalName,
    readyCallback: globalName => `on${lodash.capitalize(globalName)}Ready`,
    loadedCallback: globalName => `_on${lodash.capitalize(globalName)}Loaded`
  },

  // Server
  serverMiddleware: [],

  // Dirs and extensions
  _nuxtConfigFile: undefined,
  srcDir: undefined,
  buildDir: '.nuxt',
  modulesDir: [
    'node_modules'
  ],
  dir: {
    assets: 'assets',
    app: 'app',
    layouts: 'layouts',
    middleware: 'middleware',
    pages: 'pages',
    static: 'static',
    store: 'store'
  },
  extensions: [],
  styleExtensions: ['css', 'pcss', 'postcss', 'styl', 'stylus', 'scss', 'sass', 'less'],
  alias: {},

  // Ignores
  ignoreOptions: undefined,
  ignorePrefix: '-',
  ignore: [
    '**/*.test.*',
    '**/*.spec.*'
  ],

  // Watch
  watch: [],
  watchers: {
    rewatchOnRawEvents: undefined,
    webpack: {
      aggregateTimeout: 1000
    },
    chokidar: {
      ignoreInitial: true
    }
  },

  // Editor
  editor: undefined,

  // Hooks
  hooks: null,

  // runtimeConfig
  privateRuntimeConfig: {},
  publicRuntimeConfig: {}
});

const build = () => ({
  quiet: Boolean(env__default['default'].ci || env__default['default'].test),
  analyze: false,
  profile: process.argv.includes('--profile'),
  extractCSS: false,
  cssSourceMap: undefined,
  ssr: undefined,
  parallel: false,
  cache: false,
  standalone: false,
  publicPath: '/_nuxt/',
  serverURLPolyfill: 'url',
  filenames: {
    // { isDev, isClient, isServer }
    app: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
    chunk: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
    css: ({ isDev }) => isDev ? '[name].css' : 'css/[contenthash:7].css',
    img: ({ isDev }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]',
    font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]',
    video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]'
  },
  loaders: {
    file: { esModule: false },
    fontUrl: { esModule: false, limit: 1000 },
    imgUrl: { esModule: false, limit: 1000 },
    pugPlain: {},
    vue: {
      transformAssetUrls: {
        video: 'src',
        source: 'src',
        object: 'src',
        embed: 'src'
      }
    },
    css: {
      esModule: false,
      modules: {
        compileType: 'icss'
      }
    },
    cssModules: {
      esModule: false,
      modules: {
        localIdentName: '[local]_[hash:base64:5]'
      }
    },
    less: {},
    sass: {
      sassOptions: {
        indentedSyntax: true
      }
    },
    scss: {},
    stylus: {},
    vueStyle: {}
  },
  styleResources: {},
  plugins: [],
  terser: {},
  hardSource: false,
  aggressiveCodeRemoval: false,
  optimizeCSS: undefined,
  optimization: {
    runtimeChunk: 'single',
    minimize: undefined,
    minimizer: undefined,
    splitChunks: {
      chunks: 'all',
      automaticNameDelimiter: '/',
      cacheGroups: {}
    }
  },
  splitChunks: {
    layouts: false,
    pages: true,
    commons: true
  },
  corejs: 'auto',
  babel: {
    configFile: false,
    babelrc: false,
    cacheDirectory: undefined
  },
  transpile: [], // Name of NPM packages to be transpiled
  postcss: {
    preset: {
      // https://cssdb.org/#staging-process
      stage: 2
    }
  },
  html: {
    minify: {
      collapseBooleanAttributes: true,
      decodeEntities: true,
      minifyCSS: true,
      minifyJS: true,
      processConditionalComments: true,
      removeEmptyAttributes: true,
      removeRedundantAttributes: true,
      trimCustomFragments: true,
      useShortDoctype: true
    }
  },

  template: undefined,
  templates: [],

  watch: [],
  devMiddleware: {
    // stats will be printed by webapckbar StateReporter
    stats: 'none'
  },
  hotMiddleware: {},

  stats: {
    excludeAssets: [
      /.map$/,
      /index\..+\.html$/,
      /vue-ssr-(client|modern)-manifest.json/
    ]
  },
  friendlyErrors: true,
  additionalExtensions: [],
  warningIgnoreFilters: [],

  followSymlinks: false,

  loadingScreen: {},
  indicator: {
    position: 'bottom-right',
    backgroundColor: '#2E495E',
    color: '#00C48D'
  }
});

const messages = () => ({
  loading: 'Loading...',
  error_404: 'This page could not be found',
  server_error: 'Server error',
  nuxtjs: 'Nuxt',
  back_to_home: 'Back to the home page',
  server_error_details:
    'An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details.',
  client_error: 'Error',
  client_error_details:
    'An error occurred while rendering the page. Check developer tools console for details.'
});

const modes = () => ({
  [utils.MODES.universal]: {
    build: {
      ssr: true
    },
    render: {
      ssr: true
    }
  },
  [utils.MODES.spa]: {
    build: {
      ssr: false
    },
    render: {
      ssr: false
    }
  }
});

// TODO: Refactor @nuxt/server related options into `server.js`

const render = () => ({
  bundleRenderer: {
    shouldPrefetch: () => false,
    shouldPreload: (fileWithoutQuery, asType) => ['script', 'style'].includes(asType),
    runInNewContext: undefined
  },
  crossorigin: undefined,
  resourceHints: true,
  ssr: undefined,
  ssrLog: undefined,
  http2: {
    push: false,
    shouldPush: null,
    pushAssets: null
  },
  static: {
    prefix: true
  },
  compressor: {
    threshold: 0
  },
  etag: {
    weak: false
  },
  csp: false,
  dist: {
    // Don't serve index.html template
    index: false,
    // 1 year in production
    maxAge: '1y'
  },
  // https://github.com/nuxt/serve-placeholder
  fallback: {
    dist: {},
    static: {
      skipUnknown: true,
      handlers: {
        '.htm': false,
        '.html': false
      }
    }
  }
});

const router = () => ({
  mode: 'history',
  base: '/',
  routes: [],
  routeNameSplitter: '-',
  middleware: [],
  linkActiveClass: 'nuxt-link-active',
  linkExactActiveClass: 'nuxt-link-exact-active',
  linkPrefetchedClass: false,
  extendRoutes: null,
  scrollBehavior: null,
  parseQuery: false,
  stringifyQuery: false,
  fallback: false,
  prefetchLinks: true,
  prefetchPayloads: true,
  trailingSlash: undefined
});

const server = ({ env = {} } = {}) => ({
  https: false,
  port: env.NUXT_PORT ||
    env.PORT ||
    env.npm_package_config_nuxt_port ||
    3000,
  host: env.NUXT_HOST ||
    env.HOST ||
    env.npm_package_config_nuxt_host ||
    'localhost',
  socket: env.UNIX_SOCKET ||
    env.npm_package_config_unix_socket,
  timing: false
});

const cli = () => ({
  badgeMessages: [],
  bannerColor: 'green'
});

const generate = () => ({
  dir: 'dist',
  routes: [],
  exclude: [],
  concurrency: 500,
  interval: 0,
  subFolders: true,
  fallback: '200.html',
  crawler: true,
  manifest: true,
  cache: {
    ignore: [],
    globbyOptions: {
      gitignore: true
    }
  },
  staticAssets: {
    base: undefined, // Default: "/_nuxt/static:
    versionBase: undefined, // Default: "_nuxt/static/{version}""
    dir: 'static',
    version: undefined // Default: "{timeStampSec}"
  }
});

const defaultNuxtConfigFile = 'nuxt.config';

function getDefaultNuxtConfig (options = {}) {
  if (!options.env) {
    options.env = process.env;
  }

  return {
    ..._app(),
    ..._common(),
    build: build(),
    messages: messages(),
    modes: modes(),
    render: render(),
    router: router(),
    server: server(options),
    cli: cli(),
    generate: generate()
  }
}

function getNuxtConfig (_options) {
  // Prevent duplicate calls
  if (_options.__normalized__) {
    return _options
  }

  // Clone options to prevent unwanted side-effects
  const options = Object.assign({}, _options);
  options.__normalized__ = true;

  // Normalize options
  if (options.loading === true) {
    delete options.loading;
  }

  if (
    options.router &&
    options.router.middleware &&
    !Array.isArray(options.router.middleware)
  ) {
    options.router.middleware = [options.router.middleware];
  }

  if (options.router && typeof options.router.base === 'string') {
    options._routerBaseSpecified = true;
  }

  // TODO: Remove for Nuxt 3
  // router.scrollBehavior -> app/router.scrollBehavior.js
  if (options.router && typeof options.router.scrollBehavior !== 'undefined') {
    consola__default['default'].warn('`router.scrollBehavior` property is deprecated in favor of using `~/app/router.scrollBehavior.js` file, learn more: https://nuxtjs.org/api/configuration-router#scrollbehavior');
  }

  // TODO: Remove for Nuxt 3
  // transition -> pageTransition
  if (typeof options.transition !== 'undefined') {
    consola__default['default'].warn('`transition` property is deprecated in favor of `pageTransition` and will be removed in Nuxt 3');
    options.pageTransition = options.transition;
    delete options.transition;
  }

  if (typeof options.pageTransition === 'string') {
    options.pageTransition = { name: options.pageTransition };
  }

  if (typeof options.layoutTransition === 'string') {
    options.layoutTransition = { name: options.layoutTransition };
  }

  if (typeof options.extensions === 'string') {
    options.extensions = [options.extensions];
  }

  options.globalName = (utils.isNonEmptyString(options.globalName) && /^[a-zA-Z]+$/.test(options.globalName))
    ? options.globalName.toLowerCase()
    // use `` for preventing replacing to nuxt-edge
    : `nuxt`;

  // Resolve rootDir
  options.rootDir = utils.isNonEmptyString(options.rootDir) ? path__default['default'].resolve(options.rootDir) : process.cwd();

  // Apply defaults by ${buildDir}/dist/build.config.js
  // TODO: Unsafe operation.
  // const buildDir = options.buildDir || defaults.buildDir
  // const buildConfig = resolve(options.rootDir, buildDir, 'build.config.js')
  // if (existsSync(buildConfig)) {
  //   defaultsDeep(options, require(buildConfig))
  // }

  // Apply defaults
  const nuxtConfig = getDefaultNuxtConfig();

  nuxtConfig.build._publicPath = nuxtConfig.build.publicPath;

  // Fall back to default if publicPath is falsy
  if (options.build && !options.build.publicPath) {
    options.build.publicPath = undefined;
  }

  lodash.defaultsDeep(options, nuxtConfig);

  // Target
  options.target = options.target || 'server';
  if (!Object.values(utils.TARGETS).includes(options.target)) {
    consola__default['default'].warn(`Unknown target: ${options.target}. Falling back to server`);
    options.target = 'server';
  }

  // Deprecate Mode
  if (options.mode) {
    if ((options.mode === utils.MODES.universal && options.ssr) || (options.mode === utils.MODES.spa && !options.ssr)) {
      consola__default['default'].warn('`mode` option is deprecated. You can safely remove it from `nuxt.config`');
    } else {
      consola__default['default'].warn('`mode` option is deprecated. Please use `ssr: true` for universal mode or `ssr: false` for spa mode and remove `mode` from `nuxt.config`');
    }
  } else {
    // For backward compat we need default value
    options.mode = utils.MODES.universal;
  }

  // SSR root option
  if (options.ssr === false) {
    options.mode = utils.MODES.spa;
  }

  // Apply mode preset
  const modePreset = options.modes[options.mode || utils.MODES.universal];

  if (!modePreset) {
    consola__default['default'].warn(`Unknown mode: ${options.mode}. Falling back to ${utils.MODES.universal}`);
  }
  lodash.defaultsDeep(options, modePreset || options.modes[utils.MODES.universal]);

  // Sanitize router.base
  options.router.base = ufo.withTrailingSlash(ufo.normalizeURL(options.router.base));

  // Legacy support for export
  if (options.export) {
    consola__default['default'].warn('export option is deprecated and will be removed in a future version! Please switch to generate');
    options.generate = defu__default['default'](options.export, options.generate);
  }
  exports.export = options.generate;

  // Check srcDir and generate.dir existence
  const hasSrcDir = utils.isNonEmptyString(options.srcDir);
  const hasGenerateDir = utils.isNonEmptyString(options.generate.dir);

  // Resolve srcDir
  options.srcDir = hasSrcDir
    ? path__default['default'].resolve(options.rootDir, options.srcDir)
    : options.rootDir;

  // Resolve buildDir
  options.buildDir = path__default['default'].resolve(options.rootDir, options.buildDir);

  // Aliases
  const { rootDir, srcDir, dir: { assets: assetsDir, static: staticDir } } = options;
  options.alias = {
    '~~': rootDir,
    '@@': rootDir,
    '~': srcDir,
    '@': srcDir,
    [assetsDir]: path__default['default'].join(srcDir, assetsDir),
    [staticDir]: path__default['default'].join(srcDir, staticDir),
    ...options.alias
  };

  // Default value for _nuxtConfigFile
  if (!options._nuxtConfigFile) {
    options._nuxtConfigFile = path__default['default'].resolve(options.rootDir, `${defaultNuxtConfigFile}.js`);
  }

  if (!options._nuxtConfigFiles) {
    options._nuxtConfigFiles = [
      options._nuxtConfigFile
    ];
  }

  // Watch for config file changes
  options.watch.push(...options._nuxtConfigFiles);

  // Protect rootDir against buildDir
  utils.guardDir(options, 'rootDir', 'buildDir');

  if (hasGenerateDir) {
    // Resolve generate.dir
    options.generate.dir = path__default['default'].resolve(options.rootDir, options.generate.dir);

    // Protect rootDir against buildDir
    utils.guardDir(options, 'rootDir', 'generate.dir');
  }

  if (hasSrcDir) {
    // Protect srcDir against buildDir
    utils.guardDir(options, 'srcDir', 'buildDir');

    if (hasGenerateDir) {
      // Protect srcDir against generate.dir
      utils.guardDir(options, 'srcDir', 'generate.dir');
    }
  }

  // Populate modulesDir
  options.modulesDir = lodash.uniq(
    utils.getMainModule().paths.concat(
      [].concat(options.modulesDir).map(dir => path__default['default'].resolve(options.rootDir, dir))
    )
  );

  const mandatoryExtensions = ['js', 'mjs'];

  options.extensions = mandatoryExtensions
    .filter(ext => !options.extensions.includes(ext))
    .concat(options.extensions);

  // If app.html is defined, set the template path to the user template
  if (options.appTemplatePath === undefined) {
    options.appTemplatePath = path__default['default'].resolve(options.buildDir, 'views/app.template.html');
    if (fs__default['default'].existsSync(path__default['default'].join(options.srcDir, 'app.html'))) {
      options.appTemplatePath = path__default['default'].join(options.srcDir, 'app.html');
    }
  } else {
    options.appTemplatePath = path__default['default'].resolve(options.srcDir, options.appTemplatePath);
  }

  options.build.publicPath = options.build.publicPath.replace(/([^/])$/, '$1/');
  options.build._publicPath = options.build._publicPath.replace(/([^/])$/, '$1/');

  // Ignore publicPath on dev
  if (options.dev && utils.isUrl(options.build.publicPath)) {
    options.build.publicPath = options.build._publicPath;
  }

  // If store defined, update store options to true unless explicitly disabled
  if (
    options.store !== false &&
    fs__default['default'].existsSync(path__default['default'].join(options.srcDir, options.dir.store)) &&
    fs__default['default'].readdirSync(path__default['default'].join(options.srcDir, options.dir.store))
      .find(filename => filename !== 'README.md' && filename[0] !== '.')
  ) {
    options.store = true;
  }

  // SPA loadingIndicator
  if (options.loadingIndicator) {
    // Normalize loadingIndicator
    if (!utils.isPureObject(options.loadingIndicator)) {
      options.loadingIndicator = { name: options.loadingIndicator };
    }

    // Apply defaults
    options.loadingIndicator = Object.assign(
      {
        name: 'default',
        color: (options.loading && options.loading.color) || '#D3D3D3',
        color2: '#F5F5F5',
        background: (options.manifest && options.manifest.theme_color) || 'white',
        dev: options.dev,
        loading: options.messages.loading
      },
      options.loadingIndicator
    );
  }

  // Debug errors
  if (options.debug === undefined) {
    options.debug = options.dev;
  }

  // Validate that etag.hash is a function, if not unset it
  if (options.render.etag) {
    const { hash } = options.render.etag;
    if (hash) {
      const isFn = typeof hash === 'function';
      if (!isFn) {
        options.render.etag.hash = undefined;

        if (options.dev) {
          consola__default['default'].warn(`render.etag.hash should be a function, received ${typeof hash} instead`);
        }
      }
    }
  }

  // Apply default hash to CSP option
  if (options.render.csp) {
    options.render.csp = defu__default['default'](options.render.csp, {
      hashAlgorithm: 'sha256',
      allowedSources: undefined,
      policies: undefined,
      addMeta: Boolean(options.target === utils.TARGETS.static),
      unsafeInlineCompatibility: false,
      reportOnly: options.debug
    });

    // TODO: Remove this if statement in Nuxt 3, we will stop supporting this typo (more on: https://github.com/nuxt/nuxt.js/pull/6583)
    if (options.render.csp.unsafeInlineCompatiblity) {
      consola__default['default'].warn('Using `unsafeInlineCompatiblity` is deprecated and will be removed in Nuxt 3. Use `unsafeInlineCompatibility` instead.');
      options.render.csp.unsafeInlineCompatibility = options.render.csp.unsafeInlineCompatiblity;
      delete options.render.csp.unsafeInlineCompatiblity;
    }
  }

  // cssSourceMap
  if (options.build.cssSourceMap === undefined) {
    options.build.cssSourceMap = options.dev;
  }

  const babelConfig = options.build.babel;
  // babel cacheDirectory
  if (babelConfig.cacheDirectory === undefined) {
    babelConfig.cacheDirectory = options.dev;
  }

  // TODO: remove this warn in Nuxt 3
  if (Array.isArray(babelConfig.presets)) {
    const warnPreset = (presetName) => {
      const oldPreset = '@nuxtjs/babel-preset-app';
      const newPreset = '@nuxt/babel-preset-app';
      if (presetName.includes(oldPreset)) {
        presetName = presetName.replace(oldPreset, newPreset);
        consola__default['default'].warn('@nuxtjs/babel-preset-app has been deprecated, please use @nuxt/babel-preset-app.');
      }
      return presetName
    };
    babelConfig.presets = babelConfig.presets.map((preset) => {
      const hasOptions = Array.isArray(preset);
      if (hasOptions) {
        preset[0] = warnPreset(preset[0]);
      } else if (typeof preset === 'string') {
        preset = warnPreset(preset);
      }
      return preset
    });
  }

  // Vue config
  const vueConfig = options.vue.config;

  if (vueConfig.silent === undefined) {
    vueConfig.silent = !options.dev;
  }
  if (vueConfig.performance === undefined) {
    vueConfig.performance = options.dev;
  }

  // merge custom env with variables
  const eligibleEnvVariables = lodash.pick(process.env, Object.keys(process.env).filter(k => k.startsWith('NUXT_ENV_')));
  Object.assign(options.env, eligibleEnvVariables);

  // Normalize ignore
  options.ignore = options.ignore ? [].concat(options.ignore) : [];

  // Append ignorePrefix glob to ignore
  if (typeof options.ignorePrefix === 'string') {
    options.ignore.push(`**/${options.ignorePrefix}*.*`);
  }

  // Compression middleware legacy
  if (options.render.gzip) {
    consola__default['default'].warn('render.gzip is deprecated and will be removed in a future version! Please switch to render.compressor');
    options.render.compressor = options.render.gzip;
    delete options.render.gzip;
  }

  // If no server-side rendering, add appear true transition
  if (options.render.ssr === false && options.pageTransition) {
    options.pageTransition.appear = true;
  }

  options.render.ssrLog = options.dev
    ? options.render.ssrLog === undefined || options.render.ssrLog
    : false;

  // We assume the SPA fallback path is 404.html (for GitHub Pages, Surge, etc.)
  if (options.generate.fallback === true) {
    options.generate.fallback = '404.html';
  }

  if (options.build.stats === 'none' || options.build.quiet === true) {
    options.build.stats = false;
  }

  // Vendor backward compatibility with nuxt 1.x
  if (typeof options.build.vendor !== 'undefined') {
    delete options.build.vendor;
    consola__default['default'].warn('vendor has been deprecated due to webpack4 optimization');
  }

  // Disable CSS extraction due to incompatibility with thread-loader
  if (options.build.extractCSS && options.build.parallel) {
    options.build.parallel = false;
    consola__default['default'].warn('extractCSS cannot work with parallel build due to limited work pool in thread-loader');
  }

  // build.extractCSS.allChunks has no effect
  if (typeof options.build.extractCSS.allChunks !== 'undefined') {
    consola__default['default'].warn('build.extractCSS.allChunks has no effect from v2.0.0. Please use build.optimization.splitChunks settings instead.');
  }

  // devModules has been renamed to buildModules
  if (typeof options.devModules !== 'undefined') {
    consola__default['default'].warn('`devModules` has been renamed to `buildModules` and will be removed in Nuxt 3.');
    options.buildModules.push(...options.devModules);
    delete options.devModules;
  }

  // Enable minimize for production builds
  if (options.build.optimization.minimize === undefined) {
    options.build.optimization.minimize = !options.dev;
  }

  // Enable optimizeCSS only when extractCSS is enabled
  if (options.build.optimizeCSS === undefined) {
    options.build.optimizeCSS = options.build.extractCSS ? {} : false;
  }

  const { loaders } = options.build;
  const vueLoader = loaders.vue;
  if (vueLoader.productionMode === undefined) {
    vueLoader.productionMode = !options.dev;
  }
  const styleLoaders = [
    'css', 'cssModules', 'less',
    'sass', 'scss', 'stylus', 'vueStyle'
  ];
  for (const name of styleLoaders) {
    const loader = loaders[name];
    if (loader && loader.sourceMap === undefined) {
      loader.sourceMap = Boolean(options.build.cssSourceMap);
    }
  }

  options.build.transpile = [].concat(options.build.transpile || []);

  if (options.build.quiet === true) {
    consola__default['default'].level = 0;
  }

  // Use runInNewContext for dev mode by default
  const { bundleRenderer } = options.render;
  if (typeof bundleRenderer.runInNewContext === 'undefined') {
    bundleRenderer.runInNewContext = options.dev;
  }

  // TODO: Remove this if statement in Nuxt 3
  if (options.build.crossorigin) {
    consola__default['default'].warn('Using `build.crossorigin` is deprecated and will be removed in Nuxt 3. Please use `render.crossorigin` instead.');
    options.render.crossorigin = options.build.crossorigin;
    delete options.build.crossorigin;
  }

  const { timing } = options.server;
  if (timing) {
    options.server.timing = { total: true, ...timing };
  }

  if (utils.isPureObject(options.serverMiddleware)) {
    options.serverMiddleware = Object.entries(options.serverMiddleware)
      .map(([path, handler]) => ({ path, handler }));
  }

  // App config (internal for nuxt2 at this stage)
  const useCDN = utils.isUrl(options.build.publicPath) && !options.dev;
  const isRelativePublicPath = ufo.isRelative(options.build.publicPath);

  options.app = defu__default['default'](options.app, {
    basePath: options.router.base,
    assetsPath: isRelativePublicPath ? options.build.publicPath : useCDN ? '/' : ufo.joinURL(options.router.base, options.build.publicPath),
    cdnURL: useCDN ? options.build.publicPath : null
  });
  // Expose app config to $config._app
  options.publicRuntimeConfig = options.publicRuntimeConfig || {};
  options.publicRuntimeConfig._app = options.app;

  // Generate staticAssets
  const { staticAssets } = options.generate;
  if (!staticAssets.version) {
    staticAssets.version = String(Math.round(Date.now() / 1000));
  }
  if (!staticAssets.base) {
    staticAssets.base = ufo.joinURL(options.app.assetsPath, staticAssets.dir);
  }
  if (!staticAssets.versionBase) {
    staticAssets.versionBase = ufo.joinURL(staticAssets.base, staticAssets.version);
  }

  // createRequire
  const isJest = typeof jest !== 'undefined';
  const defaultCreateRequire = isJest ? 'native' : 'jiti';

  options.createRequire = process.env.NUXT_CREATE_REQUIRE || options.createRequire || defaultCreateRequire;

  if (options.createRequire === 'native' || options.createRequire === 'jiti') {
    const useJiti = options.createRequire === 'jiti';
    options.createRequire = p => utils.createRequire(typeof p === 'string' ? p : p.filename, useJiti);
  } else if (typeof options.createRequire !== 'function') {
    throw new TypeError(
      `Unsupported createRequire value ${options.createRequire}! Possible values: "native", "jiti", <Function>`
    )
  }

  // Indicator
  // Change boolean true to default nuxt value
  if (options.build.indicator === true) {
    options.build.indicator = nuxtConfig.build.indicator;
  }

  // ----- Builtin modules -----

  // Loading screen
  // Force disable for production and programmatic users
  if (!options.dev || !options._cli || !utils.getPKG('@nuxt/loading-screen')) {
    options.build.loadingScreen = false;
  }
  if (options.build.loadingScreen) {
    options._modules.push(['@nuxt/loading-screen', options.build.loadingScreen]);
  } else {
    // When loadingScreen is disabled we should also disable build indicator
    options.build.indicator = false;
  }

  // Components Module
  if (!options._start && utils.getPKG('@nuxt/components')) {
    options._modules.push('@nuxt/components');
  }

  // Nuxt Telemetry
  if (
    options.telemetry !== false &&
    !options.test &&
    !destr__default['default'](process.env.NUXT_TELEMETRY_DISABLED) &&
    utils.getPKG('@nuxt/telemetry')
  ) {
    options._modules.push('@nuxt/telemetry');
  }

  return options
}

async function loadNuxtConfig ({
  rootDir = '.',
  envConfig = {},
  configFile = defaultNuxtConfigFile,
  configContext = {},
  configOverrides = {}
} = {}) {
  rootDir = path__default['default'].resolve(rootDir);

  const _require = utils.createRequire(rootDir, true);

  let options = {};

  try {
    configFile = _require.resolve(path__default['default'].resolve(rootDir, configFile));
  } catch (e) {
    if (e.code !== 'MODULE_NOT_FOUND') {
      throw (e)
    } else if (configFile !== defaultNuxtConfigFile) {
      consola__default['default'].fatal('Config file not found: ' + configFile);
    }
    // Skip configFile if cannot resolve
    configFile = undefined;
  }

  // Load env
  envConfig = {
    dotenv: '.env',
    env: process.env,
    expand: true,
    ...envConfig
  };

  const env = loadEnv(envConfig, rootDir);

  // Fill process.env so it is accessible in nuxt.config
  for (const key in env) {
    if (!key.startsWith('_') && envConfig.env[key] === undefined) {
      envConfig.env[key] = env[key];
    }
  }

  if (configFile) {
    // Clear cache
    utils.clearRequireCache(configFile);
    options = _require(configFile) || {};
    if (options.default) {
      options = options.default;
    }

    if (typeof options === 'function') {
      try {
        options = await options(configContext);
        if (options.default) {
          options = options.default;
        }
      } catch (error) {
        consola__default['default'].error(error);
        consola__default['default'].fatal('Error while fetching async configuration');
      }
    }

    // Don't mutate options export
    options = { ...options };

    // Keep _nuxtConfigFile for watching
    options._nuxtConfigFile = configFile;

    // Keep all related files for watching
    options._nuxtConfigFiles = Array.from(utils.scanRequireTree(configFile));
    if (!options._nuxtConfigFiles.includes(configFile)) {
      options._nuxtConfigFiles.unshift(configFile);
    }
  }

  if (typeof options.rootDir !== 'string') {
    options.rootDir = rootDir;
  }

  // Load Combine configs
  // Priority: configOverrides > nuxtConfig > .nuxtrc > .nuxtrc (global)
  options = defu__default['default'](
    configOverrides,
    options,
    rc__namespace.read({ name: '.nuxtrc', dir: options.rootDir }),
    rc__namespace.readUser('.nuxtrc')
  );

  // Load env to options._env
  options._env = env;
  options._envConfig = envConfig;
  if (configContext) { configContext.env = env; }

  // Expand and interpolate runtimeConfig from _env
  if (envConfig.expand) {
    for (const c of ['publicRuntimeConfig', 'privateRuntimeConfig']) {
      if (options[c]) {
        if (typeof options[c] === 'function') {
          options[c] = options[c](env);
        }
        expand(options[c], env, destr__default['default']);
      }
    }
  }

  return options
}

function loadEnv (envConfig, rootDir = process.cwd()) {
  const env = Object.create(null);

  // Read dotenv
  if (envConfig.dotenv) {
    envConfig.dotenv = path__default['default'].resolve(rootDir, envConfig.dotenv);
    if (fs__default['default'].existsSync(envConfig.dotenv)) {
      const parsed = dotenv__default['default'].parse(fs__default['default'].readFileSync(envConfig.dotenv, 'utf-8'));
      Object.assign(env, parsed);
    }
  }

  // Apply process.env
  if (!envConfig.env._applied) {
    Object.assign(env, envConfig.env);
    envConfig.env._applied = true;
  }

  // Interpolate env
  if (envConfig.expand) {
    expand(env);
  }

  return env
}

// Based on https://github.com/motdotla/dotenv-expand
function expand (target, source = {}, parse = v => v) {
  function getValue (key) {
    // Source value 'wins' over target value
    return source[key] !== undefined ? source[key] : target[key]
  }

  function interpolate (value, parents = []) {
    if (typeof value !== 'string') {
      return value
    }
    const matches = value.match(/(.?\${?(?:[a-zA-Z0-9_:]+)?}?)/g) || [];
    return parse(matches.reduce((newValue, match) => {
      const parts = /(.?)\${?([a-zA-Z0-9_:]+)?}?/g.exec(match);
      const prefix = parts[1];

      let value, replacePart;

      if (prefix === '\\') {
        replacePart = parts[0];
        value = replacePart.replace('\\$', '$');
      } else {
        const key = parts[2];
        replacePart = parts[0].substring(prefix.length);

        // Avoid recursion
        if (parents.includes(key)) {
          consola__default['default'].warn(`Please avoid recursive environment variables ( loop: ${parents.join(' > ')} > ${key} )`);
          return ''
        }

        value = getValue(key);

        // Resolve recursive interpolations
        value = interpolate(value, [...parents, key]);
      }

      return value !== undefined ? newValue.replace(replacePart, value) : newValue
    }, value))
  }

  for (const key in target) {
    target[key] = interpolate(getValue(key));
  }
}

exports.defaultNuxtConfigFile = defaultNuxtConfigFile;
exports.getDefaultNuxtConfig = getDefaultNuxtConfig;
exports.getNuxtConfig = getNuxtConfig;
exports.loadNuxtConfig = loadNuxtConfig;
