text: 'use strict';
  
  // OpenSSL 3 does not support md4, webpack 4 hardcodes md4 in many places
  // https://github.com/webpack/webpack/issues/13572#issuecomment-923736472
  // As the issue suggests we should update to webpack 5, doing so requires a lot
  // of changes. TODO: Remove after updating to webpack v5.54.0+
  const crypto = require('crypto');
  const crypto_orig_createHash = crypto.createHash;
  crypto.createHash = algorithm =>
      crypto_orig_createHash(algorithm == 'md4' ? 'sha256' : algorithm);
  
  // Modules
  var webpack = require('webpack');
  var autoprefixer = require('autoprefixer');
  var HtmlWebpackInlineSourcePlugin =
      require('html-webpack-inline-source-plugin');
  var HtmlWebpackPlugin = require('html-webpack-plugin');
  var CopyWebpackPlugin = require('copy-webpack-plugin');
  var CompressionPlugin = require('compression-webpack-plugin');
  var path = require('path');
  var FilterChunkWebpackPlugin = require('filter-chunk-webpack-plugin');
  var MiniCssExtractPlugin = require('mini-css-extract-plugin');
  
  const isPathInside = require('is-path-inside')
  const pkgDir = require('pkg-dir')
  const coreJsDir = pkgDir.sync(require.resolve('core-js'))
  
  module.exports = (env, options) => {
    var isProd = options.mode === 'production';
  
    /**
     * Config
     * Reference: http://webpack.github.io/docs/configuration.html
     * This is the object where all configuration gets set
     */
    var config = {};
  
    /**
     * Entry
     * Reference: http://webpack.github.io/docs/configuration.html#entry
     * Should be an empty object if it's generating a test build
     * Karma will set this when it's a test build
     */
    config.entry = {app: './app/index.js'};
  
    /**
     * Output
     * Reference: http://webpack.github.io/docs/configuration.html#output
     * Should be an empty object if it's generating a test build
     * Karma will handle setting it up for you when it's a test build
     */
    config.output = {
      // Absolute output directory
      path: __dirname + '/dist',
  
      // Output path from the view of the page
      // Uses webpack-dev-server in development
      publicPath: '/',
  
      // Filename for entry points
      // Only adds hash in build mode
      filename: '[name].bundle.js',
  
      // Filename for non-entry points
      // Only adds hash in build mode
      chunkFilename: '[name].bundle.js'
    };
  
    /**
     * Loaders
     * Reference:
     * http://webpack.github.io/docs/configuration.html#module-loaders
     * List: http://webpack.github.io/docs/list-of-loaders.html
     * This handles most of the magic responsible for converting modules
     */
  
    // Initialize module
    config.module = {
      rules: [
        {
          // JS LOADER
          // Reference: https://github.com/babel/babel-loader
          // Transpile .js files using babel-loader
          // Compiles ES6 and ES7 into ES5 code
          test: /\.js$/,
          exclude: (input) => isPathInside(input, coreJsDir),
          use: {
            loader: 'babel-loader',
            options: {
              presets: [['@babel/preset-env', {useBuiltIns: 'entry', corejs: 3}]]
            }
          }
        },
        {
          // ASSET LOADER
          // Reference: https://github.com/webpack/file-loader
          // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to
          // output
          // Rename the file using the asset hash
          // Pass along the updated reference to your code
          // You can add here any file extension you want to get copied
          // to your output
          // Excludes .svg files in icons directory
          test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
          exclude: /icons\/.*\.svg$/,
          loader: 'file-loader',
          options: {name: '[path][name].[ext]'}
        },
        {
          // INLINE SVG LOADER
          // Inlines .svg assets in icons directory
          // needed specifically for icon-provider.js directive
          test: /icons\/.*\.svg$/,
          loader: 'svg-inline-loader'
        },
        {
          // HTML LOADER
          // Reference: https://github.com/webpack/raw-loader
          // Allow loading html through js
          test: /\.html$/,
          loader: 'html-loader'
        },
        {
          test: /\.css$/,
          use: [MiniCssExtractPlugin.loader, 'css-loader'],
        },
        {
          test: /\.scss$/,
          use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
        }
      ]
    };
  
    config.plugins = [
      new HtmlWebpackPlugin({
        template: './app/index.html',
        inject: 'body',
        favicon: './app/assets/images/favicon.ico',
        minify: {removeComments: true, collapseWhitespace: true},
  
      }),
      new MiniCssExtractPlugin(),
  
      new FilterChunkWebpackPlugin({
        patterns: [
          '*glyphicons-halflings-regular*.ttf',
          '*glyphicons-halflings-regular*.svg',
          '*glyphicons-halflings-regular*.eot',
          '*glyphicons-halflings-regular*.woff2',
        ]
      })
    ];
  
    // Comment in to see per-module js sizes.  This is useful in debugging "why is
    // my binary so big"
    /*
    config.optimization = {
      runtimeChunk: 'single',
      splitChunks: {
        chunks: 'all',
        maxInitialRequests: Infinity,
        minSize: 0,
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name(module) {
              // get the name. E.g. node_modules/packageName/not/this/part.js
              // or node_modules/packageName
              const packageName =
    module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
  
              // npm package names are URL-safe, but some servers don't like @
    symbols return `${packageName.replace('@', '')}`;
            },
          },
        },
      },
    };
    */
  
    // Add build specific plugins
    if (isProd) {
      config.plugins.push(new CompressionPlugin({deleteOriginalAssets: true}));
    }
  
    /**
     * Dev server configuration
     * Reference: http://webpack.github.io/docs/configuration.html#devserver
     * Reference: http://webpack.github.io/docs/webpack-dev-server.html
     */
    config.devServer = {contentBase: './src/public', stats: 'minimal'};
  
    return config;
  };
  