code:
export = pluginCreator;
/**
 * @typedef {{precision?: number | false,
 *          preserve?: boolean,
 *          warnWhenCannotResolve?: boolean,
 *          mediaQueries?: boolean,
 *          selectors?: boolean}} PostCssCalcOptions
 */
/**
 * @type {import('postcss').PluginCreator<PostCssCalcOptions>}
 * @param {PostCssCalcOptions} opts
 * @return {import('postcss').Plugin}
 */
declare function pluginCreator(opts: PostCssCalcOptions): import('postcss').Plugin;
declare namespace pluginCreator {
    export { postcss, PostCssCalcOptions };
}
type PostCssCalcOptions = {
    precision?: number | false;
    preserve?: boolean;
    warnWhenCannotResolve?: boolean;
    mediaQueries?: boolean;
    selectors?: boolean;
};
declare var postcss: true;

license: mit


code:
export = convertUnit;
/**
 * @param {number} value
 * @param {string} sourceUnit
 * @param {string} targetUnit
 * @param {number|false} precision
 */
declare function convertUnit(value: number, sourceUnit: string, targetUnit: string, precision: number | false): number;


code:
export = reduce;
/**
 * @param {import('../parser').CalcNode} node
 * @param {number} precision
 * @return {import('../parser').CalcNode}
 */
declare function reduce(node: import('../parser').CalcNode, precision: number): import('../parser').CalcNode;
declare namespace reduce {
    export { Collectible };
}
type Collectible = {
    preOperator: '+' | '-';
    node: import('../parser').CalcNode;
};


code:
declare function _exports(calc: string, node: import('../parser').CalcNode, originalValue: string, options: {
    precision: number | false;
    warnWhenCannotResolve: boolean;
}, result: import("postcss").Result, item: import("postcss").ChildNode): string;
export = _exports;


code:
declare function _exports(node: any, property: 'value' | 'params' | 'selector', options: {
    precision: number;
    preserve: boolean;
    warnWhenCannotResolve: boolean;
}, result: import("postcss").Result): void;
export = _exports;


code:
Copyright (c) Ben Briggs <beneb.info@gmail.com> (http://beneb.info)

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


code:
# [postcss][postcss]-colormin

> Minify colors in your CSS files with PostCSS.

## Install

With [npm](https://npmjs.org/package/postcss-colormin) do:

```
npm install postcss-colormin --save
```

## Example

```js
var postcss = require('postcss')
var colormin = require('postcss-colormin');

var css = 'h1 {color: rgba(255, 0, 0, 1)}';
console.log(postcss(colormin()).process(css).css);

// => 'h1 {color:red}'
```

For more examples see the [tests](src/__tests__/index.js).

## Usage

See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
examples for your environment.

## Contributors

See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).

## License

MIT © [Ben Briggs](http://beneb.info)

[postcss]:  https://github.com/postcss/postcss


postcss-colormin

description: Minify colors in your CSS files with PostCSS.

files: src LICENSE-MIT types

keywords: color colors compression css minify postcss postcss-plugin

license: MIT

repository: cssnano/cssnano


code:
'use strict';
const browserslist = require('browserslist');
const { isSupported } = require('caniuse-api');
const valueParser = require('postcss-value-parser');
const minifyColor = require('./minifyColor');

/**
 * @param {{nodes: valueParser.Node[]}} parent
 * @param {(node: valueParser.Node, index: number, parent: {nodes: valueParser.Node[]}) => false | undefined} callback
 * @return {void}
 */
function walk(parent, callback) {
  parent.nodes.forEach((node, index) => {
    const bubble = callback(node, index, parent);

    if (node.type === 'function' && bubble !== false) {
      walk(node, callback);
    }
  });
}

/*
 * IE 8 & 9 do not properly handle clicks on elements
 * with a `transparent` `background-color`.
 *
 * https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer
 */
const browsersWithTransparentBug = new Set(['ie 8', 'ie 9']);
const mathFunctions = new Set(['calc', 'min', 'max', 'clamp']);

/**
 * @param {valueParser.Node} node
 * @return {boolean}
 */
function isMathFunctionNode(node) {
  if (node.type !== 'function') {
    return false;
  }
  return mathFunctions.has(node.value.toLowerCase());
}

/**
 * @param {string} value
 * @param {Record<string, boolean>} options
 * @return {string}
 */
function transform(value, options) {
  const parsed = valueParser(value);

  walk(parsed, (node, index, parent) => {
    if (node.type === 'function') {
      if (/^(rgb|hsl)a?$/i.test(node.value)) {
        const { value: originalValue } = node;

        node.value = minifyColor(valueParser.stringify(node), options);
        /** @type {string} */ (node.type) = 'word';

        const next = parent.nodes[index + 1];

        if (
          node.value !== originalValue &&
          next &&
          (next.type === 'word' || next.type === 'function')
        ) {
          parent.nodes.splice(
            index + 1,
            0,
            /** @type {valueParser.SpaceNode} */ ({
              type: 'space',
              value: ' ',
            })
          );
        }
      } else if (isMathFunctionNode(node)) {
        return false;
      }
    } else if (node.type === 'word') {
      node.value = minifyColor(node.value, options);
    }
  });

  return parsed.toString();
}

/**
 * @param {Record<string, boolean>} options
 * @param {string[]} browsers
 * @return {Record<string, boolean>}
 */
function addPluginDefaults(options, browsers) {
  const defaults = {
    // Does the browser support 4 & 8 character hex notation
    transparent:
      browsers.some((b) => browsersWithTransparentBug.has(b)) === false,
    // Does the browser support "transparent" value properly
    alphaHex: isSupported('css-rrggbbaa', browsers),
    name: true,
  };
  return { ...defaults, ...options };
}
/**
 * @type {import('postcss').PluginCreator<Record<string, boolean>>}
 * @param {Record<string, boolean>} config
 * @return {import('postcss').Plugin}
 */
function pluginCreator(config = {}) {
  return {
    postcssPlugin: 'postcss-colormin',

    prepare(result) {
      /** @type {typeof result.opts & browserslist.Options} */
      const resultOptions = result.opts || {};
      const browsers = browserslist(null, {
        stats: resultOptions.stats,
        path: __dirname,
        env: resultOptions.env,
      });

      const cache = new Map();
      const options = addPluginDefaults(config, browsers);

      return {
        OnceExit(css) {
          css.walkDecls((decl) => {
            if (
              /^(composes|font|src$|filter|-webkit-tap-highlight-color)/i.test(
                decl.prop
              )
            ) {
              return;
            }

            const value = decl.value;

            if (!value) {
              return;
            }

            const cacheKey = JSON.stringify({ value, options, browsers });

            if (cache.has(cacheKey)) {
              decl.value = cache.get(cacheKey);

              return;
            }

            const newValue = transform(value, options);

            decl.value = newValue;
            cache.set(cacheKey, newValue);
          });
        },
      };
    },
  };
}

pluginCreator.postcss = true;
module.exports = pluginCreator;


code:
'use strict';
const { colord, extend } = require('colord');
const namesPlugin = require('colord/plugins/names');
const minifierPlugin = require('colord/plugins/minify');

extend(/** @type {any[]} */ ([namesPlugin, minifierPlugin]));

/**
 * Performs color value minification
 *
 * @param {string} input - CSS value
 * @param {Record<string, boolean>} options  object with colord.minify() options
 * @return {string}
 */
module.exports = function minifyColor(input, options = {}) {
  const instance = colord(input);

  if (instance.isValid()) {
    // Try to shorten the string if it is a valid CSS color value
    const minified = instance.minify(options);

    // Fall back to the original input if it's smaller or has equal length
    return minified.length < input.length ? minified : input.toLowerCase();
  } else {
    // Possibly malformed, so pass through
    return input;
  }
};


code:
export = pluginCreator;
/**
 * @type {import('postcss').PluginCreator<Record<string, boolean>>}
 * @param {Record<string, boolean>} config
 * @return {import('postcss').Plugin}
 */
declare function pluginCreator(config?: Record<string, boolean>): import('postcss').Plugin;
declare namespace pluginCreator {
    const postcss: true;
}


code:
declare function _exports(input: string, options?: Record<string, boolean>): string;
export = _exports;


code:
# [postcss][postcss]-convert-values

> Convert values with PostCSS (e.g. ms -> s)

## Install

With [npm](https://npmjs.org/package/postcss-convert-values) do:

```
npm install postcss-convert-values --save
```

## Example

This plugin reduces CSS size by converting values to use different units
where possible; for example, `500ms` can be represented as `.5s`. You can
read more about these units in [this article][csstricks].

### Input

```css
h1 {
    font-size: 16px;
    width: 0em
}
```

### Output

```css
h1 {
    font-size: 1pc;
    width: 0
}
```

Note that this plugin only covers conversions for duration and absolute length
values. For color conversions, use [postcss-colormin][colormin].

## API

### convertValues([options])

#### options

##### length

Type: `boolean`
Default: `true`

Pass `false` to disable conversion from `px` to other absolute length units,
such as `pc` & `pt` & vice versa.

##### time

Type: `boolean`
Default: `true`

Pass `false` to disable conversion from `ms` to `s` & vice versa.

##### angle

Type: `boolean`
Default: `true`

Pass `false` to disable conversion from `deg` to `turn` & vice versa.

##### precision

Type: `boolean|number`
Default: `false`

Specify any numeric value here to round `px` values to that many decimal places;
for example, using `{precision: 2}` will round `6.66667px` to `6.67px`, and
`{precision: 0}` will round it to `7px`. Passing `false` (the default) will
leave these values as is.

It is recommended for most use cases to set this option to `2`.

## Usage

See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
examples for your environment.

## Contributors

See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).

## License

MIT © [Ben Briggs](http://beneb.info)

[postcss]: https://github.com/postcss/postcss
[csstricks]: https://css-tricks.com/the-lengths-of-css/


postcss-convert-values

description: Convert values with PostCSS (e.g. ms -> s)

files: LICENSE-MIT src types

keywords: css optimisation postcss postcss-plugin


code:
'use strict';
const valueParser = require('postcss-value-parser');
const browserslist = require('browserslist');
const convert = require('./lib/convert.js');

const LENGTH_UNITS = new Set([
  'em',
  'ex',
  'ch',
  'rem',
  'vw',
  'vh',
  'vmin',
  'vmax',
  'cm',
  'mm',
  'q',
  'in',
  'pt',
  'pc',
  'px',
]);

// These properties only accept percentages, so no point in trying to transform
const notALength = new Set([
  'descent-override',
  'ascent-override',
  'font-stretch',
  'size-adjust',
  'line-gap-override',
]);

// Can't change the unit on these properties when they're 0
const keepWhenZero = new Set([
  'stroke-dashoffset',
  'stroke-width',
  'line-height',
]);

// Can't remove the % on these properties when they're 0 on IE 11
const keepZeroPercent = new Set(['max-height', 'height', 'min-width']);

/**
 * Numbers without digits after the dot are technically invalid,
 * but in that case css-value-parser returns the dot as part of the unit,
 * so we use this to remove the dot.
 *
 * @param {string} item
 * @return {string}
 */
function stripLeadingDot(item) {
  if (item.charCodeAt(0) === '.'.charCodeAt(0)) {
    return item.slice(1);
  } else {
    return item;
  }
}

/**
 * @param {valueParser.Node} node
 * @param {Options} opts
 * @param {boolean} keepZeroUnit
 * @return {void}
 */
function parseWord(node, opts, keepZeroUnit) {
  const pair = valueParser.unit(node.value);
  if (pair) {
    const num = Number(pair.number);
    const u = stripLeadingDot(pair.unit);
    if (num === 0) {
      node.value =
        0 +
        (keepZeroUnit || (!LENGTH_UNITS.has(u.toLowerCase()) && u !== '%')
          ? u
          : '');
    } else {
      node.value = convert(num, u, opts);

      if (
        typeof opts.precision === 'number' &&
        u.toLowerCase() === 'px' &&
        pair.number.includes('.')
      ) {
        const precision = Math.pow(10, opts.precision);
        node.value =
          Math.round(parseFloat(node.value) * precision) / precision + u;
      }
    }
  }
}

/**
 * @param {valueParser.WordNode} node
 * @return {void}
 */
function clampOpacity(node) {
  const pair = valueParser.unit(node.value);
  if (!pair) {
    return;
  }
  let num = Number(pair.number);
  if (num > 1) {
    node.value = pair.unit === '%' ? num + pair.unit : 1 + pair.unit;
  } else if (num < 0) {
    node.value = 0 + pair.unit;
  }
}

/**
 * @param {import('postcss').Declaration} decl
 * @param {string[]} browsers
 * @return {boolean}
 */
function shouldKeepZeroUnit(decl, browsers) {
  const { parent } = decl;
  const lowerCasedProp = decl.prop.toLowerCase();
  return (
    (decl.value.includes('%') &&
      keepZeroPercent.has(lowerCasedProp) &&
      browsers.includes('ie 11')) ||
    (parent &&
      parent.parent &&
      parent.parent.type === 'atrule' &&
      /** @type {import('postcss').AtRule} */ (
        parent.parent
      ).name.toLowerCase() === 'keyframes' &&
      lowerCasedProp === 'stroke-dasharray') ||
    keepWhenZero.has(lowerCasedProp)
  );
}
/**
 * @param {Options} opts
 * @param {string[]} browsers
 * @param {import('postcss').Declaration} decl
 * @return {void}
 */
function transform(opts, browsers, decl) {
  const lowerCasedProp = decl.prop.toLowerCase();
  if (
    lowerCasedProp.includes('flex') ||
    lowerCasedProp.indexOf('--') === 0 ||
    notALength.has(lowerCasedProp)
  ) {
    return;
  }

  decl.value = valueParser(decl.value)
    .walk((node) => {
      const lowerCasedValue = node.value.toLowerCase();

      if (node.type === 'word') {
        parseWord(node, opts, shouldKeepZeroUnit(decl, browsers));
        if (
          lowerCasedProp === 'opacity' ||
          lowerCasedProp === 'shape-image-threshold'
        ) {
          clampOpacity(node);
        }
      } else if (node.type === 'function') {
        if (
          lowerCasedValue === 'calc' ||
          lowerCasedValue === 'min' ||
          lowerCasedValue === 'max' ||
          lowerCasedValue === 'clamp' ||
          lowerCasedValue === 'hsl' ||
          lowerCasedValue === 'hsla'
        ) {
          valueParser.walk(node.nodes, (n) => {
            if (n.type === 'word') {
              parseWord(n, opts, true);
            }
          });
          return false;
        }
        if (lowerCasedValue === 'url') {
          return false;
        }
      }
    })
    .toString();
}

const plugin = 'postcss-convert-values';
/**
 * @typedef {{precision: boolean | number, angle?: boolean, time?: boolean, length?: boolean} & browserslist.Options} Options */
/**
 * @type {import('postcss').PluginCreator<Options>}
 * @param {Options} opts
 * @return {import('postcss').Plugin}
 */
function pluginCreator(opts = { precision: false }) {
  const browsers = browserslist(null, {
    stats: opts.stats,
    path: __dirname,
    env: opts.env,
  });

  return {
    postcssPlugin: plugin,
    OnceExit(css) {
      css.walkDecls((decl) => transform(opts, browsers, decl));
    },
  };
}

pluginCreator.postcss = true;
module.exports = pluginCreator;


code:
'use strict';
const lengthConv = new Map([
  ['in', 96],
  ['px', 1],
  ['pt', 4 / 3],
  ['pc', 16],
]);

const timeConv = new Map([
  ['s', 1000],
  ['ms', 1],
]);

const angleConv = new Map([
  ['turn', 360],
  ['deg', 1],
]);
/**
 * @param {number} number
 * @return {string}
 */
function dropLeadingZero(number) {
  const value = String(number);

  if (number % 1) {
    if (value[0] === '0') {
      return value.slice(1);
    }

    if (value[0] === '-' && value[1] === '0') {
      return '-' + value.slice(2);
    }
  }

  return value;
}
/**
 * @param {number} number
 * @param {string} originalUnit
 * @param {lengthConv | timeConv | angleConv} conversions
 * @return {string}
 */
function transform(number, originalUnit, conversions) {
  let conversionUnits = [...conversions.keys()].filter((u) => {
    return originalUnit !== u;
  });

  const base = number * /** @type {number} */ (conversions.get(originalUnit));

  return conversionUnits
    .map(
      (u) =>
        dropLeadingZero(base / /** @type {number} */ (conversions.get(u))) + u
    )
    .reduce((a, b) => (a.length < b.length ? a : b));
}

/**
 * @param {number} number
 * @param {string} unit
 * @param {{time?: boolean, length?: boolean, angle?: boolean}} options
 * @return {string}
 */
module.exports = function (number, unit, { time, length, angle }) {
  let value = dropLeadingZero(number) + (unit ? unit : '');
  let converted;
  const lowerCaseUnit = unit.toLowerCase();
  if (length !== false && lengthConv.has(lowerCaseUnit)) {
    converted = transform(number, lowerCaseUnit, lengthConv);
  }

  if (time !== false && timeConv.has(lowerCaseUnit)) {
    converted = transform(number, lowerCaseUnit, timeConv);
  }

  if (angle !== false && angleConv.has(lowerCaseUnit)) {
    converted = transform(number, lowerCaseUnit, angleConv);
  }

  if (converted && converted.length < value.length) {
    value = converted;
  }

  return value;
};


code:
export = pluginCreator;
/**
 * @typedef {{precision: boolean | number, angle?: boolean, time?: boolean, length?: boolean} & browserslist.Options} Options */
/**
 * @type {import('postcss').PluginCreator<Options>}
 * @param {Options} opts
 * @return {import('postcss').Plugin}
 */
declare function pluginCreator(opts?: Options): import('postcss').Plugin;
declare namespace pluginCreator {
    export { postcss, Options };
}
type Options = {
    precision: boolean | number;
    angle?: boolean;
    time?: boolean;
    length?: boolean;
} & browserslist.Options;
declare var postcss: true;
import browserslist = require("browserslist");


code:
declare function _exports(number: number, unit: string, { time, length, angle }: {
    time?: boolean;
    length?: boolean;
    angle?: boolean;
}): string;
export = _exports;


code:
# [postcss][postcss]-discard-comments

> Discard comments in your CSS files with PostCSS.

## Install

With [npm](https://npmjs.org/package/postcss-discard-comments) do:

```
npm install postcss-discard-comments --save
```

## Example

### Input

```css
h1/* heading */{
    margin: 0 auto
}
```

### Output

```css
h1 {
    margin: 0 auto
}
```

This module discards comments from your CSS files; by default, it will remove
all regular comments (`/* comment */`) and preserve comments marked as important
(`/*! important */`).

Note that this module does not handle source map comments because they are not
available to it; PostCSS handles this internally, so if they are removed then
you will have to [configure source maps in PostCSS][maps].

[maps]: https://github.com/postcss/postcss/blob/master/docs/source-maps.md

## API

### comments([options])

#### options

##### remove(function)

Type: `function`
Return: `boolean`
Variable: `comment` contains a comment without `/**/`

For each comment, return true to remove, or false to keep the comment.

```js
function(comment) {}
```

```js
var css = '/* headings *//*@ h1 */h1{margin:0 auto}/*@ h2 */h2{color:red}';
console.log(postcss(comments({
    remove: function(comment) { return comment[0] == "@"; }
})).process(css).css);
//=> /* headings */h1{margin:0 auto}h2{color:red}
```
**NOTE:** If you use the `remove` function other options will not be available.

##### removeAll

Type: `boolean`
Default: `false`

Remove all comments marked as important.

```js
var css = '/*! heading */h1{margin:0 auto}/*! heading 2 */h2{color:red}';
console.log(postcss(comments({removeAll: true})).process(css).css);
//=> h1{margin:0 auto}h2{color:red}
```

##### removeAllButFirst

Type: `boolean`
Default: `false`

Remove all comments marked as important, but the first one.

```js
var css = '/*! heading */h1{margin:0 auto}/*! heading 2 */h2{color:red}';
console.log(postcss(comments({removeAllButFirst: true})).process(css).css);
//=> /*! heading */h1{margin:0 auto}h2{color:red}
```

## Usage

See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
examples for your environment.

## Contributors

See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).

## License

MIT © [Ben Briggs](http://beneb.info)

[postcss]: https://github.com/postcss/postcss


postcss-discard-comments

description: Discard comments in your CSS files with PostCSS.

keywords: css comments postcss postcss-plugin


code:
'use strict';
const CommentRemover = require('./lib/commentRemover');
const commentParser = require('./lib/commentParser');

/** @typedef {object} Options
 *  @property {boolean=} removeAll
 *  @property {boolean=} removeAllButFirst
 *  @property {(s: string) => boolean=} remove
 */
/**
 * @type {import('postcss').PluginCreator<Options>}
 * @param {Options} opts
 * @return {import('postcss').Plugin}
 */
function pluginCreator(opts = {}) {
  const remover = new CommentRemover(opts);
  const matcherCache = new Map();
  const replacerCache = new Map();

  /**
   * @param {string} source
   * @return {[number, number, number][]}
   */
  function matchesComments(source) {
    if (matcherCache.has(source)) {
      return matcherCache.get(source);
    }

    const result = commentParser(source).filter(([type]) => type);

    matcherCache.set(source, result);

    return result;
  }

  /**
   * @param {string} source
   * @param {(s: string) => string[]} space
   * @return {string}
   */
  function replaceComments(source, space, separator = ' ') {
    const key = source + '@|@' + separator;

    if (replacerCache.has(key)) {
      return replacerCache.get(key);
    }
    const parsed = commentParser(source).reduce((value, [type, start, end]) => {
      const contents = source.slice(start, end);

      if (!type) {
        return value + contents;
      }

      if (remover.canRemove(contents)) {
        return value + separator;
      }

      return `${value}/*${contents}*/`;
    }, '');

    const result = space(parsed).join(' ');

    replacerCache.set(key, result);

    return result;
  }

  return {
    postcssPlugin: 'postcss-discard-comments',

    OnceExit(css, { list }) {
      css.walk((node) => {
        if (node.type === 'comment' && remover.canRemove(node.text)) {
          node.remove();

          return;
        }

        if (typeof node.raws.between === 'string') {
          node.raws.between = replaceComments(node.raws.between, list.space);
        }

        if (node.type === 'decl') {
          if (node.raws.value && node.raws.value.raw) {
            if (node.raws.value.value === node.value) {
              node.value = replaceComments(node.raws.value.raw, list.space);
            } else {
              node.value = replaceComments(node.value, list.space);
            }

            /** @type {null | {value: string, raw: string}} */ (
              node.raws.value
            ) = null;
          }

          if (node.raws.important) {
            node.raws.important = replaceComments(
              node.raws.important,
              list.space
            );

            const b = matchesComments(node.raws.important);

            node.raws.important = b.length ? node.raws.important : '!important';
          } else {
            node.value = replaceComments(node.value, list.space);
          }

          return;
        }

        if (
          node.type === 'rule' &&
          node.raws.selector &&
          node.raws.selector.raw
        ) {
          node.raws.selector.raw = replaceComments(
            node.raws.selector.raw,
            list.space,
            ''
          );

          return;
        }

        if (node.type === 'atrule') {
          if (node.raws.afterName) {
            const commentsReplaced = replaceComments(
              node.raws.afterName,
              list.space
            );

            if (!commentsReplaced.length) {
              node.raws.afterName = commentsReplaced + ' ';
            } else {
              node.raws.afterName = ' ' + commentsReplaced + ' ';
            }
          }

          if (node.raws.params && node.raws.params.raw) {
            node.raws.params.raw = replaceComments(
              node.raws.params.raw,
              list.space
            );
          }
        }
      });
    },
  };
}

pluginCreator.postcss = true;
module.exports = pluginCreator;


code:
'use strict';

/**
 * @param {string} input
 * @return {[number, number, number][]}
 */
module.exports = function commentParser(input) {
  /** @type [number, number, number][] */
  const tokens = [];
  const length = input.length;
  let pos = 0;
  let next;

  while (pos < length) {
    next = input.indexOf('/*', pos);

    if (~next) {
      tokens.push([0, pos, next]);
      pos = next;

      next = input.indexOf('*/', pos + 2);
      tokens.push([1, pos + 2, next]);
      pos = next + 2;
    } else {
      tokens.push([0, pos, length]);
      pos = length;
    }
  }

  return tokens;
};


code:
'use strict';

/** @param {import('../index.js').Options} options */
function CommentRemover(options) {
  this.options = options;
}
/**
 * @param {string} comment
 * @return {boolean | undefined}
 */
CommentRemover.prototype.canRemove = function (comment) {
  const remove = this.options.remove;

  if (remove) {
    return remove(comment);
  } else {
    const isImportant = comment.indexOf('!') === 0;

    if (!isImportant) {
      return true;
    }

    if (this.options.removeAll || this._hasFirst) {
      return true;
    } else if (this.options.removeAllButFirst && !this._hasFirst) {
      this._hasFirst = true;
      return false;
    }
  }
};

module.exports = CommentRemover;


code:
export = pluginCreator;
/** @typedef {object} Options
 *  @property {boolean=} removeAll
 *  @property {boolean=} removeAllButFirst
 *  @property {(s: string) => boolean=} remove
 */
/**
 * @type {import('postcss').PluginCreator<Options>}
 * @param {Options} opts
 * @return {import('postcss').Plugin}
 */
declare function pluginCreator(opts?: Options): import('postcss').Plugin;
declare namespace pluginCreator {
    export { postcss, Options };
}
type Options = {
    removeAll?: boolean | undefined;
    removeAllButFirst?: boolean | undefined;
    remove?: ((s: string) => boolean) | undefined;
};
declare var postcss: true;


code:
declare function _exports(input: string): [number, number, number][];
export = _exports;


code:
export = CommentRemover;
/** @param {import('../index.js').Options} options */
declare function CommentRemover(options: import('../index.js').Options): void;
declare class CommentRemover {
    /** @param {import('../index.js').Options} options */
    constructor(options: import('../index.js').Options);
    options: import("../index.js").Options;
    /**
     * @param {string} comment
     * @return {boolean | undefined}
     */
    canRemove(comment: string): boolean | undefined;
    _hasFirst: boolean | undefined;
}


code:
Copyright (c) Ben Briggs <beneb.info@gmail.com> (http://beneb.info)

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


code:
# [postcss][postcss]-discard-duplicates

> Discard duplicate rules in your CSS files with PostCSS.

## Install

With [npm](https://npmjs.org/package/postcss-discard-duplicates) do:

```
npm install postcss-discard-duplicates --save
```

## Example

This module will remove all duplicate rules from your stylesheets. It works on
at rules, normal rules and declarations. Note that this module does not have any
responsibility for normalising declarations, selectors or whitespace, so that it
considers these two rules to be different:

```css
h1, h2 {
    color: blue;
}

h2, h1 {
    color: blue;
}
```

It has to assume that your rules have already been transformed by another
processor, otherwise it would be responsible for too many things.

### Input

```css
h1 {
    margin: 0 auto;
    margin: 0 auto
}

h1 {
    margin: 0 auto
}
```

### Output

```css
h1 {
    margin: 0 auto
}
```

## Usage

See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
examples for your environment.

## Contributors

See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).

## License

MIT © [Ben Briggs](http://beneb.info)

[postcss]: https://github.com/postcss/postcss


code:
'use strict';
/**
 * @param {string | undefined} value
 * @return {string | undefined}
 */
function trimValue(value) {
  return value ? value.trim() : value;
}

/**
 * @param {{nodes: import('postcss').Node[]}} node
 * @return {boolean}
 */
function empty(node) {
  return !node.nodes.filter((child) => child.type !== 'comment').length;
}

/**
 * @param {import('postcss').AnyNode} nodeA
 * @param {import('postcss').AnyNode} nodeB
 * @return {boolean}
 */
function equals(nodeA, nodeB) {
  const a = /** @type {any} */ (nodeA);
  const b = /** @type {any} */ (nodeB);
  if (a.type !== b.type) {
    return false;
  }

  if (a.important !== b.important) {
    return false;
  }

  if ((a.raws && !b.raws) || (!a.raws && b.raws)) {
    return false;
  }

  switch (a.type) {
    case 'rule':
      if (a.selector !== b.selector) {
        return false;
      }
      break;
    case 'atrule':
      if (a.name !== b.name || a.params !== b.params) {
        return false;
      }

      if (a.raws && trimValue(a.raws.before) !== trimValue(b.raws.before)) {
        return false;
      }

      if (
        a.raws &&
        trimValue(a.raws.afterName) !== trimValue(b.raws.afterName)
      ) {
        return false;
      }
      break;
    case 'decl':
      if (a.prop !== b.prop || a.value !== b.value) {
        return false;
      }

      if (a.raws && trimValue(a.raws.before) !== trimValue(b.raws.before)) {
        return false;
      }
      break;
  }

  if (a.nodes) {
    if (a.nodes.length !== b.nodes.length) {
      return false;
    }

    for (let i = 0; i < a.nodes.length; i++) {
      if (!equals(a.nodes[i], b.nodes[i])) {
        return false;
      }
    }
  }
  return true;
}

/**
 * @param {import('postcss').Rule} last
 * @param {import('postcss').AnyNode[]} nodes
 * @return {void}
 */
function dedupeRule(last, nodes) {
  let index = nodes.indexOf(last) - 1;
  while (index >= 0) {
    const node = nodes[index--];
    if (node && node.type === 'rule' && node.selector === last.selector) {
      last.each((child) => {
        if (child.type === 'decl') {
          dedupeNode(child, node.nodes);
        }
      });

      if (empty(node)) {
        node.remove();
      }
    }
  }
}

/**
 * @param {import('postcss').AtRule | import('postcss').Declaration} last
 * @param {import('postcss').AnyNode[]} nodes
 * @return {void}
 */
function dedupeNode(last, nodes) {
  let index = nodes.includes(last) ? nodes.indexOf(last) - 1 : nodes.length - 1;

  while (index >= 0) {
    const node = nodes[index--];
    if (node && equals(node, last)) {
      node.remove();
    }
  }
}

/**
 * @param {import('postcss').AnyNode} root
 * @return {void}
 */
function dedupe(root) {
  const { nodes } =
    /** @type {import('postcss').Container<import('postcss').ChildNode>} */ (
      root
    );

  if (!nodes) {
    return;
  }

  let index = nodes.length - 1;
  while (index >= 0) {
    let last = nodes[index--];
    if (!last || !last.parent) {
      continue;
    }
    dedupe(last);
    if (last.type === 'rule') {
      dedupeRule(last, nodes);
    } else if (last.type === 'atrule' || last.type === 'decl') {
      dedupeNode(last, nodes);
    }
  }
}

/**
 * @type {import('postcss').PluginCreator<void>}
 * @return {import('postcss').Plugin}
 */
function pluginCreator() {
  return {
    postcssPlugin: 'postcss-discard-duplicates',
    OnceExit(css) {
      dedupe(css);
    },
  };
}

pluginCreator.postcss = true;
module.exports = pluginCreator;


code:
export = pluginCreator;
/**
 * @type {import('postcss').PluginCreator<void>}
 * @return {import('postcss').Plugin}
 */
declare function pluginCreator(): import('postcss').Plugin;
declare namespace pluginCreator {
    const postcss: true;
}


code:
# [postcss][postcss]-discard-empty

> Discard empty rules and values with PostCSS.

## Install

With [npm](https://npmjs.org/package/postcss-discard-empty) do:

```
npm install postcss-discard-empty --save
```

## Example

For more examples see the [tests](src/__tests__/index.js).

### Input

```css
@font-face;
h1 {}
{color:blue}
h2 {color:}
h3 {color:red}
```

### Output

```css
h3 {color:red}
```

## Usage

See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
examples for your environment.

## Contributors

See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).

## License

MIT © [Ben Briggs](http://beneb.info)

[postcss]: https://github.com/postcss/postcss


postcss-discard-empty

keywords: compress css empty minify optimisation postcss postcss-plugin

readme:
# [postcss][postcss]-discard-empty

> Discard empty rules and values with PostCSS.

## Install

With [npm](https://npmjs.org/package/postcss-discard-empty) do:

```
npm install postcss-discard-empty --save
```

## Example

For more examples see the [tests](src/__tests__/index.js).

### Input

```css
@font-face;
h1 {}
{color:blue}
h2 {color:}
h3 {color:red}
```

### Output

```css
h3 {color:red}
```

## Usage

See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
examples for your environment.

## Contributors

See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).

## License

MIT © [Ben Briggs](http://beneb.info)

[postcss]: https://github.com/postcss/postcss


code:
'use strict';
const plugin = 'postcss-discard-empty';
/**
 * @param {import('postcss').Root} css
 * @param {import('postcss').Result} result
 * @return {void}
 */
function discardAndReport(css, result) {
  /**
   * @param {import('postcss').AnyNode} node
   * @return {void}
   */
  function discardEmpty(node) {
    const { type } = node;
    /** @type {(import('postcss').ChildNode | import('postcss').ChildProps)[] | undefined} */
    const sub = /** @type {any} */ (node).nodes;
    if (sub) {
      /** @type {import('postcss').Container} */ (node).each(discardEmpty);
    }

    if (
      (type === 'decl' && !node.value && !node.prop.startsWith('--')) ||
      (type === 'rule' && !node.selector) ||
      (sub && !sub.length) ||
      (type === 'atrule' &&
        ((!sub && !node.params) ||
          (!node.params &&
            !(/** @type {import('postcss').ChildNode[]}*/ (sub).length))))
    ) {
      node.remove();

      result.messages.push({
        type: 'removal',
        plugin,
        node,
      });
    }
  }

  css.each(discardEmpty);
}

/**
 * @type {import('postcss').PluginCreator<void>}
 * @return {import('postcss').Plugin}
 */
function pluginCreator() {
  return {
    postcssPlugin: plugin,
    OnceExit(css, { result }) {
      discardAndReport(css, result);
    },
  };
}

pluginCreator.postcss = true;
module.exports = pluginCreator;


code:
# PostCSS Discard Overridden

[PostCSS] plugin to discard overridden `@keyframes` or `@counter-style`.

`@keyframes` or `@counter-style` will be overridden by those who share the same identifiers and appear later in stylesheets. So we can discard all of them except the last one. When defined inside a `@media` or `@supports` rule, `@keyframes` and `@counter-style` rules only override global rules in some of the client browsers so they need handled separately. This plugin has taken care of this and transforms the PostCss AST **safely**.

[PostCSS]: https://github.com/postcss/postcss

```css
@-webkit-keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.8;
  }
}
@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.8;
  }
}
@media (max-width: 500px) {
  @-webkit-keyframes fade-in {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
  @keyframes fade-in {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
  @-webkit-keyframes fade-in {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 0.8;
    }
  }
  @keyframes fade-in {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 0.8;
    }
  }
  @supports (display: flex) {
    @-webkit-keyframes fade-in {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }
    @keyframes fade-in {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }
  }
}
@-webkit-keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
```

```css
@media (max-width: 500px) {
  @-webkit-keyframes fade-in {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 0.8;
    }
  }
  @keyframes fade-in {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 0.8;
    }
  }
  @supports (display: flex) {
    @-webkit-keyframes fade-in {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }
    @keyframes fade-in {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }
  }
}
@-webkit-keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
```

## Usage

See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
examples for your environment.

## Contributors

See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).


code:
'use strict';
const OVERRIDABLE_RULES = new Set(['keyframes', 'counter-style']);
const SCOPE_RULES = new Set(['media', 'supports']);

/**
 * @param {string} prop
 * @return {string}
 */
function vendorUnprefixed(prop) {
  return prop.replace(/^-\w+-/, '');
}

/**
 * @param {string} name
 * @return {boolean}
 */
function isOverridable(name) {
  return OVERRIDABLE_RULES.has(vendorUnprefixed(name.toLowerCase()));
}

/**
 * @param {string} name
 * @return {boolean}
 */
function isScope(name) {
  return SCOPE_RULES.has(vendorUnprefixed(name.toLowerCase()));
}

/**
 * @param {import('postcss').AtRule} node
 * @return {string}
 */
function getScope(node) {
  /** @type {import('postcss').Container<import('postcss').ChildNode> | import('postcss').Document | undefined} */
  let current = node.parent;

  const chain = [node.name.toLowerCase(), node.params];

  while (current) {
    if (
      current.type === 'atrule' &&
      isScope(/** @type import('postcss').AtRule */ (current).name)
    ) {
      chain.unshift(
        /** @type import('postcss').AtRule */ (current).name +
          ' ' +
          /** @type import('postcss').AtRule */ (current).params
      );
    }
    current = current.parent;
  }

  return chain.join('|');
}

/**
 * @type {import('postcss').PluginCreator<void>}
 * @return {import('postcss').Plugin}
 */
function pluginCreator() {
  return {
    postcssPlugin: 'postcss-discard-overridden',
    prepare() {
      const cache = new Map();
      /** @type {{node: import('postcss').AtRule, scope: string}[]} */
      const rules = [];

      return {
        OnceExit(css) {
          css.walkAtRules((node) => {
            if (isOverridable(node.name)) {
              const scope = getScope(node);

              cache.set(scope, node);
              rules.push({
                node,
                scope,
              });
            }
          });

          rules.forEach((rule) => {
            if (cache.get(rule.scope) !== rule.node) {
              rule.node.remove();
            }
          });
        },
      };
    },
  };
}

pluginCreator.postcss = true;
module.exports = pluginCreator;


code:
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![size][size]][size-url]

Webpack chat: [![chat][chat]][chat-url]

PostCSS chat: [![chat-postcss][chat-postcss]][chat-postcss-url]

# postcss-loader

Loader to process CSS with [`PostCSS`](https://github.com/postcss/postcss).

## Getting Started

You need webpack v5 to use the latest version. For Webpack v4, you have to install postcss-loader v4.

To begin, you'll need to install `postcss-loader` and `postcss`:

```console
npm install --save-dev postcss-loader postcss
```

Then add the plugin to your `webpack` config. For example:

> In the following configuration the plugin [`postcss-preset-env`](https://github.com/csstools/postcss-preset-env) is used, which is not installed by default.

**file.js**

```js
import css from "file.css";
```

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env",
                    {
                      // Options
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};
```

Alternative use with [config files](#config):

**postcss.config.js**

```js
module.exports = {
  plugins: [
    [
      "postcss-preset-env",
      {
        // Options
      },
    ],
  ],
};
```

The loader **automatically** searches for configuration files.

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader", "postcss-loader"],
      },
    ],
  },
};
```

And run `webpack` via your preferred method.

## Options

|                Name                 |         Type         |                Default                | Description                                  |
| :---------------------------------: | :------------------: | :-----------------------------------: | :------------------------------------------- |
|        [`execute`](#execute)        |     `{Boolean}`      |              `undefined`              | Enable PostCSS Parser support in `CSS-in-JS` |
| [`postcssOptions`](#postcssOptions) | `{Object\|Function}` | `defaults values for Postcss.process` | Set `PostCSS` options and plugins            |
|      [`sourceMap`](#sourcemap)      |     `{Boolean}`      |          `compiler.devtool`           | Enables/Disables generation of source maps   |
| [`implementation`](#implementation) | `{Function\|String}` |               `postcss`               | Setup PostCSS implementation to use          |

### `execute`

Type: `Boolean`
Default: `undefined`

If you use JS styles the [`postcss-js`](https://github.com/postcss/postcss-js) parser, add the `execute` option.

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.style.js$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                parser: "postcss-js",
              },
              execute: true,
            },
          },
        ],
      },
    ],
  },
};
```

### `postcssOptions`

Type: `Object|Function`
Default: `undefined`

Allows to set [`PostCSS options`](https://postcss.org/api/#processoptions) and plugins.

All `PostCSS` options are supported.
There is the special `config` option for config files. How it works and how it can be configured is described below.

We recommend do not specify `from`, `to` and `map` options, because this can lead to wrong path in source maps.
If you need source maps please use the [`sourcemap`](#sourcemap) option.

#### `Object`

Setup `plugins`:

**webpack.config.js** (**recommended**)

```js
const myOtherPostcssPlugin = require("postcss-my-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            plugins: [
              "postcss-import",
              ["postcss-short", { prefix: "x" }],
              require.resolve("my-postcss-plugin"),
              myOtherPostcssPlugin({ myOption: true }),
              // Deprecated and will be removed in the next major release
              { "postcss-nested": { preserveEmpty: true } },
            ],
          },
        },
      },
    ],
  },
};
```

**webpack.config.js** (**deprecated**, will be removed in the next major release)

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            plugins: {
              "postcss-import": {},
              "postcss-short": { prefix: "x" },
            },
          },
        },
      },
    ],
  },
};
```

Setup `syntax`:

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            // Can be `String`
            syntax: "sugarss",
            // Can be `Object`
            syntax: require("sugarss"),
          },
        },
      },
    ],
  },
};
```

Setup `parser`:

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            // Can be `String`
            parser: "sugarss",
            // Can be `Object`
            parser: require("sugarss"),
            // Can be `Function`
            parser: require("sugarss").parse,
          },
        },
      },
    ],
  },
};
```

Setup `stringifier`:

**webpack.config.js**

```js
const Midas = require("midas");
const midas = new Midas();

module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            // Can be `String`
            stringifier: "sugarss",
            // Can be `Object`
            stringifier: require("sugarss"),
            // Can be `Function`
            stringifier: midas.stringifier,
          },
        },
      },
    ],
  },
};
```

#### `Function`

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(css|sss)$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: (loaderContext) => {
            if (/\.sss$/.test(loaderContext.resourcePath)) {
              return {
                parser: "sugarss",
                plugins: [
                  ["postcss-short", { prefix: "x" }],
                  "postcss-preset-env",
                ],
              };
            }

            return {
              plugins: [
                ["postcss-short", { prefix: "x" }],
                "postcss-preset-env",
              ],
            };
          },
        },
      },
    ],
  },
};
```

#### `config`

Type: `Boolean|String`
Default: `undefined`

Allows to set options using config files.
Options specified in the config file are combined with options passed to the loader, the loader options overwrite options from config.

##### Config Files

The loader will search up the directory tree for configuration in the following places:

- a `postcss` property in `package.json`
- a `.postcssrc` file in JSON or YAML format
- a `.postcssrc.json`, `.postcssrc.yaml`, `.postcssrc.yml`, `.postcssrc.js`, or `.postcssrc.cjs` file
- a `postcss.config.js` or `postcss.config.cjs` CommonJS module exporting an object (**recommended**)

##### Examples of Config Files

Using `Object` notation:

**postcss.config.js** (**recommend**)

```js
module.exports = {
  // You can specify any options from https://postcss.org/api/#processoptions here
  // parser: 'sugarss',
  plugins: [
    // Plugins for PostCSS
    ["postcss-short", { prefix: "x" }],
    "postcss-preset-env",
  ],
};
```

Using `Function` notation:

**postcss.config.js** (**recommend**)

```js
module.exports = (api) => {
  // `api.file` - path to the file
  // `api.mode` - `mode` value of webpack, please read https://webpack.js.org/configuration/mode/
  // `api.webpackLoaderContext` - loader context for complex use cases
  // `api.env` - alias `api.mode` for compatibility with `postcss-cli`
  // `api.options` - the `postcssOptions` options

  if (/\.sss$/.test(api.file)) {
    return {
      // You can specify any options from https://postcss.org/api/#processoptions here
      parser: "sugarss",
      plugins: [
        // Plugins for PostCSS
        ["postcss-short", { prefix: "x" }],
        "postcss-preset-env",
      ],
    };
  }

  return {
    // You can specify any options from https://postcss.org/api/#processoptions here
    plugins: [
      // Plugins for PostCSS
      ["postcss-short", { prefix: "x" }],
      "postcss-preset-env",
    ],
  };
};
```

**postcss.config.js** (**deprecated**, will be removed in the next major release)

```js
module.exports = {
  // You can specify any options from https://postcss.org/api/#processoptions here
  // parser: 'sugarss',
  plugins: {
    // Plugins for PostCSS
    "postcss-short": { prefix: "x" },
    "postcss-preset-env": {},
  },
};
```

##### Config Cascade

You can use different `postcss.config.js` files in different directories.
Config lookup starts from `path.dirname(file)` and walks the file tree upwards until a config file is found.

```
|– components
| |– component
| | |– index.js
| | |– index.png
| | |– style.css (1)
| | |– postcss.config.js (1)
| |– component
| | |– index.js
| | |– image.png
| | |– style.css (2)
|
|– postcss.config.js (1 && 2 (recommended))
|– webpack.config.js
|
|– package.json
```

After setting up your `postcss.config.js`, add `postcss-loader` to your `webpack.config.js`.
You can use it standalone or in conjunction with `css-loader` (recommended).

Use it **before** `css-loader` and `style-loader`, but **after** other preprocessor loaders like e.g `sass|less|stylus-loader`, if you use any (since [webpack loaders evaluate right to left/bottom to top](https://webpack.js.org/concepts/loaders/#configuration)).

**webpack.config.js** (**recommended**)

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              importLoaders: 1,
            },
          },
          "postcss-loader",
        ],
      },
    ],
  },
};
```

#### Boolean

Enables/Disables autoloading config.

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            config: false,
          },
        },
      },
    ],
  },
};
```

#### String

Allows to specify the path to the config file.

**webpack.config.js**

```js
const path = require("path");

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            config: path.resolve(__dirname, "custom.config.js"),
          },
        },
      },
    ],
  },
};
```

### `sourceMap`

Type: `Boolean`
Default: depends on the `compiler.devtool` value

By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option.
All values enable source map generation except `eval` and `false` value.

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader", options: { sourceMap: true } },
          { loader: "postcss-loader", options: { sourceMap: true } },
          { loader: "sass-loader", options: { sourceMap: true } },
        ],
      },
    ],
  },
};
```

Alternative setup:

**webpack.config.js**

```js
module.exports = {
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader" },
          { loader: "postcss-loader" },
          { loader: "sass-loader" },
        ],
      },
    ],
  },
};
```

### `implementation`

Type: `Function | String`
Default: `postcss`

The special `implementation` option determines which implementation of PostCSS to use. Overrides the locally installed `peerDependency` version of `postcss`.

**This option is only really useful for downstream tooling authors to ease the PostCSS 7-to-8 transition.**

#### Function

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader" },
          {
            loader: "postcss-loader",
            options: { implementation: require("postcss") },
          },
          { loader: "sass-loader" },
        ],
      },
    ],
  },
};
```

#### String

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader" },
          {
            loader: "postcss-loader",
            options: { implementation: require.resolve("postcss") },
          },
          { loader: "sass-loader" },
        ],
      },
    ],
  },
};
```

## Examples

### SugarSS

You'll need to install `sugarss`:

```console
npm install --save-dev sugarss
```

Using [`SugarSS`](https://github.com/postcss/sugarss) syntax.

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: { importLoaders: 1 },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                parser: "sugarss",
              },
            },
          },
        ],
      },
    ],
  },
};
```

### Autoprefixer

You'll need to install `autoprefixer`:

```console
npm install --save-dev autoprefixer
```

Add vendor prefixes to CSS rules using [`autoprefixer`](https://github.com/postcss/autoprefixer).

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: { importLoaders: 1 },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "autoprefixer",
                    {
                      // Options
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};
```

> :warning: [`postcss-preset-env`](https://github.com/csstools/postcss-preset-env) includes [`autoprefixer`](https://github.com/postcss/autoprefixer), so adding it separately is not necessary if you already use the preset. More [information](https://github.com/csstools/postcss-preset-env#autoprefixer)

### PostCSS Preset Env

You'll need to install `postcss-preset-env`:

```console
npm install --save-dev postcss-preset-env
```

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: { importLoaders: 1 },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env",
                    {
                      // Options
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};
```

### CSS Modules

What is `CSS Modules`? Please [read](https://github.com/webpack-contrib/css-loader#modules).

No additional options required on the `postcss-loader` side.
To make them work properly, either add the `css-loader`’s `importLoaders` option.

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              modules: true,
              importLoaders: 1,
            },
          },
          "postcss-loader",
        ],
      },
    ],
  },
};
```

### CSS-in-JS and [`postcss-js`](https://github.com/postcss/postcss-js)

You'll need to install `postcss-js`:

```console
npm install --save-dev postcss-js
```

If you want to process styles written in JavaScript, use the [`postcss-js`](https://github.com/postcss/postcss-js) parser.

**webpack.config.js**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.style.js$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              importLoaders: 2,
            },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                parser: "postcss-js",
              },
              execute: true,
            },
          },
          "babel-loader",
        ],
      },
    ],
  },
};
```

As result you will be able to write styles in the following way

```js
import colors from "./styles/colors";

export default {
  ".menu": {
    color: colors.main,
    height: 25,
    "&_link": {
      color: "white",
    },
  },
};
```

> :warning: If you are using Babel you need to do the following in order for the setup to work

> 1. Add [`babel-plugin-add-module-exports`](https://github.com/59naga/babel-plugin-add-module-exports) to your configuration.
> 2. You need to have only one **default** export per style module.

### Extract CSS

Using [`mini-css-extract-plugin`](https://github.com/webpack-contrib/mini-css-extract-plugin).

**webpack.config.js**

```js
const isProductionMode = process.env.NODE_ENV === "production";

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  mode: isProductionMode ? "production" : "development",
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          isProductionMode ? MiniCssExtractPlugin.loader : "style-loader",
          "css-loader",
          "postcss-loader",
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: isProductionMode ? "[name].[contenthash].css" : "[name].css",
    }),
  ],
};
```

### Emit assets

To write a asset from PostCSS plugin to the webpack, need to add a message in `result.messages`.

The message should contain the following fields:

- `type` = `asset` - Message type (require, should be equal `asset`)
- `file` - file name (require)
- `content` - file content (require)
- `sourceMap` - sourceMap
- `info` - asset info

**webpack.config.js**

```js
const customPlugin = () => (css, result) => {
  result.messages.push({
    type: "asset",
    file: "sprite.svg",
    content: "<svg>...</svg>",
  });
};

const postcssPlugin = postcss.plugin("postcss-assets", customPlugin);

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [postcssPlugin()],
              },
            },
          },
        ],
      },
    ],
  },
};
```

### Add dependencies, contextDependencies, buildDependencies, missingDependencies

The dependencies are necessary for webpack to understand when it needs to run recompilation on the changed files.

There are two way to add dependencies:

1. (Recommended). The plugin may emit messages in `result.messages`.

The message should contain the following fields:

- `type` = `dependency` - Message type (require, should be equal `dependency`, `context-dependency`, `build-dependency` or `missing-dependency`)
- `file` - absolute file path (require)

**webpack.config.js**

```js
const path = require("path");

const customPlugin = () => (css, result) => {
  result.messages.push({
    type: "dependency",
    file: path.resolve(__dirname, "path", "to", "file"),
  });
};

const postcssPlugin = postcss.plugin("postcss-assets", customPlugin);

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [postcssPlugin()],
              },
            },
          },
        ],
      },
    ],
  },
};
```

2. Pass `loaderContext` in plugin.

**webpack.config.js**

```js
const path = require("path");

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                config: path.resolve(__dirname, "path/to/postcss.config.js"),
              },
            },
          },
        ],
      },
    ],
  },
};
```

**postcss.config.js**

```js
module.exports = (api) => ({
  plugins: [
    require("path/to/customPlugin")({
      loaderContext: api.webpackLoaderContext,
    }),
  ],
});
```

**customPlugin.js**

```js
const path = require("path");

const customPlugin = (loaderContext) => (css, result) => {
  loaderContext.webpack.addDependency(
    path.resolve(__dirname, "path", "to", "file")
  );
};

module.exports = postcss.plugin("postcss-assets", customPlugin);
```

## Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

[CONTRIBUTING](./.github/CONTRIBUTING.md)

## License

[MIT](./LICENSE)

[npm]: https://img.shields.io/npm/v/postcss-loader.svg
[npm-url]: https://npmjs.com/package/postcss-loader
[node]: https://img.shields.io/node/v/postcss-loader.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/postcss-loader.svg
[deps-url]: https://david-dm.org/webpack-contrib/postcss-loader
[tests]: https://github.com/webpack-contrib/postcss-loader/workflows/postcss-loader/badge.svg
[tests-url]: https://github.com/webpack-contrib/postcss-loader/actions
[cover]: https://codecov.io/gh/webpack-contrib/postcss-loader/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/postcss-loader
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[chat-postcss]: https://badges.gitter.im/postcss/postcss.svg
[chat-postcss-url]: https://gitter.im/postcss/postcss
[size]: https://packagephobia.now.sh/badge?p=postcss-loader
[size-url]: https://packagephobia.now.sh/result?p=postcss-loader


code:
"use strict";

/**
 * **PostCSS Syntax Error**
 *
 * Loader wrapper for postcss syntax errors
 *
 * @class SyntaxError
 * @extends Error
 *
 * @param {Object} err CssSyntaxError
 */
class SyntaxError extends Error {
  constructor(error) {
    super(error);
    const {
      line,
      column,
      reason,
      plugin,
      file
    } = error;
    this.name = "SyntaxError";
    this.message = `${this.name}\n\n`;

    if (typeof line !== "undefined") {
      this.message += `(${line}:${column}) `;
    }

    this.message += plugin ? `${plugin}: ` : "";
    this.message += file ? `${file} ` : "<css input> ";
    this.message += `${reason}`;
    const code = error.showSourceCode();

    if (code) {
      this.message += `\n\n${code}\n`;
    }

    this.stack = false;
  }

}

module.exports = SyntaxError;


code:
"use strict";

/**
 * **PostCSS Plugin Warning**
 *
 * Loader wrapper for postcss plugin warnings (`root.messages`)
 *
 * @class Warning
 * @extends Error
 *
 * @param {Object} warning PostCSS Warning
 */
class Warning extends Error {
  constructor(warning) {
    super(warning);
    const {
      text,
      line,
      column,
      plugin
    } = warning;
    this.name = "Warning";
    this.message = `${this.name}\n\n`;

    if (typeof line !== "undefined") {
      this.message += `(${line}:${column}) `;
    }

    this.message += plugin ? `${plugin}: ` : "";
    this.message += `${text}`;
    this.stack = false;
  }

}

module.exports = Warning;


code:
"use strict";

module.exports = require("./index").default;


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = loader;

var _path = _interopRequireDefault(require("path"));

var _semver = require("semver");

var _package = _interopRequireDefault(require("postcss/package.json"));

var _Warning = _interopRequireDefault(require("./Warning"));

var _Error = _interopRequireDefault(require("./Error"));

var _options = _interopRequireDefault(require("./options.json"));

var _utils = require("./utils");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

let hasExplicitDependencyOnPostCSS = false;
/**
 * **PostCSS Loader**
 *
 * Loads && processes CSS with [PostCSS](https://github.com/postcss/postcss)
 *
 * @method loader
 *
 * @param {String} content Source
 * @param {Object} sourceMap Source Map
 * @param {Object} meta Meta
 *
 * @return {callback} callback Result
 */

async function loader(content, sourceMap, meta) {
  const options = this.getOptions(_options.default);
  const callback = this.async();
  const configOption = typeof options.postcssOptions === "undefined" || typeof options.postcssOptions.config === "undefined" ? true : options.postcssOptions.config;
  const postcssFactory = (0, _utils.getPostcssImplementation)(this, options.implementation);

  if (!postcssFactory) {
    callback(new Error(`The Postcss implementation "${options.implementation}" not found`));
    return;
  }

  let loadedConfig;

  if (configOption) {
    try {
      loadedConfig = await (0, _utils.loadConfig)(this, configOption, options.postcssOptions);
    } catch (error) {
      callback(error);
      return;
    }
  }

  const useSourceMap = typeof options.sourceMap !== "undefined" ? options.sourceMap : this.sourceMap;
  const {
    plugins,
    processOptions
  } = await (0, _utils.getPostcssOptions)(this, loadedConfig, options.postcssOptions);

  if (useSourceMap) {
    processOptions.map = {
      inline: false,
      annotation: false,
      ...processOptions.map
    };
  }

  if (sourceMap && processOptions.map) {
    processOptions.map.prev = (0, _utils.normalizeSourceMap)(sourceMap, this.context);
  }

  let root; // Reuse PostCSS AST from other loaders

  if (meta && meta.ast && meta.ast.type === "postcss" && (0, _semver.satisfies)(meta.ast.version, `^${_package.default.version}`)) {
    ({
      root
    } = meta.ast);
  }

  if (!root && options.execute) {
    // eslint-disable-next-line no-param-reassign
    content = (0, _utils.exec)(content, this);
  }

  let result;
  let processor;

  try {
    processor = postcssFactory(plugins);
    result = await processor.process(root || content, processOptions);
  } catch (error) {
    // Check postcss versions to avoid using PostCSS 7.
    // For caching reasons, we use the readFileSync and existsSync functions from the context,
    // not the functions from the `fs` module.
    if (!hasExplicitDependencyOnPostCSS && processor && processor.version && processor.version.startsWith("7.")) {
      // The `findPackageJsonDir` function returns `string` or `null`.
      // This is used to do for caching, that is, an explicit comparison with `undefined`
      // is used to make the condition body run once.
      const packageJSONDir = (0, _utils.findPackageJSONDir)(process.cwd(), this.fs.statSync);

      if (packageJSONDir) {
        let bufferOfPackageJSON;

        try {
          bufferOfPackageJSON = this.fs.readFileSync(_path.default.resolve(packageJSONDir, "package.json"), "utf8");
        } catch (_error) {// Nothing
        }

        if (bufferOfPackageJSON) {
          let pkg;

          try {
            pkg = JSON.parse(bufferOfPackageJSON);
          } catch (_error) {// Nothing
          }

          if (pkg) {
            if (!pkg.dependencies.postcss && !pkg.devDependencies.postcss) {
              this.emitWarning(new Error("Add postcss as project dependency. postcss is not a peer dependency for postcss-loader. " + "Use `npm install postcss` or `yarn add postcss`"));
            } else {
              hasExplicitDependencyOnPostCSS = true;
            }
          }
        }
      }
    }

    if (error.file) {
      this.addDependency(error.file);
    }

    if (error.name === "CssSyntaxError") {
      callback(new _Error.default(error));
    } else {
      callback(error);
    }

    return;
  }

  for (const warning of result.warnings()) {
    this.emitWarning(new _Warning.default(warning));
  }

  for (const message of result.messages) {
    // eslint-disable-next-line default-case
    switch (message.type) {
      case "dependency":
        this.addDependency(message.file);
        break;

      case "build-dependency":
        this.addBuildDependency(message.file);
        break;

      case "missing-dependency":
        this.addMissingDependency(message.file);
        break;

      case "context-dependency":
        this.addContextDependency(message.file);
        break;

      case "dir-dependency":
        this.addContextDependency(message.dir);
        break;

      case "asset":
        if (message.content && message.file) {
          this.emitFile(message.file, message.content, message.sourceMap, message.info);
        }

    }
  } // eslint-disable-next-line no-undefined

  let map = result.map ? result.map.toJSON() : undefined;

  if (map && useSourceMap) {
    map = (0, _utils.normalizeSourceMapAfterPostcss)(map, this.context);
  }

  const ast = {
    type: "postcss",
    version: result.processor.version,
    root: result.root
  };
  callback(null, result.css, map, {
    ast
  });
}


title: PostCSS Loader options

type: object

description: Options to pass through to `Postcss`.

description: Allows to specify PostCSS config path.

description: Allows to specify the path to the configuration file

type: string

description: Enables/Disables autoloading config

type: boolean

instanceof: Function

description: Enables/Disables PostCSS parser support in 'CSS-in-JS'.

description: Enables/Disables generation of source maps.

description: The implementation of postcss to use, instead of the locally installed version


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.exec = exec;
exports.findPackageJSONDir = findPackageJSONDir;
exports.getPostcssImplementation = getPostcssImplementation;
exports.getPostcssOptions = getPostcssOptions;
exports.loadConfig = loadConfig;
exports.normalizeSourceMap = normalizeSourceMap;
exports.normalizeSourceMapAfterPostcss = normalizeSourceMapAfterPostcss;

var _path = _interopRequireDefault(require("path"));

var _module = _interopRequireDefault(require("module"));

var _full = require("klona/full");

var _cosmiconfig = require("cosmiconfig");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const parentModule = module;

const stat = (inputFileSystem, filePath) => new Promise((resolve, reject) => {
  inputFileSystem.stat(filePath, (err, stats) => {
    if (err) {
      reject(err);
    }

    resolve(stats);
  });
});

function exec(code, loaderContext) {
  const {
    resource,
    context
  } = loaderContext;
  const module = new _module.default(resource, parentModule); // eslint-disable-next-line no-underscore-dangle

  module.paths = _module.default._nodeModulePaths(context);
  module.filename = resource; // eslint-disable-next-line no-underscore-dangle

  module._compile(code, resource);

  return module.exports;
}

async function loadConfig(loaderContext, config, postcssOptions) {
  const searchPath = typeof config === "string" ? _path.default.resolve(config) : _path.default.dirname(loaderContext.resourcePath);
  let stats;

  try {
    stats = await stat(loaderContext.fs, searchPath);
  } catch (errorIgnore) {
    throw new Error(`No PostCSS config found in: ${searchPath}`);
  }

  const explorer = (0, _cosmiconfig.cosmiconfig)("postcss");
  let result;

  try {
    if (stats.isFile()) {
      result = await explorer.load(searchPath);
    } else {
      result = await explorer.search(searchPath);
    }
  } catch (error) {
    throw error;
  }

  if (!result) {
    return {};
  }

  loaderContext.addBuildDependency(result.filepath);
  loaderContext.addDependency(result.filepath);

  if (result.isEmpty) {
    return result;
  }

  if (typeof result.config === "function") {
    const api = {
      mode: loaderContext.mode,
      file: loaderContext.resourcePath,
      // For complex use
      webpackLoaderContext: loaderContext,
      // Partial compatibility with `postcss-cli`
      env: loaderContext.mode,
      options: postcssOptions || {}
    };
    result.config = result.config(api);
  }

  result = (0, _full.klona)(result);
  return result;
}

function loadPlugin(plugin, options, file) {
  try {
    if (!options || Object.keys(options).length === 0) {
      // eslint-disable-next-line global-require, import/no-dynamic-require
      const loadedPlugin = require(plugin);

      if (loadedPlugin.default) {
        return loadedPlugin.default;
      }

      return loadedPlugin;
    } // eslint-disable-next-line global-require, import/no-dynamic-require

    const loadedPlugin = require(plugin);

    if (loadedPlugin.default) {
      return loadedPlugin.default(options);
    }

    return loadedPlugin(options);
  } catch (error) {
    throw new Error(`Loading PostCSS "${plugin}" plugin failed: ${error.message}\n\n(@${file})`);
  }
}

function pluginFactory() {
  const listOfPlugins = new Map();
  return plugins => {
    if (typeof plugins === "undefined") {
      return listOfPlugins;
    }

    if (Array.isArray(plugins)) {
      for (const plugin of plugins) {
        if (Array.isArray(plugin)) {
          const [name, options] = plugin;
          listOfPlugins.set(name, options);
        } else if (plugin && typeof plugin === "function") {
          listOfPlugins.set(plugin);
        } else if (plugin && Object.keys(plugin).length === 1 && (typeof plugin[Object.keys(plugin)[0]] === "object" || typeof plugin[Object.keys(plugin)[0]] === "boolean") && plugin[Object.keys(plugin)[0]] !== null) {
          const [name] = Object.keys(plugin);
          const options = plugin[name];

          if (options === false) {
            listOfPlugins.delete(name);
          } else {
            listOfPlugins.set(name, options);
          }
        } else if (plugin) {
          listOfPlugins.set(plugin);
        }
      }
    } else {
      const objectPlugins = Object.entries(plugins);

      for (const [name, options] of objectPlugins) {
        if (options === false) {
          listOfPlugins.delete(name);
        } else {
          listOfPlugins.set(name, options);
        }
      }
    }

    return listOfPlugins;
  };
}

async function tryRequireThenImport(module) {
  let exports;

  try {
    // eslint-disable-next-line import/no-dynamic-require, global-require
    exports = require(module);
    return exports;
  } catch (requireError) {
    let importESM;

    try {
      // eslint-disable-next-line no-new-func
      importESM = new Function("id", "return import(id);");
    } catch (e) {
      importESM = null;
    }

    if (requireError.code === "ERR_REQUIRE_ESM" && importESM) {
      exports = await importESM(module);
      return exports.default;
    }

    throw requireError;
  }
}

async function getPostcssOptions(loaderContext, loadedConfig = {}, postcssOptions = {}) {
  const file = loaderContext.resourcePath;
  let normalizedPostcssOptions = postcssOptions;

  if (typeof normalizedPostcssOptions === "function") {
    normalizedPostcssOptions = normalizedPostcssOptions(loaderContext);
  }

  let plugins = [];

  try {
    const factory = pluginFactory();

    if (loadedConfig.config && loadedConfig.config.plugins) {
      factory(loadedConfig.config.plugins);
    }

    factory(normalizedPostcssOptions.plugins);
    plugins = [...factory()].map(item => {
      const [plugin, options] = item;

      if (typeof plugin === "string") {
        return loadPlugin(plugin, options, file);
      }

      return plugin;
    });
  } catch (error) {
    loaderContext.emitError(error);
  }

  const processOptionsFromConfig = loadedConfig.config || {};

  if (processOptionsFromConfig.from) {
    processOptionsFromConfig.from = _path.default.resolve(_path.default.dirname(loadedConfig.filepath), processOptionsFromConfig.from);
  }

  if (processOptionsFromConfig.to) {
    processOptionsFromConfig.to = _path.default.resolve(_path.default.dirname(loadedConfig.filepath), processOptionsFromConfig.to);
  } // No need them for processOptions

  delete processOptionsFromConfig.plugins;
  const processOptionsFromOptions = (0, _full.klona)(normalizedPostcssOptions);

  if (processOptionsFromOptions.from) {
    processOptionsFromOptions.from = _path.default.resolve(loaderContext.rootContext, processOptionsFromOptions.from);
  }

  if (processOptionsFromOptions.to) {
    processOptionsFromOptions.to = _path.default.resolve(loaderContext.rootContext, processOptionsFromOptions.to);
  } // No need them for processOptions

  delete processOptionsFromOptions.config;
  delete processOptionsFromOptions.plugins;
  const processOptions = {
    from: file,
    to: file,
    map: false,
    ...processOptionsFromConfig,
    ...processOptionsFromOptions
  };

  if (typeof processOptions.parser === "string") {
    try {
      processOptions.parser = await tryRequireThenImport(processOptions.parser);
    } catch (error) {
      loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.parser}" parser failed: ${error.message}\n\n(@${file})`));
    }
  }

  if (typeof processOptions.stringifier === "string") {
    try {
      processOptions.stringifier = await tryRequireThenImport(processOptions.stringifier);
    } catch (error) {
      loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.stringifier}" stringifier failed: ${error.message}\n\n(@${file})`));
    }
  }

  if (typeof processOptions.syntax === "string") {
    try {
      processOptions.syntax = await tryRequireThenImport(processOptions.syntax);
    } catch (error) {
      loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.syntax}" syntax failed: ${error.message}\n\n(@${file})`));
    }
  }

  if (processOptions.map === true) {
    // https://github.com/postcss/postcss/blob/master/docs/source-maps.md
    processOptions.map = {
      inline: true
    };
  }

  return {
    plugins,
    processOptions
  };
}

const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
const ABSOLUTE_SCHEME = /^[a-z0-9+\-.]+:/i;

function getURLType(source) {
  if (source[0] === "/") {
    if (source[1] === "/") {
      return "scheme-relative";
    }

    return "path-absolute";
  }

  if (IS_NATIVE_WIN32_PATH.test(source)) {
    return "path-absolute";
  }

  return ABSOLUTE_SCHEME.test(source) ? "absolute" : "path-relative";
}

function normalizeSourceMap(map, resourceContext) {
  let newMap = map; // Some loader emit source map as string
  // Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.

  if (typeof newMap === "string") {
    newMap = JSON.parse(newMap);
  }

  delete newMap.file;
  const {
    sourceRoot
  } = newMap;
  delete newMap.sourceRoot;

  if (newMap.sources) {
    newMap.sources = newMap.sources.map(source => {
      const sourceType = getURLType(source); // Do no touch `scheme-relative` and `absolute` URLs

      if (sourceType === "path-relative" || sourceType === "path-absolute") {
        const absoluteSource = sourceType === "path-relative" && sourceRoot ? _path.default.resolve(sourceRoot, _path.default.normalize(source)) : _path.default.normalize(source);
        return _path.default.relative(resourceContext, absoluteSource);
      }

      return source;
    });
  }

  return newMap;
}

function normalizeSourceMapAfterPostcss(map, resourceContext) {
  const newMap = map; // result.map.file is an optional property that provides the output filename.
  // Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
  // eslint-disable-next-line no-param-reassign

  delete newMap.file; // eslint-disable-next-line no-param-reassign

  newMap.sourceRoot = ""; // eslint-disable-next-line no-param-reassign

  newMap.sources = newMap.sources.map(source => {
    if (source.indexOf("<") === 0) {
      return source;
    }

    const sourceType = getURLType(source); // Do no touch `scheme-relative`, `path-absolute` and `absolute` types

    if (sourceType === "path-relative") {
      return _path.default.resolve(resourceContext, source);
    }

    return source;
  });
  return newMap;
}

function findPackageJSONDir(cwd, statSync) {
  let dir = cwd;

  for (;;) {
    try {
      if (statSync(_path.default.join(dir, "package.json")).isFile()) {
        break;
      }
    } catch (error) {// Nothing
    }

    const parent = _path.default.dirname(dir);

    if (dir === parent) {
      dir = null;
      break;
    }

    dir = parent;
  }

  return dir;
}

function getPostcssImplementation(loaderContext, implementation) {
  let resolvedImplementation = implementation;

  if (!implementation || typeof implementation === "string") {
    const postcssImplPkg = implementation || "postcss";

    try {
      // eslint-disable-next-line import/no-dynamic-require, global-require
      resolvedImplementation = require(postcssImplPkg);
    } catch (error) {
      loaderContext.emitError(error); // eslint-disable-next-line consistent-return

      return;
    }
  } // eslint-disable-next-line consistent-return

  return resolvedImplementation;
}


code:
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

case `uname` in
    *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node" ]; then
  exec "$basedir/node"  "$basedir/../semver/bin/semver.js" "$@"
else
  exec node  "$basedir/../semver/bin/semver.js" "$@"
fi


code:
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0

IF EXIST "%dp0%\node.exe" (
  SET "_prog=%dp0%\node.exe"
) ELSE (
  SET "_prog=node"
  SET PATHEXT=%PATHEXT:;.JS;=;%
)

endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%"  "%dp0%\..\semver\bin\semver.js" %*


code:
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent

$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
  # Fix case when both the Windows and Linux builds of Node
  # are installed in the same directory
  $exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
  # Support pipeline input
  if ($MyInvocation.ExpectingInput) {
    $input | & "$basedir/node$exe"  "$basedir/../semver/bin/semver.js" $args
  } else {
    & "$basedir/node$exe"  "$basedir/../semver/bin/semver.js" $args
  }
  $ret=$LASTEXITCODE
} else {
  # Support pipeline input
  if ($MyInvocation.ExpectingInput) {
    $input | & "node$exe"  "$basedir/../semver/bin/semver.js" $args
  } else {
    & "node$exe"  "$basedir/../semver/bin/semver.js" $args
  }
  $ret=$LASTEXITCODE
}
exit $ret