Full Code of postcss/autoprefixer for AI

main 360f2d9ecbad cached
268 files
485.9 KB
148.8k tokens
398 symbols
1 requests
Download .txt
Showing preview only (541K chars total). Download the full file or copy to clipboard to get everything.
Repository: postcss/autoprefixer
Branch: main
Commit: 360f2d9ecbad
Files: 268
Total size: 485.9 KB

Directory structure:
gitextract_70q035xe/

├── .editorconfig
├── .github/
│   ├── CONTRIBUTING.md
│   ├── FUNDING.yml
│   └── workflows/
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .npmignore
├── AUTHORS
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin/
│   └── autoprefixer
├── data/
│   └── prefixes.js
├── eslint.config.mjs
├── lib/
│   ├── at-rule.js
│   ├── autoprefixer.d.ts
│   ├── autoprefixer.js
│   ├── brackets.js
│   ├── browsers.js
│   ├── declaration.js
│   ├── hacks/
│   │   ├── align-content.js
│   │   ├── align-items.js
│   │   ├── align-self.js
│   │   ├── animation.js
│   │   ├── appearance.js
│   │   ├── autofill.js
│   │   ├── backdrop-filter.js
│   │   ├── background-clip.js
│   │   ├── background-size.js
│   │   ├── block-logical.js
│   │   ├── border-image.js
│   │   ├── border-radius.js
│   │   ├── break-props.js
│   │   ├── cross-fade.js
│   │   ├── display-flex.js
│   │   ├── display-grid.js
│   │   ├── file-selector-button.js
│   │   ├── filter-value.js
│   │   ├── filter.js
│   │   ├── flex-basis.js
│   │   ├── flex-direction.js
│   │   ├── flex-flow.js
│   │   ├── flex-grow.js
│   │   ├── flex-shrink.js
│   │   ├── flex-spec.js
│   │   ├── flex-wrap.js
│   │   ├── flex.js
│   │   ├── fullscreen.js
│   │   ├── gradient.js
│   │   ├── grid-area.js
│   │   ├── grid-column-align.js
│   │   ├── grid-end.js
│   │   ├── grid-row-align.js
│   │   ├── grid-row-column.js
│   │   ├── grid-rows-columns.js
│   │   ├── grid-start.js
│   │   ├── grid-template-areas.js
│   │   ├── grid-template.js
│   │   ├── grid-utils.js
│   │   ├── image-rendering.js
│   │   ├── image-set.js
│   │   ├── inline-logical.js
│   │   ├── intrinsic.js
│   │   ├── justify-content.js
│   │   ├── mask-border.js
│   │   ├── mask-composite.js
│   │   ├── order.js
│   │   ├── overscroll-behavior.js
│   │   ├── pixelated.js
│   │   ├── place-self.js
│   │   ├── placeholder-shown.js
│   │   ├── placeholder.js
│   │   ├── print-color-adjust.js
│   │   ├── text-decoration-skip-ink.js
│   │   ├── text-decoration.js
│   │   ├── text-emphasis-position.js
│   │   ├── transform-decl.js
│   │   ├── user-select.js
│   │   └── writing-mode.js
│   ├── info.js
│   ├── old-selector.js
│   ├── old-value.js
│   ├── prefixer.js
│   ├── prefixes.js
│   ├── processor.js
│   ├── resolution.js
│   ├── selector.js
│   ├── supports.js
│   ├── transition.js
│   ├── utils.js
│   ├── value.js
│   └── vendor.js
├── package.json
├── patches/
│   └── yargs@17.7.2.patch
└── test/
    ├── at-rule.test.js
    ├── autoprefixer.test.js
    ├── brackets.test.js
    ├── browsers.test.js
    ├── cases/
    │   ├── 3d-transform.css
    │   ├── 3d-transform.out.css
    │   ├── advanced-filter.css
    │   ├── advanced-filter.out.css
    │   ├── animation.css
    │   ├── animation.out.css
    │   ├── appearance.css
    │   ├── appearance.out.css
    │   ├── at-rules.css
    │   ├── at-rules.out.css
    │   ├── autofill.css
    │   ├── autofill.out.css
    │   ├── backdrop-filter.css
    │   ├── backdrop-filter.out.css
    │   ├── backdrop.css
    │   ├── backdrop.out.css
    │   ├── background-clip.css
    │   ├── background-clip.out.css
    │   ├── background-size.css
    │   ├── background-size.out.css
    │   ├── border-image.css
    │   ├── border-image.out.css
    │   ├── border-radius.css
    │   ├── border-radius.out.css
    │   ├── cascade.css
    │   ├── cascade.out.css
    │   ├── check-down.css
    │   ├── check-down.out.css
    │   ├── comments.css
    │   ├── comments.out.css
    │   ├── config/
    │   │   ├── browserslist
    │   │   ├── test.css
    │   │   ├── test.out.css
    │   │   └── test.production.css
    │   ├── content.css
    │   ├── cross-fade.css
    │   ├── cross-fade.out.css
    │   ├── custom-prefix.css
    │   ├── custom-prefix.out.css
    │   ├── disabled.css
    │   ├── disabled.out.css
    │   ├── double.css
    │   ├── double.out.css
    │   ├── element.css
    │   ├── element.out.css
    │   ├── example.css
    │   ├── example.out.css
    │   ├── file-selector-button.css
    │   ├── file-selector-button.out.css
    │   ├── filter.css
    │   ├── filter.out.css
    │   ├── flex-rewrite.css
    │   ├── flex-rewrite.out.css
    │   ├── flexbox.css
    │   ├── flexbox.out.css
    │   ├── fullscreen.css
    │   ├── fullscreen.out.css
    │   ├── gradient-fix.css
    │   ├── gradient-fix.out.css
    │   ├── gradient.css
    │   ├── gradient.out.css
    │   ├── grid-area-media-sequence.css
    │   ├── grid-area-media-sequence.out.css
    │   ├── grid-area.css
    │   ├── grid-area.out.css
    │   ├── grid-areas-duplicate-complex.css
    │   ├── grid-areas-duplicate-complex.out.css
    │   ├── grid-autoplacement.css
    │   ├── grid-autoplacement.out.css
    │   ├── grid-gap.css
    │   ├── grid-gap.out.css
    │   ├── grid-media-rules.css
    │   ├── grid-media-rules.out.css
    │   ├── grid-options.autoplace.out.css
    │   ├── grid-options.css
    │   ├── grid-options.disabled.out.css
    │   ├── grid-options.no-autoplace.out.css
    │   ├── grid-status.css
    │   ├── grid-status.out.css
    │   ├── grid-template-areas.css
    │   ├── grid-template-areas.out.css
    │   ├── grid-template.css
    │   ├── grid-template.out.css
    │   ├── grid.css
    │   ├── grid.disabled.css
    │   ├── grid.out.css
    │   ├── grouping-rule.css
    │   ├── grouping-rule.out.css
    │   ├── ignore-next.css
    │   ├── ignore-next.out.css
    │   ├── image-rendering.css
    │   ├── image-rendering.out.css
    │   ├── image-set.css
    │   ├── image-set.out.css
    │   ├── intrinsic.css
    │   ├── intrinsic.ff.css
    │   ├── intrinsic.out.css
    │   ├── keyframes.css
    │   ├── keyframes.out.css
    │   ├── logical.css
    │   ├── logical.out.css
    │   ├── mask-border.css
    │   ├── mask-border.out.css
    │   ├── mask-composite.css
    │   ├── mask-composite.out.css
    │   ├── mistakes.css
    │   ├── mistakes.out.css
    │   ├── multicolumn.css
    │   ├── multicolumn.out.css
    │   ├── notes.css
    │   ├── notes.out.css
    │   ├── overscroll-behavior.css
    │   ├── overscroll-behavior.out.css
    │   ├── pie.css
    │   ├── placeholder-shown.css
    │   ├── placeholder-shown.out.css
    │   ├── placeholder.css
    │   ├── placeholder.out.css
    │   ├── print-color-adjust.css
    │   ├── print-color-adjust.out.css
    │   ├── resolution.css
    │   ├── resolution.out.css
    │   ├── scope.css
    │   ├── scope.out.css
    │   ├── selectors.css
    │   ├── selectors.out.css
    │   ├── style.css
    │   ├── style.out.css
    │   ├── supports.css
    │   ├── supports.out.css
    │   ├── syntax.css
    │   ├── text-decoration.css
    │   ├── text-decoration.out.css
    │   ├── text-decoration.shorthand.out.css
    │   ├── text-emphasis-position.css
    │   ├── text-emphasis-position.out.css
    │   ├── transition-no-warning.css
    │   ├── transition-no-warning.out.css
    │   ├── transition-spec.css
    │   ├── transition-spec.out.css
    │   ├── transition.css
    │   ├── transition.out.css
    │   ├── trim.css
    │   ├── uncascade.css
    │   ├── uncascade.out.css
    │   ├── user-select.css
    │   ├── user-select.out.css
    │   ├── value-hack.css
    │   ├── value-hack.out.css
    │   ├── values.css
    │   ├── values.out.css
    │   ├── vendor-hack.css
    │   ├── vendor-hack.out.css
    │   ├── viewport.css
    │   ├── viewport.out.css
    │   ├── webkit-line-clamp.css
    │   ├── webkit-line-clamp.out.css
    │   ├── writing-mode.css
    │   └── writing-mode.out.css
    ├── declaration.test.js
    ├── info.test.js
    ├── old-selector.test.js
    ├── old-value.test.js
    ├── postcss.test.js
    ├── prefixer.test.js
    ├── prefixes.test.js
    ├── selector.test.js
    ├── supports.test.js
    ├── utils.test.js
    └── value.test.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true


================================================
FILE: .github/CONTRIBUTING.md
================================================
<img width="94" height="71" src="../logo.svg" title="Autoprefixer logo by Anton Lovchikov">

# Contributing to Autoprefixer

* [Filing Issues](#filing-issues)
* [Getting Started](#getting-started)
* [Adding a Prefix](#adding-a-prefix)


## Filing Issues

- If you have problems with the output CSS from Autoprefixer;
you’ll need to post:

  1. Input CSS.
  2. Output CSS.
  3. Expected output CSS.
  4. Browserslist config. If you use `browsers` or option,
     create Browserslist config first.
  5. Run `npm ls | grep autoprefixer` and check output.

- If Autoprefixer throws error:

  1. Input CSS.
  2. Browserslist config.
  3. Error stacktrace (copy and paste the error message that you get
     so we can identify where the problem is).
  4. Run `npm ls | grep autoprefixer` and check output.
  5. Run `npm ls | grep postcss` and check output.


## Getting Started

Before you begin contributing make sure you have a [GitHub account].

* [Fork the repository](https://github.com/postcss/autoprefixer)
* Clone a copy of it to your computer:
  `git clone https://github.com/USERNAME/autoprefixer` (replace `USERNAME`
  to your GitHub name).
* Ensure that you have the [pnpm](https://pnpm.io/) package manager
  installed.
* Run `pnpm install` this will install all dependencies needed to run tests.

[GitHub account]: https://github.com/signup/free


## Adding a Prefix

We’ll explain how would you go about adding a CSS feature to Autoprefixer.
For example, we’ll add support for a CSS feature called `background-clip: text`.

Note: Remember that the feature that you want to add must also be supported
on [Can I use](https://caniuse.com/).

1. Create a topic branch from the `master` branch.
   Like this: `git checkout -b background-clip-text`.

2. To add support for a CSS feature you must call the convert function inside
   of `data/prefixes.js` and specify three parameters: data, options
   and a callback. Like this:

   ```js
   f(require('caniuse-lite/data/features/background-clip-text'), browsers =>
     prefix(['background-clip'], {
       feature: 'background-clip-text',
       browsers
     })
   )
   ```

3. If the prefix is simple (`-webkit-` for Safari, `-moz-` for Firefox,
  all use the same syntax) go to step 8.

4. If you need some non-standard behavior for the prefix (`-webkit-` prefix
   for Firefox or different syntax for different browsers) you will need
   to create a “hack”. Create a JS file in the `libs/hacks` folder using
   the name of the CSS feature as the filename.

5. Check out other hacks for examples. In this new class change the prefix
   for `IE` to `-webkit-`. [See complete example](https://github.com/postcss/Autoprefixer/blob/73c7b6ab090a9a9a03869b3099096af00be7eb7d/lib/hacks/background-clip.js)

6. Load the new hack in `lib/prefixes.js`. Load it into `Declaration`
   if you need a prefix for property name. Load it into `Value` if you need
   a prefix for value.

   ```js
   Declaration.hack(require('./hacks/background-clip'))
   ```

7. Create a `.css` and `.out.css` example in `test/cases`. Add this test to
   `test/autoprefixer.test.js`:

   ```js
   it('supports background-clip', () => check('background-clip'))
   ```

   If you need different browsers, change `prefixer()` function in the top
   of test file.

8. Run `pnpm test`.
9. Push the branch to GitHub.
10. Open your fork on GitHub an send pull request.


================================================
FILE: .github/FUNDING.yml
================================================
open_collective: postcss
tidelift: npm/autoprefixer
github: ai


================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
  push:
    tags:
      - '*'
permissions:
  contents: write
jobs:
  release:
    name: Release On Tag
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - name: Extract the changelog
        id: changelog
        run: |
          TAG_NAME=${GITHUB_REF/refs\/tags\//}
          READ_SECTION=false
          CHANGELOG=""
          while IFS= read -r line; do
            if [[ "$line" =~ ^#+\ +(.*) ]]; then
              if [[ "${BASH_REMATCH[1]}" == "$TAG_NAME" ]]; then
                READ_SECTION=true
              elif [[ "$READ_SECTION" == true ]]; then
                break
              fi
            elif [[ "$READ_SECTION" == true ]]; then
              CHANGELOG+="$line"$'\n'
            fi
          done < "CHANGELOG.md"
          CHANGELOG=$(echo "$CHANGELOG" | awk '/./ {$1=$1;print}')
          echo "changelog_content<<EOF" >> $GITHUB_OUTPUT
          echo "$CHANGELOG" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
      - name: Create the release
        if: steps.changelog.outputs.changelog_content != ''
        uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
        with:
          name: ${{ github.ref_name }}
          body: '${{ steps.changelog.outputs.changelog_content }}'
          draft: false
          prerelease: false


================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on:
  push:
    branches:
      - main
  pull_request:
permissions:
  contents: read
jobs:
  full:
    name: Node.js Latest Full
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - name: Install pnpm
        uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
        with:
          version: 10
      - name: Install Node.js
        uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
        with:
          node-version: 25
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --ignore-scripts
      - name: Run tests
        run: pnpm test
  short:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version:
          - 24
          - 22
          - 20
          - 18
    name: Node.js ${{ matrix.node-version }} Quick
    steps:
      - name: Checkout the repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - name: Install pnpm
        uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
        with:
          version: 10
      - name: Install Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
        with:
          node-version: ${{ matrix.node-version }}
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --ignore-scripts
      - name: Run unit tests
        run: pnpm unit
  old:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version:
          - 16
          - 14
          - 12
          - 10
    name: Node.js ${{ matrix.node-version }} Quick
    steps:
      - name: Checkout the repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - name: Install pnpm
        uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
        with:
          version: 3
        env:
          ACTIONS_ALLOW_UNSECURE_COMMANDS: true
      - name: Install Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install dependencies
        run: pnpm install --no-frozen-lockfile --ignore-scripts
      - name: Run unit tests
        run: for f in test/*.test.js; do node "$f"; done


================================================
FILE: .gitignore
================================================
node_modules/

coverage/


================================================
FILE: .npmignore
================================================
test/
coverage/

logo.svg
AUTHORS
eslint.config.mjs
patches


================================================
FILE: AUTHORS
================================================
# This is the official list of Autoprefixer authors for copyright purposes.
#
# This does not necessarily list everyone who has contributed code, since in
# some cases, their employer may be the copyright holder. To see the full list
# of contributors, see the revision history in source control or
# https://github.com/postcss/autoprefixer/graphs/contributors
#
# Authors who wish to be recognized in this file should add themselves (or
# their employer, as appropriate).

Aaron <me@aaron.md>
Adam Lynch <contact@adamlynch.ie>
Adonis K <aklp08@gmail.com>
Adriaan <https://github.com/harianus>
Albert Juhé Lluveras <aljullu@gmail.com>
Aleksei Androsov <aandrosov@yandex-team.ru>
Aleksey Shvayka <shvaikalesh@gmail.com>
Aleks Hudochenkov <aleks@hudochenkov.com>
Alexey Komarov <alex7kom@gmail.com>
Alexey Plutalov <demiazz.py@gmail.com>
Anders Olsen Sandvik <https://github.com/Andersos>
Andreas Haller <Andreas.Haller@invision.de>
Andreas Lind <andreas@one.com>
Andrew Rhoads <andrew.c.rhoads@gmail.com
Andrey Alexandrov <icima.fan@gmail.com>
Andrey Deryabin <deriabin@gmail.com>
Andrey Sitnik <andrey@sitnik.ru>
Andrey Taritsyn <taritsyn@gmail.com>
Andy Trevorah <a.trevorah@gmail.com>
Antoine du Hamel <duhamelantoine1995@gmail.com>
Anton Khlynovskiy <subzey@gmail.com>
Artem Yavorsky <info@yavorsky.org>
aruseni <aruseni.magiku@gmail.com>
Ben Briggs <beneb.info@gmail.com>
bernig <https://github.com/bernig>
Bogdan Chadkin <trysound@yandex.ru>
Bogdan Dolin <d.bogdan@inbox.ru>
brainopia <brainopia@evilmartians.com>
Brandon Mathis <brandon@imathis.com>
Chad von Nau <chad@vonnau.com>
Chi Vinh Le <vinh@wikiwi.io>
Christian Oliff <christianoliff@yahoo.com>
Cory House <housecor@gmail.com>
Cory Simmons <cory@mojotech.com>
Craig Martin <https://github.com/craigmichaelmartin>
Damon <motoxer4533@gmail.com>
Daniel Garcia-Carrillo <garciacarrillo.daniel@gmail.com>
Daniel Tonon <https://github.com/Dan503>
Daniel Tschinder <daniel@tschinder.de>
Danny Pule <kojikusan@gmail.com>
Darius
David Narbutovich <vamnemne@gmail.com>
David Pike <david@evolution7.com.au>
Denys Kniazevych <webschik@gmail.com>
Denis Sokolov <denis@sokolov.cc>
Diablohu <https://github.com/Diablohu>
Dominik Porada <dominik@porada.co>
Dominik Schilling <dominikschilling+git@gmail.com>
dotch <ch.weiss@hotmail.de>
Dmitry Semigradsky <semigradskyd@gmail.com>
Eduard Kyvenko <duardeco@gmail.com>
Efremov Alexey <lexich121@gmail.com>
eitanr <eitanr@wix.com>
Erik Sundahl <esundahl@gmail.com>
Eugene Datsky <eugene@datsky.ru>
Even Stensberg <evenstensberg@gmail.com>
Evgeny Petukhov <petukhov.yevgeny@gmail.com>
Evilebot Tnawi <sheo13666q@gmail.com>
Fangzhou Li <riophaelee@gmail.com>
Forrest York <https://github.com/badisa>
Gibr <todayz@yandex.ru>
Google Inc.
Gregory Eremin <magnolia_fan@me.com>
GU Yiling <justice360@gmail.com>
Gustavo Real <https://github.com/kotfire>
Hallvord R. M. Steen <hallvord@hallvord.com>
heady <https://github.com/heady>
HongShaoRou <evanzlist@sina.com>
Huáng Jùnliàng <https://github.com/JLHwung>
Iain Beeston <iain.beeston@gmail.com>
Igor Adamenko <https://github.com/igoradamenko>
Ivan <menshikov.ivn@gmail.com>
Ivan Malov <https://github.com/ivandata>
Ivan Verevkin <ivan.p.verevkin@gmail.com>
Filipe W. Lima <fwl.ufpe@gmail.com>
Jack Moore <hello@jacklmoore.com>
Jason Kuhrt <jasonkuhrt@me.com>
Jeff Escalante <hello@jenius.me>
Joan León <joan.leon@gmail.com>
Johannes J. Schmidt <schmidt@netzmerk.com>
John Kreitlow <jkreitlow@deepfocus.net>
Jonathan Ong <jonathanrichardong@gmail.com>
Josh Gillies <github@joshgilli.es>
Joshua Hall <joshuahallmail@gmail.com>
Juan Martin Marco <jmmarco@gmail.com>
Junliang Huang
jvdanilo <jvdanilo@gmail.com>
Kevin Pfefferle <kevin@rebaseinteractive.com>
Kieran <Kieranju@gmail.com>
Kir Shatrov <shatrov@me.com>
Kiwi <vinh@wikiwi.io>
kizu <kizmarh@gmail.com>
Leonya Khachaturov <leonidkhachaturov@gmail.com>
Lovchikov Anton <besyanya@yandex.ru>
L.T <ec.huyinghuan@gmail.com>
Lucas Caton <lucascaton@gmail.com>
Luciano Battagliero <lucianobattagliero+git@gmail.com>
Luke Page <luke.a.page@gmail.com>
martco <martco@gmail.com>
Mat Gadd <github@catchall.drarok.com>
Matt Buresh <matt@mburesh.com>
Matt Smith <runner_28@hotmail.com>
Maxime Thirouin <m@moox.io>
Max Mechanic <max@philo.com>
Michael Beil <michaelbeil@me.com>
Michael Prentice <splaktar@gmail.com>
Michael Scott Hertzberg <mshertzberg@gmail.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Mikael Jorhult <mikael@jorhult.se>
Morton Fox <github@qslw.com>
mvasilkov <mvasilkov@gmail.com>
Nick Howes <nick@nickhowes.co.uk>
Nick Marchenko <n30n1ck@gmail.com>
Nic Nilov <https://github.com/nicnilov>
Nick Schonning <nschonni@gmail.com>
nickspielgist <dev@nickspiel.me>
Niels Dequeker <niels.dequeker@gmail.com>
Nikolay Burlov <kohgpat@gmail.com>
Oleh Aloshkin <olegaleshkin@gmail.com>
Oleksandr Sergiienko <sigerello@gmail.com>
Pavel Pustovalov <pustovalov.pavel@gmail.com>
Pavel Vostrikov <mail@vostrik.com>
Paul Statezny <Paulstatezny@gmail.com>
Peter van Westen <info@regularlabs.com>
Peter Zotov <whitequark@whitequark.org>
Phani Kandula <phani.kandula@gmail.com>
Phil Dokas <phil@jetless.org>
Rafael Silva <rafael@rafaelsilva.net>
Ray Lehnhoff <raymond.lehnhoff@gmail.com>
ReadmeCritic <frankensteinbot@gmail.com>
Reinaldo Schiehll <rn.schiehll@gmail.com>
René Stalder <rene@whatwedo.ch>
Richard Wang <richardwa@google.com>
Rob Howell <rob@robhowell.com>
Roland Warmerdam <rowno@webspirited.com>
Roman Dvornov <rdvornov@gmail.com>
Roy Revelt <roy@codsen.com>
Ryan Zimmerman <https://github.com/RyanZim>
Sami Suo-Heikki <suoheikki.sami@gmail.com>
Sasha Koss <koss@nocorp.me>
Sean Anderson <Sean.Palmer.Anderson@gmail.com>
Semen Levenson <levenson94@gmail.com>
Sergey Belov <peimei@ya.ru>
Sergey Leschina <mail@putnik.ws>
Sergey Lysenko <soulwish.ls@gmail.com>
sethjgore <sethjgore@gmail.com>
Šime Vidas <sime.vidas@gmail.com>
Simon Lydell <simon.lydell@gmail.com>
Sindre Sorhus <sindresorhus@gmail.com>
Sire
Stanislav <botev.st@gmail.com>
Stanislav Lashmanov <stasvarenkin@gmail.com>
Stephen Edgar <stephen@netweb.com.au>
Steve Mao <https://github.com/stevemao>
Stig Otnes Kolstad <stig@stigok.net>
Subash Pathak <sbspk@msn.com>
sunhao <sunhao_1988@msn.cn>
Sven Wagner <https://github.com/svewag>
Timothy <zzzzBov@gmail.com>
tomdavenport <playmusic@me.com>
Tony Ganch <tonyganch@gmail.com>
Vegard Andreas Larsen <vegard@xaltra.net>
Vera Surkova <vera@surkova.se>
Vincent De Oliveira <vincent@iamvdo.me>
Vishnu Ravi <vishnu@vishnu.io>
Vladimir Pouzanov <farcaller@gmail.com>
vladkens <vladkens@yandex.ru>
Yet Another Minion <yam@thinkalexandria.com>
Yuriy Alekseyev <dev.yuriy.a@gmail.com>
Yury Timofeev <y.timofeyev@gmail.com>
Даниил Пронин <mail@grawl.ru>
一丝 <jie.lijie@alibaba-inc.com>
刘祺 <gucong@gmail.com>
忆初 <baby@justjavac.com>


================================================
FILE: CHANGELOG.md
================================================
# Change Log
This project adheres to [Semantic Versioning](http://semver.org/).

## 10.4.27
* Removed development key from `package.json`.

## 10.4.26
* Reduced package size.

## 10.4.25
* Fixed broken gradients on CSS Custom Properties (by @serger777).

## 10.4.24
* Made Autoprefixer a little faster (by @Cherry).

## 10.4.23
* Reduced dependencies (by @hyperz111).

## 10.4.22
* Fixed `stretch` prefixes on new Can I Use database.
* Updated `fraction.js`.

## 10.4.21
* Fixed old `-moz-` prefix for `:placeholder-shown` (by @Marukome0743).

## 10.4.20
* Fixed `fit-content` prefix for Firefox.

## 10.4.19
* Removed `end value has mixed support, consider using flex-end` warning
  since `end`/`start` now have good support.

## 10.4.18
* Fixed removing `-webkit-box-orient` on `-webkit-line-clamp` (@Goodwine).

## 10.4.17
* Fixed `user-select: contain` prefixes.

## 10.4.16
* Improved performance (by Romain Menke).
* Fixed docs (by Christian Oliff).

## 10.4.15
* Fixed `::backdrop` prefixes (by 一丝).
* Fixed docs (by Christian Oliff).

## 10.4.14
* Improved startup time and reduced JS bundle size (by Kārlis Gaņģis).

## 10.4.13
* Fixed missed prefixes on vendor prefixes in name of CSS Custom Property.

## 10.4.12
* Fixed support of unit-less zero angle in backgrounds (by 一丝).

## 10.4.11
* Fixed `text-decoration` prefixes by moving to MDN data (by Romain Menke).

## 10.4.10
* Fixed `unicode-bidi` prefixes by moving to MDN data.

## 10.4.9
* Fixed `css-unicode-bidi` issue from latest Can I Use.

## 10.4.8
* Do not print `color-adjust` warning if `print-color-adjust` also is in rule.

## 10.4.7
* Fixed `print-color-adjust` support in Firefox.

## 10.4.6
* Fixed `print-color-adjust` support.

## 10.4.5
* Fixed `NaN` in grid (by @SukkaW).

## 10.4.4
* Fixed `package.funding` to have same value between all PostCSS packages.

## 10.4.3
* Fixed `package.funding` (by Álvaro Mondéjar).

## 10.4.2
* Fixed missed `-webkit-` prefix for `width: stretch`.

## 10.4.1
* Fixed `::file-selector-button` data (by Luke Warlow).

## 10.4 “ǃke e꞉ ǀxarra ǁke”
* Added `:autofill` support (by Luke Warlow).

## 10.3.7
* Replaced `nanocolors` to `picocolors`.

## 10.3.6
* Updated `nanocolors`.
* Reduced package size.

## 10.3.5
* Replaced `colorette` to `nanocolors`.

## 10.3.4
* Fixed `stretch` value in latest Firefox.

## 10.3.3
* Fixed wrong `-moz-` prefix from  `::file-selector-button` (by Usman Yunusov).

## 10.3.2
* Fixed `::file-selector-button` support (by Usman Yunusov).

## 10.3.1
* Fixed adding wrong prefixes to `content` (by Luke Warlow).

## 10.3 “Чести своей не отдам никому”
* Added `::file-selector-button` support (by Luke Warlow).

## 10.2.6
* Fixed “no prefixes needed” warning (by @Pwntheon).

## 10.2.5
* Fixed `:` support in `@supports` (by Dmitry Semigradsky).
* Fixed docs (by Christian Oliff).

## 10.2.4
* Fixed browser names in `npx autoprefixer --info`.

## 10.2.3
* Fixed PostCSS 8 support.

## 10.2.2
* Fixed PostCSS 8 plugins compatibility.

## 10.2.1
* Fixed `transition-property` warnings (by @Sheraff).

## 10.2 “Sub rosa”
* Added TypeScript definitions (by Dmitry Semigradsky).
* Fixed docs (by Florian Pellet).

## 10.1 “Pula”
* Added `dpcm` unit support to `min-resolution: 2dppx` (by Robert Eisele).
* Fixed rational approximation in `min-resolution` (by Robert Eisele).

## 10.0.4
* Fixed `Cannot read property 'proxyOf' of undefined` error (by Igor Kamyshev).

## 10.0.3
* Fixed `substract` to `subtract` value for `mask-composite` (by Michelle Enos).

## 10.0.2
* Removed `-ms-user-select: all` because IE and old Edge don’t support it.
* Fixed Grid Layout warning.

## 10.0.1
* Fix PostCSS 8.1 compatability.
* Add our OpenCollective to `package.json`.
* Clean up code (by Sukka).

## 10.0 “Alis volat propriis”
* Removed support for Node.js 6.x, 8.x, 11.x.
* Moved `postcss` to `peerDependencies`.
* Moved to PostCSS 8.

## 9.8.6
* Fixed `env` option.

## 9.8.5
* Improved Grid Layout warnings (by Daniel Tonon).
* Fixed `align-self` and `justify-self` with `display: flex` (by Daniel Tonon).

## 9.8.4
* Replace color output library.

## 9.8.3
* Return old non-LTS Node.js versions to avoid breaking changes.

## 9.8.2
* Remove Node.js 13.0-13.7 from supported engines, because of buggy ESM support.

## 9.8.1
* Replace `chalk` to `kleur` (by Luke Edwards).
* Update docs (by @mbomb007).

## 9.8 “Vigilo Confido”
* Add `:placeholder-shown` support (by Tanguy Krotoff).

## 9.7.6
* Revert `-webkit-stretch` fix.

## 9.7.5
* Fix `-webkit-stretch` support.

## 9.7.4
* Fix warning text (by Dmitry Ishkov).

## 9.7.3
* Fix compatibility with PostCSS Modules.

## 9.7.2
* Add `-ms-user-select: element` support.
* Add funding link for `npm fund`.

## 9.7.1
* Avoid unnecessary transitions in prefixed selectors (by Andrey Alexandrov).
* Fix `fit-content` for Firefox.

## 9.7 “Ad Victoriam”
* Add `AUTOPREFIXER_GRID` env variable to enable Grid Layout polyfill for IE.
* Fix `Cannot read property 'grid' of undefined` error.

## 9.6.5
* Fix selector prefixing (by Andrey Alexandrov).

## 9.6.4
* Now the real fix for `'startsWith' of undefined` error.

## 9.6.3
* Fix `Cannot read property 'startsWith' of undefined` error.

## 9.6.2
* Fix false `Replace fill to stretch` warning.

## 9.6.1
* Fix `-webkit-line-clamp` truncating multi-line text support.

## 9.6 “Nunc id vides, nunc ne vides”
* Show warning about Browserslist config on `browser` option.
* Add warning-less `overrideBrowserslist` option.
* Add `text-orientation` support.
* Add `min-resolution: 2x` alias support.
* Add `.github/CONTRIBUTING.md` (by Juan Martin Marco).

## 9.5.1
* Fix `backdrop-filter` for Edge (by Oleh Aloshkin).
* Fix `min-resolution` media query support in Firefox < 16.

## 9.5 “Draco dormiens nunquam titillandus”
* Add `mask-composite` support (by Semen Levenson).

## 9.4.10
* Add warning for named Grid rows.

## 9.4.9
* Fix `grid-template` and `@media` case (by Bogdan Dolin).

## 9.4.8
* Fix `calc()` support in Grid gap.

## 9.4.7
* Fix infinite loop on mismatched parens.

## 9.4.6
* Fix warning text (by Albert Juhé Lluveras).

## 9.4.5
* Fix `text-decoration-skip-ink` support.

## 9.4.4
* Use `direction` value for `-ms-writing-mode` (by Denys Kniazevych).
* Fix warning text (by @zzzzBov).

## 9.4.3
* Add warning to force `flex-start` instead of `start` (by Antoine du Hamel).
* Fix docs (by Christian Oliff).

## 9.4.2
* Fix Grid autoplacement warning.

## 9.4.1
* Fix unnecessary Flexbox prefixes in Grid elements.

## 9.4 “Advance Australia”
* Add Grid autoplacement for `-ms-` (by Bogdan Dolin).
* Improve docs and warnings (by Daniel Tonon).
* Remove some unnecessary warnings for Grid (by Andrey Alexandrov).

## 9.3.1
* Fix Grid prefixes with `repeat()` value (by Bogdan Dolin).

## 9.3 “Labor omnia vincit”
* Add `place-self` support (by Bogdan Dolin).
* Fix Grid row/column span inheritance bug (by Bogdan Dolin).

## 9.2.1
* Fix broken AST.

## 9.2 “Onyi est glavnaya krepost”
* Add `/* autoprefixer grid: on */` control comment (by Andrey Alexandrov).
* Add duplicate `grid-area` support (by Bogdan Dolin).
* Fix `grid-gap` support for rules with different specifity (by Bogdan Dolin).
* Disable Grid in `@supports` at-rule with non-supported Grid features.
* Improve Grid warnings (by Daniel Tonon).
* Improve docs (by Joshua Hall, Mat Gadd, Roy Revelt, and Ivan).

## 9.1.5
* Remove `@babel/register` from dependencies.

## 9.1.4
* Use Babel 7.

## 9.1.3
* Sort properties in `autoprefixer --info` alphabetically.
* Fix old Firefox gradient prefix.

## 9.1.2
* Fix `autoprefixer --info` in new Node.js.

## 9.1.1
* Retain `grid-gap` through `@media` (by Bogdan Dolin).
* Fix `grid-template` and  `@media` (by Bogdan Dolin).
* Fix Grid areas searching error (by Bogdan Dolin).
* Fix `span X` Grid prefix (by Bogdan Dolin).
* Fix docs (by Eduard Kyvenko).

## 9.1 “Equality before the law”
* Add `background-clip: text` support.
* Fix adding Grid span for IE (by Bogdan Dolin).

## 9.0.2
* Show warning on Grid area names conflict (by Bogdan Dolin).
* Fix documentation (by Sven Wagner).

## 9.0.1
* Fix nested at-rules in Grid prefixes (by Ivan Malov).

## 9.0 “A Mari Usque Ad Mare”
* Remove Node.js 9 and Node.js 4 support.
* Remove IE and “dead” browsers from Babel.
* Use PostCSS 7.0.
* Use Browserslist 4.0.

## 8.6.5
* Do not show Grid warnings if IE was not selected.

## 8.6.4
* Fix `stretch` prefix in Chrome >= 46.

## 8.6.3
* Add warnings for unsupported Grid features.
* Add warnings about wrong Grid properties.
* Add note about `grid` option for grid properties in `autoprefixer --info`.

## 8.6.2
* Fix error during adding Grid prefixes in `@media` (by Evgeny Petukhov).

## 8.6.1
* Fix `grid-template` with media queries (by Evgeny Petukhov).

## 8.6 “Follow Reason”
* Add `gap` support (by Evgeny Petukhov).
* Add two values support for `grid-gap` and `gap` (by Evgeny Petukhov).
* Add `ignoreUnknownVersions` option for Browserslist.

## 8.5.2
* Fix `grid-template` support wit auto row sizes (by Yury Timofeev).

## 8.5.1
* Remove unnecessary warning on `-webkit-fill-available`.

## 8.5 “Muito Nobre e Sempre Leal”
* Add `grid-gap` support (by Evgeny Petukhov).
* Fix radial gradients direction fix.
* Fix docs (by Phani Kandula and Huáng Jùnliàng).

## 8.4.1
* Fix working in old PostCSS versions (by Diablohu).

## 8.4 “Non in aves, sed in angues”
* Add `/* autoprefixer: ignore next */` control comment (by Pavel Vostrikov).

## 8.3 “Benigno Numine”
* Add `@media` support to `grid-template` (by Evgeny Petukhov).
* Fix `radial-gradient` direction warning (by Gustavo Real).

## 8.2 “Ad Astra per Aspera”
* Add `color-adjust` (by Sergey Lysenko, Stanislav Botev, and Yuriy Alekseyev).

## 8.1 “Rex, Familia et Ultio”
* Add `overscroll-behavior` support.
* Add `grid-template` shortcut support (by Evgeny Petukhov).
* Add better `grid-column-end` and `grid-row-end` support (by Evgeny Petukhov).
* Fix Grid properties support in `@supports`.

## 8.0 “Excelsior”
* Use Browserslist 3.0.
* Rename `autoprefixer-info` CLI tool to `autoprefixer --info`.
* Remove `break-*` to `page-break-*` conversion for Firefox.

## 7.2.6
* Fix `-ms-` prefix for grid cells with same `grid-area` (by Evgeny Petukhov).

## 7.2.5
* Fix multiple prefixes in declaration value.

## 7.2.4
* Fix IE 10 support.

## 7.2.3
* Fix `grid-template-areas` in `@media` (by Evgeny Petukhov).

## 7.2.2
* Fix `_autoprefixerDisabled is undefined` issue.

## 7.2.1
* Fix IE and other old JS runtimes support.

## 7.2 “Ordem e Progresso”
* Add `grid-template-areas` support (by Evgeny Petukhov).
* Add `grid-template` support (by Evgeny Petukhov).
* Add `grid-area` support (by Alexey Komarov).
* Add `autoprefixer-info` CLI tool.
* Add wrong `radial-gradient` properties warning.
* Use current working dir on missed `from` in `info()` (by Phil Dokas).
* Fix `grid-row` and `grid-column` support (by Alexey Komarov).
* Do not prefix `reverse` animation direction.
* Improve test coverage (by Dmitry Semigradsky).

## 7.1.6
* Add warning for using `browserslist` option instead of `browsers`.
* Add warning for multiple control comments in the same scope.
* Fix `Invalid array length` error during indent changes.

## 7.1.5
* Fix `::placeholder` prefix for Edge.
* Fix `inherit`/`initial`/`unset` values for `flex-direction`.
* Fix RegExp usage in gradients (by Yet Another Minion).

## 7.1.4
* Fix `radial-gradient` direction conversion.
* Fix `image-set` in `cursor`.

## 7.1.3
* Add warning for old `radial-gradient` direction syntax.

## 7.1.2
* Fix `text-decoration` shortcut support.

## 7.1.1
* Remove non-`-webkit-` intrinsic prefixes in Grid Layout (by 一丝).

## 7.1 “Universitas litterarum”
* Add `unicode-bidi` support.
* Add `-webkit-appearance` support for Edge.
* Add `from` option to `info()`.
* Fix intrinsic widths prefixes in Grid Layout.

## 7.0.1
* Fix Autoprefixer for old JS runtimes.

## 7.0 “Coelestem adspicit lucem”
* Remove node.js 0.12 support.
* Use PostCSS 6.0.
* Use Browserslist 2.
* Use `caniuse-lite` instead of `caniuse-db` (by Ben Briggs).
* Use `^` for Browserslist dependencies, instead of `~`.
* Rewrite project from CoffeeScript to Babel (by Dmitry Semigradsky).
* Disable Grid Layout prefixes for IE by default.
* Fix `-ms-grid-column-align`.
* Move tests to Jest.

## 6.7.7
* Fix `order` for non-digit values.

## 6.7.6
* Fix `font-kerning` (by Chi Vinh Le).

## 6.7.5
* Fix `text-decoration-skip` in iOS (by Chi Vinh Le).
* Fix `clip-path` (by Chi Vinh Le).

## 6.7.4
* Improve `browsers` option perfomance.
* Update CoffeeScript compiler.

## 6.7.3
* Fix compatibility with “Intrinsic & Extrinsic Sizing” spec update.

## 6.7.2
* Do not prefix grid/flexbox in `@supports` on `grid: false`/`flexbox: false`.

## 6.7.1
* Update Browserslist with `last n version` fix.

## 6.7 “Krungthep doot thep saang”
* Add Electron support in browsers list (by Kilian Valkhof).
* Add `flex-flow` partial support for Flexbox 2009 specification.
* Fix browsers `0` version issue in some Can I Use data.

## 6.6.1
* Add metadata to use Autoprefixer in JSS tests (by Chi Vinh Le).

## 6.6 “Kaiyuan”
* Add `browserslist` key in `package.json` support.
* Add support for separated environments in browserslist config.
* Add `browserslist-stats.json` file support to load custom usage statistics.

## 6.5.4
* Fix unitless 0 basis in IE10/IE11 shorthand flex (by Google).

## 6.5.3
* Add error for popular mistake with `browser` option instead of `browsers`.

## 6.5.2
* Clean prefixes data (by Reinaldo Schiehll).

## 6.5.1
* Fix selectors with `:--` prefix support.

## 6.5 “Einigkeit und Recht und Freiheit”
* Add `defaults` keyword to browsers requirements.
* Fix CSS Grid Layout support.
* Fix `align-self` cleaning.

## 6.4.1
* Fix node cloning after some PostCSS plugins.

## 6.4 “Hic et ubique terrarum”
* Add `:any-link` selector support.
* Add `text-decoration-skip` support.
* Add `transition: duration property` support.
* Fix `-webkit-` prefix for `backface-visibility`.
* Fix `rad` unit support in gradients (by 刘祺).
* Fix `transition` support in Opera 12.
* Removed Safari TP Grid prefixes support.

## 6.3.7
* Fix rare `Cannot read property 'constructor' of null` issue.

## 6.3.6
* Add Safari TP prefix support for Grid Layout.

## 6.3.5
* Fix duplicate prefixes for `-ms-interpolation-mode`.

## 6.3.4
* Show users coverage for selected browsers in `info()`.

## 6.3.3
* Fix transition warning.

## 6.3.2
* Fix jspm support (by Sean Anderson).

## 6.3.1
* Fix compatibility with Flexibility polyfill.

## 6.3 “Pro rege et lege”
* Add Grid Layout support.
* Add `text-spacing` support.
* Add `> 10% in my stats` browsers query with custom usage statistics.
* Add options to disable `@supports`, Flexbox or Grid support.
* Fix compatibility with other PostCSS plugins.

## 6.2.3
* Fix error on broken transition with double comma.

## 6.2.2
* Fix issues in broken transitions.

## 6.2.1
* Fix AST error in transition warning (by @jvdanilo).

## 6.2 “Fluctuat nec mergitur”
* Use `fill` instead of `fill-available` according spec changes (by 一丝).
* Add `fill` support for logical dimension properties (by 一丝).
* Add `text-emphasis` support (by 一丝).
* Add prefixes to `@supports` only for compatible browsers.
* Add `rad`, `grad` and `turn` units support to linear gradients.
* Add some `deg` directions support for old WebKit linear gradients.
* Fix `@supports` parenthesis (by @heady).
* Add warning when prefixes could not be generated
  for complicated `transition-property` values.
* Add warning for outdated `fill-available` value.
* Add warning for wrong `text-emphasis-position` value.
* Add “time capsule” warning for prefix-less future.
* Normalizes all warning messages.

## 6.1.2
* Fix gradient hack on some parameters (by Alexey Efremov).

## 6.1.1
* Fix `cursor: grab` and `cursor: grabbing` support.

## 6.1 “Bil-shaʿb wa lil-shaʿb”
* Change `transition` support to output more robust CSS.
* Add `:read-only` support.
* Add support for `appearance` with any values.
* Add CSS-in-JS support via `postcss-js`.
* Add loud `/*! autoprefixer: off */` control comments support.
* Convert `rotateZ` to `rotate` for `-ms-transform`.
* Use `postcss-value-parser` to carefully work with gradients.
* Remove `-ms-transform-style` and `-o-transform-style` that never existed.

## 6.0.3
* Fix old gradient direction warning.

## 6.0.2
* Remove unnecessary `-khtml-` prefix too.

## 6.0.1
* Fix `cross-fade()` support (by 一丝).

## 6.0 “Eureka”
* CLI was removed from `autoprefixer` package to `autoprefixer-cli`.
* `autoprefixer-core` and `autoprefixer` packages was merged back.
* Remove `autoprefixer(opt).process(css)`, use `autoprefixer.process(css, opt)`.
* Remove `safe` option. Use separated Safe parser from PostCSS.
* Remove Opera 12.1 from default query.
* Use PostCSS 5.0 API.
* Add custom syntaxes support.
* Add `image-set` support (by 一丝).
* Add `mask-border` support (by 一丝).
* Add `filter()` function support (by Vincent De Oliveira).
* Add `backdrop-filter` support (by Vincent De Oliveira).
* Add `element()` support (by Vincent De Oliveira).
* Add CSS Regions support.
* Add Scroll Snap Points support.
* Add `writing-mode` support.
* Add `::backdrop` support.
* Add `cross-fade()` support.
* Add other `break-` properties support.
* Add Microsoft Edge support (by Andrey Polischuk).
* Add `not` keyword and exclude browsers by query.
* Add version ranges `IE 6-9` (by Ben Briggs).
* Fix `filter` in `transition` support on Safari.
* Fix `url()` parsing.
* Fix `pixelated` cleaning.
* Always show old gradient direction warning.

## 5.2.1
* Fix parent-less node issue on some cases (by Josh Gillies).

## 5.2 “Dont tread on me”
* Add `appearance` support.
* Warn users on old gradient direction or flexbox syntax.
* Add `add: false` option to disable new prefixes adding.
* Make Autoprefixer 30% faster.
* Use PostCSS 4.1 plugin API.
* Add prefixes for `pixelated` instead of `crisp-edges` in `image-rendering`.
* Do not add `::placeholder` prefixes for `:placeholder-shown`.
* Fix `text-decoration` prefixes.
* `autoprefixer.process()` was deprecated. Use PostCSS API.

## 5.1.11
* Update `num2fraction` to fix resolution media query (by 一丝).

## 5.1.10
* Do not generate `-webkit-image-rendering`.

## 5.1.9
* Fix DynJS compatibility (by Nick Howes).

## 5.1.8
* Fix gradients in `mask` and `mask-image` properties.
* Fix old webkit prefix on some unsupported gradients.

## 5.1.7
* Fix placeholder selector (by Vincent De Oliveira).

## 5.1.6
* Use official `::placeholder-shown` selector (by Vincent De Oliveira).

## 5.1.5
* Add transition support for CSS Masks properties.

## 5.1.4
* Use `-webkit-` prefix for Opera Mobile 24.

## 5.1.3
* Add IE support for `image-rendering: crisp-edges`.

## 5.1.2
* Add never existed `@-ms-keyframes` to common mistake.

## 5.1.1
* Safer value split in `flex` hack.

## 5.1 “Jianyuan”
* Add support for resolution media query (by 一丝).
* Higher accuracy while removing prefixes in values.
* Add support for logical properties (by 一丝).
* Add `@viewport` support.
* Add `text-overflow` support (by 一丝).
* Add `text-emphasis` support (by 一丝).
* Add `image-rendering: crisp-edges` support.
* Add `text-align-last` support.
* Return `autoprefixer.defaults` as alias to current `browserslist.defaults`.
* Save code style while adding prefixes to `@keyframes` and `@viewport`.
* Do not remove `-webkit-background-clip` with non-spec `text` value.
* Fix `-webkit-filter` in `transition`.
* Better support for browser versions joined on Can I Use
  like `ios_saf 7.0-7.1` (by Vincent De Oliveira).
* Fix compatibility with `postcss-import` (by Jason Kuhrt).
* Fix Flexbox prefixes for BlackBerry and UC Browser.
* Fix gradient prefixes for old Chrome.

## 5.0 “Pravda vítězí”
* Use PostCSS 4.0.
* Use Browserslist to parse browsers queries.
* Use global `browserslist` config.
* Add `> 5% in US` query to select browsers by usage in some country.
* Add `object-fit` and `object-position` properties support.
* Add CSS Shape properties support.
* Fix UC Browser name in debug info.
* Remove `autoprefixer.defaults` and use defaults from Browserslist.

## 4.0.2
* Remove `o-border-radius`, which is common mistake in legacy CSS.

## 4.0.1
* Fix `@supports` support with brackets in values (by Vincent De Oliveira).

## 4.0 “Indivisibiliter ac Inseparabiliter”
* Become 2.5 times fatser by new PostCSS 3.0 parser.
* Do not remove outdated prefixes by `remove: false` option.
* `map.inline` and `map.sourcesContent` options are now `true` by default.
* Add `box-decoration-break` support.
* Do not add old `-webkit-` prefix for gradients with `px` units.
* Use previous source map to show origin source of CSS syntax error.
* Use `from` option from previous source map `file` field.
* Set `to` value to `from` if `to` option is missing.
* Trim Unicode BOM on source maps parsing.
* Parse at-rules without spaces like `@import"file"`.
* Better previous `sourceMappingURL` annotation comment cleaning.
* Do not remove previous `sourceMappingURL` comment on `map.annotation: false`.

## 3.1.2
* Update Firefox ESR version from 24 to 31.

## 3.1.1
* Use Flexbox 2009 spec for Android stock browser < 4.4.

## 3.1 “Satyameva Jayate”
* Do not remove comments from prefixed values (by Eitan Rousso).
* Allow Safari 6.1 to use final Flexbox spec (by John Kreitlow).
* Fix `filter` value in `transition` in Webkits.
* Show greetings if your browsers don’t require any prefixes.
* Add `<=` and `<` browsers requirement (by Andreas Lind).

## 3.0.1
* Fix `autoprefixer.postcss` in callbacks.

## 3.0 “Liberté, Égalité, Fraternité”
* Project was split to autoprefixer (with CLI) and autoprefixer-core.
* `autoprefixer()` now receives only `options` object with `browsers` key.
* GNU format for syntax error messages from PostCSS 2.2.

## 2.2 “Mobilis in mobili”
* Allow to disable Autoprefixer for some rule by control comment.
* Use PostCSS 2.1 with Safe Mode option and broken source line
  in CSS syntax error messages.

## 2.1.1
* Fix `-webkit-background-size` hack for `contain` and `cover` values.
* Don’t add `-webkit-` prefix to `filter` with SVG (by Vincent De Oliveira).

## 2.1 “Eleftheria i thanatos”
* Add support for `clip-path` and `mask` properties.
* Return `-webkit-` prefix to `filter` with SVG URI.

## 2.0.2
* Add readable names for new browsers from 2.0 release.
* Don’t add `-webkit-` prefix to `filter` with SVG URI.
* Don’t add `-o-` prefix 3D transforms.

## 2.0.1
* Save declaration style, when clone declaration to prefix.

## 2.0 “Hongik Ingan”
* Based on PostCSS 1.0.
  See [options changes](https://github.com/postcss/postcss/releases/tag/1.0.0).
* Restore visual cascade after declaration removing.
* Enable visual cascade by default.
* Prefix declareation in `@supports` at-rule conditions.
* Add all browsers from Can I Use: `ie_mob`, `and_chr`, `and_ff`,
  `op_mob` and `op_mini`.
* Allow to use latest Autoprefixer from GitHub by npm.
* Add `--no-cascade`, `--annotation` and `--sources-content` options to binary.

## 1.3.1
* Fix gradient hack, when `background` property contains color.

## 1.3 “Tenka Fubu”
* Add `text-size-adjust` support.
* Add `background-size` to support Android 2.

## 1.2 “Meiji”
* Use Can I Use data from official `caniuse-db` npm package.
* Remove package data update from binary.
* Use increment value instead of current date in minor versions.

## 1.1 “Nutrisco et extingo”
* Add source map annotation comment support.
* Add inline source map support.
* Autodetect previous source map.
* Fix source maps support on Windows.
* Fix source maps support in subdirectory.
* Prefix selector even if it is already prefixed by developer.
* Add option `cascade` to create nice visual cascade of prefixes.
* Fix flexbox support for IE 10 (by Roland Warmerdam).
* Better `break-inside` support.
* Fix prefixing, when two same properties are near.

### 20140222
* Add `touch-action` support.

### 20140226
* Chrome 33 is moved to released versions.
* Add Chrome 36 data.

### 20140302
* Add `text-decoration-*` properties support.
* Update browsers usage statistics.
* Use new PostCSS version.

### 20140319
* Check already prefixed properties after current declaration.
* Normalize spaces before already prefixed check.
* Firefox 28 is moved to released versions.
* Add Firefox 31 data.
* Add some Blackberry data.

### 20140327
* Don’t use `-ms-transform` in `@keyframes`, because IE 9 doesn’t support
  animations.
* Update BlackBerry 10 data.

### 20140403
* Update browsers usage statistics.
* Opera 20 is moved to released versions.
* Add Opera 22 data.

### 20140410
* Chrome 34 is moved to released versions.
* Add Chrome 37 data.
* Fix Chrome 36 data.

### 20140429
* Fix `display: inline-flex` support by 2009 spec.
* Fix old WebKit gradient converter (by Sergey Belov).
* Fix CSS 3 cursors data (by Nick Schonning).

### 20140430
* Separate 2D and 3D transform prefixes to clean unnecessary `-ms-` prefixes.
* Firefox 29 is moved to released versions.
* Add Firefox 32 data.

### 20140510
* Do not add `-ms-` prefix for `transform` with 3D functions.
* Update browsers global usage statistics.

### 20140512
* Remove unnecessary `-moz-` prefix for `wavy` in `text-decoration`.
* Update Safari data for font properties.

### 20140521
* Chrome 36 is moved to released versions.
* Add Chrome 38 data.

### 20140523
* Opera 21 is moved to released versions.
* Add Opera 23 data.

### 20140605
* Allow to parse gradients without space between color and position.
* Add iOS 8, Safari 8 and Android 4.4.3 data.
* Update browsers usage statistics.

## 1.0 “Plus ultra”
* Source map support.
* Save origin indents and code formatting.
* Change CSS parser to PostCSS.
* Preserve vendor-prefixed properties put right after unprefixed ones.
* Rename `compile()` to `process()` and return result object,
  instead of CSS string.
* Rename `inspect()` to `info()`.
* Add in binary `-d` option to specify output directory.
* Binary now will not concat output files.
* Allow to select last versions for specified browser.
* Add full browser names aliases: `firefox`, `explorer` and `blackberry`.
* Ignore case in browser names.
* Change license to MIT.
* Add prefixes inside custom at-rules.
* Add only necessary prefixes to selector inside prefixed at-rule.
* Safer backgrounds list parser in gradient hack.
* Prefix `@keyframes` inside `@media`.
* Don’t prefix values for CSS3 PIE properties.
* Binary now shows file name in syntax error.
* Use browserify to build standalone version.

### 20131225
* Fix deprecated API convertor.
* Add `::placeholder` support for Firefix >= 18.
* Fix vendor prefixes order.

### 20140103
* Add `-webkit-` prefix for `sticky` position.
* Update browsers popularity statistics.

### 20140109
* Add selectors and at-rules sections to debug info.
* Fix outdated prefixes cleaning.

### 20140110
* Add `Firefox ESR` browser requirement.
* Opera 18 is moved to released versions.
* Add Opera 20 data.

### 20140117
* Chrome 32 is moved to released versions.
* Add Opera 34 data.

### 20140130
* Fix flexbox properties names in transitions.
* Add Chrome 35 and Firefox 29 data.

### 20140203
* Android 4.4 stock browser and Opera 19 are moved to released versions.
* Add Opera 21 data.
* Update browsers usage statistics.

### 20140213
* Add case insensitive to IE’s filter hack (by Dominik Schilling).
* Improve selector prefixing in some rare cases (by Simon Lydell).
* Firefox 27 is moved to released versions.
* Add Firefox 30 data.

## 0.8 “Unbowed, Unbent, Unbroken”
* Add more browsers to defaults ("> 1%, last 2 versions, ff 17, opera 12.1"
  instead of just "last 2 browsers").
* Keep vendor prefixes without unprefixed version (like vendor-specific hacks).
* Convert gradients to old WebKit syntax (actual for Android 2.3).
* Better support for several syntaxes with one prefix (like Flexbox and
  gradients in WebKit).
* Add intrinsic and extrinsic sizing values support.
* Remove never existed prefixes from common mistakes (like -ms-transition).
* Add Opera 17 data.
* Fix selector prefixes order.
* Fix browser versions order in inspect.

### 20130903
* Fix old WebKit gradients convertor on rgba() colors.
* Allow to write old direction syntax in gradients.

### 20130906
* Fix direction syntax in radial gradients.
* Don’t prefix IE filter with modern syntax.

### 20130911
* Fix parsing property name with spaces.

### 20130919
* Fix processing custom framework prefixes (by Johannes J. Schmidt).
* Concat outputs if several files compiled to one output.
* Decrease standalone build size by removing unnecessary Binary class.
* iOS 7 is moved to released versions.
* Clean up binary code (by Simon Lydell).

### 20130923
* Firefox 24 is moved to released versions.

### 20131001
* Add support for grab, grabbing, zoom-in and zoom-out cursor values.

### 20131006
* Chrome 30 is moved to released versions.

### 20131007
* Don’t add another prefixes in rule with prefixed selector.

### 20131009
* Opera 17 is moved to released versions.

### 20131015
* Fix converting multiple gradients to old webkit syntax (by Aleksei Androsov).

### 20131017
* Fix @host at-rule parsing.

### 20131020
* IE 11 and Andrid 4.3 is moved to released versions.
* Add Opera 18 data.
* Add @namespace support.
* Sort browser versions in data file.

### 20131029
* Add Safari 6.1 data.
* Add fx alias for Firefox.

### 20131104
* Update Android future version to 4.4.
* Google Chrome 32 added to future versions list.
* Firefox 25 now is actual version, 27 and 28 added to future versions.
* Browsers statistics are updated.

### 20131205
* Google Chrome 33 added to future releases list.
* Google Chrome 31 moved to current releases list.

### 20131209
* Use old webkit gradients for old iOS and Safari (by Chad von Nau).
* Fix direction conversion for old webkit gradients (by Chad von Nau).
* Update browsers popularity statistics.

### 20131213
* Firefox ESR in default browsers was changed to 24 version.
* Firefox 26 was moved to current releases list.
* Firefox 28 was added to future releases list.

## 0.7 “We Do Not Sow”
* Add vendor prefixes to selectors.
* Add ::selection and ::placeholder selectors support.
* Allow to load support data from Can I Use pull requests.
* Remove deprecated API.

### 20130806
* Add hyphens support.

### 20130807
* Add tab-size support.
* Add :fullscreen support.

### 20130808
* Allow to select browser versions by > and >= operator.
* Fix flex properties in transition.

### 20130810
* Add Firefox 25 data.

### 20130824
* Add Chrome 31 and 30 data.
* Fix CSS comments parsing (by vladkens).

## 0.6 “As High As Honor”
* New faster API, which cache preprocessed data. Old API is deprecated.
* A lot of perfomance improvements.
* Add Opera 15 -webkit- prefix support.
* Update Chrome 29 and Safari 7 prefixes data.
* Add minor browsers in popularity select.
* Better syntax error messages.

### 20130721
* Add Chrome 30 data.

### 20130728
* Don’t remove non-standard -webkit-background-clip: text.
* Don’t remove IE hack on CSS parse.

### 20130729
* Add Opera 16 data.
* Fix “Invalid range in character class” error on Firefox.

### 20130730
* Fix correct clone comments inside keyframes (by Alexey Plutalov).
* Fix angle recalculation in gradients (by Roman Komarov).

### 20130731
* Add border-image support.

## 0.5 “Ours is the Fury”
* Rewrite Autoprefixer to be more flexible.
* Use css, instead of Rework, to fix CSS parsing errors faster.
* Fix a lot of CSS parsing errors.

### 20130616
* More useful message for CSS parsing errors.
* Remove old WebKit gradient syntax.
* Fix parsing error on comment with braces.

### 20130617
* Remove old Mozilla border-radius.
* Don’t prefix old IE filter.
* Remove old background-clip, background-size and background-origin prefixes.
* Speed up regexps in values.
* Allow to hack property declarations.

### 20130625
* Convert flexbox properties to 2009 and 2012 specifications.
* Improve messages on syntax errors.

### 20130626
* Add Firefox 24 data.
* Add prefixes for font-feature-settings.

### 20130629
* Fix convert flex properties to old box-flex.

## 0.4 “Winter Is Coming”
* Remove outdated prefixes.
* Add border-radius and box-shadow properties to database.
* Change degrees in webkit gradients.

### 20130515
* Add old syntax in gradient direction.
* Add old syntax for display: flex.
* Update browser global usage statistics.

### 20130521
* Add Firefox 23 data.

### 20130524
* Add Chrome 29 data.

### 20130528
* Fix compatibilty with Rework from git master.
* Add minor browsers to data, which can be selected only directly.

### 20130530
* Add Opera 15 and iOS 6.1 data.
* Fix iOS versions in properties and values data.

### 20130603
* Use latest Rework 0.15 with a lot of CSS parsing fixes.
* Update browsers usage statistics.

## 0.3 “Growing Strong”
* Rename `autoprefixer.filter()` to `autoprefixer.rework()`.
* Use own filters instead of Rework’s `prefix` and `prefixValue`.
* Smarter value prefixer without false match “order” in “border”.
* 40% faster.
* Don’t add unnecessary properties instead of Rework’s `prefixValue`.
* Don’t change properties order.
* Sort properties and values in inspect output.
* Add main to component config (by Jonathan Ong).
* Fix documentation (by Sergey Leschina and Mark Vasilkov).

### 20130424
* Fix value override in prefixer.

### 20130427
* Prefix several same values in one property.
* Fix Windows support in binary.
* Improve print errors in binary.

### 20130502
* Don’t add -webkit- prefix to IE filter.
* Don’t duplicate prefixes on second run.

## 0.2 “Hear Me Roar!”
* Update parse libraries.
* Use component package manager to build standalone script.
* Add inspect to standalone script.

## 0.1 “Fire and Blood”
* Initial release.


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright 2013 Andrey Sitnik <andrey@sitnik.ru>

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.


================================================
FILE: README.md
================================================
# Autoprefixer [![Cult Of Martians][cult-img]][cult]

<img align="right" width="94" height="71"
     src="https://postcss.github.io/autoprefixer/logo.svg"
     title="Autoprefixer logo by Anton Lovchikov">

[PostCSS] plugin to parse CSS and add vendor prefixes to CSS rules using values
from [Can I Use]. It is recommended by Google and used in Twitter and Alibaba.

Write your CSS rules without vendor prefixes (in fact, forget about them
entirely):

```css
::placeholder {
  color: gray;
}

.image {
  width: stretch;
}
```

Autoprefixer will use the data based on current browser popularity and property
support to apply prefixes for you. You can try the [interactive demo]
of Autoprefixer.

```css
::-moz-placeholder {
  color: gray;
}
::placeholder {
  color: gray;
}

.image {
  width: -webkit-fill-available;
  width: -moz-available;
  width: stretch;
}
```

Twitter account for news and releases: [@autoprefixer].

<a href="https://evilmartians.com/?utm_source=autoprefixer">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
</a>

[interactive demo]: https://autoprefixer.github.io/
[@autoprefixer]:    https://twitter.com/autoprefixer
[Can I Use]:        https://caniuse.com/
[cult-img]:         https://cultofmartians.com/assets/badges/badge.svg
[PostCSS]:          https://github.com/postcss/postcss
[cult]:             https://cultofmartians.com/tasks/autoprefixer-grid.html


## Contents

* [Contents](#contents)
* [Browsers](#browsers)
* [FAQ](#faq)
  * [Does Autoprefixer polyfill Grid Layout for IE?](#does-autoprefixer-polyfill-grid-layout-for-ie)
  * [Does it add polyfills?](#does-it-add-polyfills)
  * [Why doesn’t Autoprefixer add prefixes to `border-radius`?](#why-doesnt-autoprefixer-add-prefixes-to-border-radius)
  * [Why does Autoprefixer use unprefixed properties in `@-webkit-keyframes`?](#why-does-autoprefixer-use-unprefixed-properties-in--webkit-keyframes)
  * [How to work with legacy `-webkit-` only code?](#how-to-work-with-legacy--webkit--only-code)
  * [Does Autoprefixer add `-epub-` prefix?](#does-autoprefixer-add--epub--prefix)
  * [Why doesn’t Autoprefixer transform generic font-family `system-ui`?](#why-doesnt-autoprefixer-transform-generic-font-family-system-ui)
* [Usage](#usage)
  * [Gulp](#gulp)
  * [Webpack](#webpack)
  * [CSS-in-JS](#css-in-js)
  * [CLI](#cli)
  * [Other Build Tools](#other-build-tools)
    * [Preprocessors](#preprocessors)
    * [GUI Tools](#gui-tools)
  * [JavaScript](#javascript)
  * [Text Editors and IDE](#text-editors-and-ide)
* [Warnings](#warnings)
* [Disabling](#disabling)
  * [Prefixes](#prefixes)
  * [Features](#features)
  * [Control Comments](#control-comments)
* [Options](#options)
* [Environment Variables](#environment-variables)
  * [Using environment variables to support CSS Grid prefixes in Create React App](#using-environment-variables-to-support-css-grid-prefixes-in-create-react-app)
* [Grid Autoplacement support in IE](#grid-autoplacement-support-in-ie)
  * [Beware of enabling autoplacement in old projects](#beware-of-enabling-autoplacement-in-old-projects)
  * [Autoplacement limitations](#autoplacement-limitations)
    * [Both columns and rows must be defined](#both-columns-and-rows-must-be-defined)
    * [Repeat auto-fit and auto-fill are not supported](#repeat-auto-fit-and-auto-fill-are-not-supported)
    * [No manual cell placement or column/row spans allowed inside an autoplacement grid](#no-manual-cell-placement-or-columnrow-spans-allowed-inside-an-autoplacement-grid)
    * [Do not create `::before` and `::after` pseudo elements](#do-not-create-before-and-after-pseudo-elements)
    * [When changing the `grid gap` value, columns and rows must be re-declared](#when-changing-the-grid-gap-value-columns-and-rows-must-be-re-declared)
* [Debug](#debug)
* [Security Contact](#security-contact)
* [For Enterprise](#for-enterprise)

## Browsers

Autoprefixer uses [Browserslist], so you can specify the browsers
you want to target in your project with queries like `> 5%`
(see [Best Practices]).

The best way to provide browsers is a `.browserslistrc` file in your project
root, or by adding a `browserslist` key to your `package.json`.

We recommend the use of these options over passing options to Autoprefixer so
that the config can be shared with other tools such as [babel-preset-env] and
[Stylelint].

See [Browserslist docs] for queries, browser names, config format, and defaults.

[Browserslist docs]: https://github.com/browserslist/browserslist#queries
[babel-preset-env]:  https://github.com/babel/babel/tree/master/packages/babel-preset-env
[Best Practices]:    https://github.com/browserslist/browserslist#best-practices
[Browserslist]:      https://github.com/browserslist/browserslist
[Stylelint]:         https://stylelint.io/


## FAQ

### Does Autoprefixer polyfill Grid Layout for IE?

Autoprefixer can be used to translate modern CSS Grid syntax into IE 10
and IE 11 syntax, but this polyfill will not work in 100% of cases.
This is why it is disabled by default.

First, you need to enable Grid prefixes by using either the `grid: "autoplace"`
option or the `/* autoprefixer grid: autoplace */` control comment.
Also you can use environment variable to enable Grid:
`AUTOPREFIXER_GRID=autoplace npm build`.

Second, you need to test every fix with Grid in IE. It is not an enable and
forget feature, but it is still very useful.
Financial Times and Yandex use it in production.

Third, there is only very limited auto placement support. Read the
[Grid Autoplacement support in IE](#grid-autoplacement-support-in-ie) section
for more details.

Fourth, if you are not using the autoplacement feature, the best way
to use Autoprefixer is by using  `grid-template` or `grid-template-areas`.

```css
.page {
  display: grid;
  grid-gap: 33px;
  grid-template:
    "head head  head" 1fr
    "nav  main  main" minmax(100px, 1fr)
    "nav  foot  foot" 2fr /
    1fr   100px 1fr;
}
.page__head {
  grid-area: head;
}
.page__nav {
  grid-area: nav;
}
.page__main {
  grid-area: main;
}
.page__footer {
  grid-area: foot;
}
```

See also:

* [The guide about Grids in IE and Autoprefixer].
* [`postcss-gap-properties`] to use new `gap` property
  instead of old `grid-gap`.
* [`postcss-grid-kiss`] has alternate “everything in one property” syntax,
  which makes using Autoprefixer’s Grid translations safer.

[The guide about Grids in IE and Autoprefixer]: https://css-tricks.com/css-grid-in-ie-css-grid-and-the-new-autoprefixer/
[`postcss-gap-properties`]:                     https://github.com/jonathantneal/postcss-gap-properties
[`postcss-grid-kiss`]:                          https://github.com/sylvainpolletvillard/postcss-grid-kiss


### Does it add polyfills?

No. Autoprefixer only adds prefixes.

Most new CSS features will require client side JavaScript to handle a new
behavior correctly.

Depending on what you consider to be a “polyfill”, you can take a look at some
other tools and libraries. If you are just looking for syntax sugar,
you might take a look at:

- [postcss-preset-env] is a plugins preset with polyfills and Autoprefixer
  to write future CSS today.
- [Oldie], a PostCSS plugin that handles some IE hacks (opacity, rgba, etc).
- [postcss-flexbugs-fixes], a PostCSS plugin to fix flexbox issues.

[postcss-flexbugs-fixes]: https://github.com/luisrudge/postcss-flexbugs-fixes
[postcss-preset-env]:     https://github.com/jonathantneal/postcss-preset-env
[Oldie]:                  https://github.com/jonathantneal/oldie


### Why doesn’t Autoprefixer add prefixes to `border-radius`?

Developers are often surprised by how few prefixes are required today.
If Autoprefixer doesn’t add prefixes to your CSS, check if they’re still
required on [Can I Use].

[Can I Use]: https://caniuse.com/


### Why does Autoprefixer use unprefixed properties in `@-webkit-keyframes`?

Browser teams can remove some prefixes before others, so we try to use all
combinations of prefixed/unprefixed values.


### How to work with legacy `-webkit-` only code?

Autoprefixer needs unprefixed property to add prefixes. So if you only
wrote `-webkit-gradient` without W3C’s `gradient`,
Autoprefixer will not add other prefixes.

But [PostCSS] has plugins to convert CSS to unprefixed state.
Use [postcss-unprefix] before Autoprefixer.

[postcss-unprefix]: https://github.com/gucong3000/postcss-unprefix


### Does Autoprefixer add `-epub-` prefix?

No, Autoprefixer works only with browsers prefixes from Can I Use.
But you can use [postcss-epub] for prefixing ePub3 properties.

[postcss-epub]: https://github.com/Rycochet/postcss-epub


### Why doesn’t Autoprefixer transform generic font-family `system-ui`?

`system-ui` is technically not a prefix and the transformation is not
future-proof. You can use [postcss-font-family-system-ui] to transform
`system-ui` to a practical font-family list.

[postcss-font-family-system-ui]: https://github.com/JLHwung/postcss-font-family-system-ui


## Usage

### Gulp

In Gulp you can use [gulp-postcss] with `autoprefixer` npm package.

```js
gulp.task('autoprefixer', () => {
  const autoprefixer = require('autoprefixer')
  const sourcemaps = require('gulp-sourcemaps')
  const postcss = require('gulp-postcss')

  return gulp.src('./src/*.css')
    .pipe(sourcemaps.init())
    .pipe(postcss([ autoprefixer() ]))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dest'))
})
```

With `gulp-postcss` you also can combine Autoprefixer
with [other PostCSS plugins].

[gulp-postcss]:          https://github.com/postcss/gulp-postcss
[other PostCSS plugins]: https://github.com/postcss/postcss#plugins


### Webpack

In [webpack] you can use [postcss-loader] with `autoprefixer`
and [other PostCSS plugins].

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

And create a `postcss.config.js` with:

```js
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}
```

[other PostCSS plugins]: https://github.com/postcss/postcss#plugins
[postcss-loader]:        https://github.com/postcss/postcss-loader
[webpack]:               https://webpack.js.org/


### CSS-in-JS

The best way to use PostCSS with CSS-in-JS is [`astroturf`].
Add its loader to your `webpack.config.js`:

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'postcss-loader'],
      },
      {
        test: /\.jsx?$/,
        use: ['babel-loader', 'astroturf/loader'],
      }
    ]
  }
}
```

Then create `postcss.config.js`:

```js
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}
```

[`astroturf`]: https://github.com/4Catalyzer/astroturf


### CLI

You can use the [postcss-cli] to run Autoprefixer from CLI:

```sh
npm install postcss postcss-cli autoprefixer
npx postcss *.css --use autoprefixer -d build/
```

See `postcss -h` for help.

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


### Other Build Tools

* **Grunt:** [grunt-postcss]
* **Ruby on Rails**: [autoprefixer-rails]
* **Neutrino**: [neutrino-middleware-postcss]
* **Jekyll**: add `autoprefixer-rails` and `jekyll-assets` to `Gemfile`
* **Brunch**: [postcss-brunch]
* **Broccoli**: [broccoli-postcss]
* **Middleman**: [middleman-autoprefixer]
* **Mincer**: add `autoprefixer` npm package and enable it:
  `environment.enable('autoprefixer')`

[neutrino-middleware-postcss]: https://www.npmjs.com/package/neutrino-middleware-postcss
[middleman-autoprefixer]:      https://github.com/middleman/middleman-autoprefixer
[autoprefixer-rails]:          https://github.com/ai/autoprefixer-rails
[broccoli-postcss]:            https://github.com/jeffjewiss/broccoli-postcss
[postcss-brunch]:              https://github.com/iamvdo/postcss-brunch
[grunt-postcss]:               https://github.com/C-Lodder/grunt-postcss


#### Preprocessors

* **Less**: [less-plugin-autoprefix]
* **Stylus**: [autoprefixer-stylus]
* **Compass**: [autoprefixer-rails#compass]

[less-plugin-autoprefix]: https://github.com/less/less-plugin-autoprefix
[autoprefixer-stylus]:    https://github.com/jenius/autoprefixer-stylus
[autoprefixer-rails#compass]:     https://github.com/ai/autoprefixer-rails#compass


#### GUI Tools

* [CodeKit](https://codekitapp.com/help/autoprefixer/)
* [Prepros](https://prepros.io)


### JavaScript

You can use Autoprefixer with [PostCSS] in your Node.js application
or if you want to develop an Autoprefixer plugin for a new environment.

```js
const autoprefixer = require('autoprefixer')
const postcss = require('postcss')

postcss([ autoprefixer ]).process(css).then(result => {
  result.warnings().forEach(warn => {
    console.warn(warn.toString())
  })
  console.log(result.css)
})
```

There is also a [standalone build] for the browser or for a non-Node.js runtime.

You can use [html-autoprefixer] to process HTML with inlined CSS.

[html-autoprefixer]: https://github.com/RebelMail/html-autoprefixer
[standalone build]:  https://raw.github.com/ai/autoprefixer-rails/master/vendor/autoprefixer.js
[PostCSS]:           https://github.com/postcss/postcss


### Text Editors and IDE

Autoprefixer should be used in assets build tools. Text editor plugins are not
a good solution, because prefixes decrease code readability and you will need
to change values in all prefixed properties.

I recommend you to learn how to use build tools like [Parcel].
They work much better and will open you a whole new world of useful plugins
and automation.

If you can’t move to a build tool, you can use text editor plugins:

* [Visual Studio Code](https://github.com/mrmlnc/vscode-autoprefixer)
* [Sublime Text](https://github.com/sindresorhus/sublime-autoprefixer)

[Parcel]: https://parceljs.org/


## Warnings

Autoprefixer uses the [PostCSS warning API] to warn about really important
problems in your CSS:

* Old direction syntax in gradients.
* Old unprefixed `display: box` instead of `display: flex`
  by latest specification version.

You can get warnings from `result.warnings()`:

```js
result.warnings().forEach(warn => {
  console.warn(warn.toString())
})
```

Every Autoprefixer runner should display these warnings.

[PostCSS warning API]: https://postcss.org/api/#warning


## Disabling

### Prefixes

Autoprefixer was designed to have no interface – it just works.
If you need some browser specific hack just write a prefixed property
after the unprefixed one.

```css
a {
  transform: scale(0.5);
  -moz-transform: scale(0.6);
}
```

If some prefixes were generated incorrectly, please create an [issue on GitHub].

[issue on GitHub]: https://github.com/postcss/autoprefixer/issues


### Features

You can use these plugin options to control some of Autoprefixer’s features.

* `grid: "autoplace"` will enable `-ms-` prefixes for Grid Layout including some
  [limited autoplacement support](#grid-autoplacement-support-in-ie).
* `supports: false` will disable `@supports` parameters prefixing.
* `flexbox: false` will disable flexbox properties prefixing.
  Or `flexbox: "no-2009"` will add prefixes only for final and IE
  versions of specification.
* `remove: false` will disable cleaning outdated prefixes.

You should set them inside the plugin like so:

```js
autoprefixer({ grid: 'autoplace' })
```


### Control Comments

If you do not need Autoprefixer in some part of your CSS,
you can use control comments to disable Autoprefixer.

```css
.a {
  transition: 1s; /* will be prefixed */
}

.b {
  /* autoprefixer: off */
  transition: 1s; /* will not be prefixed */
}

.c {
  /* autoprefixer: ignore next */
  transition: 1s; /* will not be prefixed */
  mask: url(image.png); /* will be prefixed */
}
```

There are three types of control comments:

* `/* autoprefixer: (on|off) */`: enable/disable all Autoprefixer translations for the
  whole block both *before* and *after* the comment.
* `/* autoprefixer: ignore next */`: disable Autoprefixer only for the next property
  or next rule selector or at-rule parameters (but not rule/at‑rule body).
* `/* autoprefixer grid: (autoplace|no-autoplace|off) */`: control how Autoprefixer handles
  grid translations for the whole block:
  * `autoplace`: enable grid translations with autoplacement support.
  * `no-autoplace`: enable grid translations with autoplacement
    support *disabled* (alias for deprecated value `on`).
  * `off`: disable all grid translations.

You can also use comments recursively:

```css
/* autoprefixer: off */
@supports (transition: all) {
  /* autoprefixer: on */
  a {
    /* autoprefixer: off */
  }
}
```

Note that comments that disable the whole block should not be featured in the same
block twice:

```css
/* How not to use block level control comments */

.do-not-do-this {
  /* autoprefixer: off */
  transition: 1s;
  /* autoprefixer: on */
  transform: rotate(20deg);
}
```


## Options

Function `autoprefixer(options)` returns a new PostCSS plugin.
See [PostCSS API] for plugin usage documentation.

```js
autoprefixer({ cascade: false })
```

Available options are:

* `env` (string): environment for Browserslist.
* `cascade` (boolean): should Autoprefixer use Visual Cascade,
  if CSS is uncompressed. Default: `true`
* `add` (boolean): should Autoprefixer add prefixes. Default is `true`.
* `remove` (boolean): should Autoprefixer [remove outdated] prefixes.
  Default is `true`.
* `supports` (boolean): should Autoprefixer add prefixes for `@supports`
  parameters. Default is `true`.
* `flexbox` (boolean|string): should Autoprefixer add prefixes for flexbox
  properties. With `"no-2009"` value Autoprefixer will add prefixes only
  for final and IE 10 versions of specification. Default is `true`.
* `grid` (false|`"autoplace"`|`"no-autoplace"`): should Autoprefixer
  add IE 10-11 prefixes for Grid Layout properties?
    * `false` (default): prevent Autoprefixer from outputting
       CSS Grid translations.
    * `"autoplace"`: enable Autoprefixer grid translations
      and *include* autoplacement support. You can also use
      `/* autoprefixer grid: autoplace */` in your CSS.
    * `"no-autoplace"`: enable Autoprefixer grid translations
      but *exclude* autoplacement support. You can also use
      `/* autoprefixer grid: no-autoplace */` in your CSS.
      (alias for the deprecated `true` value)
* `stats` (object): custom [usage statistics] for `> 10% in my stats`
  browsers query.
* `overrideBrowserslist` (array): list of queries for target browsers.
  Try to not use it. The best practice is to use `.browserslistrc` config
  or `browserslist` key in `package.json` to share target browsers
  with Babel, ESLint and Stylelint. See [Browserslist docs]
  for available queries and default value.
* `ignoreUnknownVersions` (boolean): do not raise error on unknown browser
  version in Browserslist config. Default is `false`.

Plugin object has `info()` method for debugging purpose.

You can use PostCSS processor to process several CSS files
to increase performance.

[usage statistics]: https://github.com/browserslist/browserslist#custom-usage-data
[PostCSS API]:      https://postcss.org/api/

## Environment Variables

* `AUTOPREFIXER_GRID`: (`autoplace`|`no-autoplace`) should Autoprefixer
  add IE 10-11 prefixes for Grid Layout properties?
    * `autoplace`: enable Autoprefixer grid translations
      and *include* autoplacement support.
    * `no-autoplace`: enable Autoprefixer grid translations
      but *exclude* autoplacement support.

Environment variables are useful, when you want to change Autoprefixer options but don't have access to config files.
[Create React App] is a good example of this.

[Create React App]: (https://reactjs.org/docs/create-a-new-react-app.html#create-react-app)

### Using environment variables to support CSS Grid prefixes in Create React App

1. Install the latest version of Autoprefixer and [cross-env](https://www.npmjs.com/package/cross-env):

```
npm install autoprefixer@latest cross-env --save-dev
```

2. Under `"browserslist"` > `"development"` in the package.json file, add `"last 1 ie version"`

```
"browserslist": {
  "production": [
    ">0.2%",
    "not dead",
    "not op_mini all"
  ],
  "development": [
    "last 1 chrome version",
    "last 1 firefox version",
    "last 1 safari version",
    "last 1 ie version"
  ]
}
```

3. Update `"scripts"` in the package.json file to the following:

```
"scripts": {
  "start": "cross-env AUTOPREFIXER_GRID=autoplace react-scripts start",
  "build": "cross-env AUTOPREFIXER_GRID=autoplace react-scripts build",
  "test": "cross-env AUTOPREFIXER_GRID=autoplace react-scripts test",
  "eject": "react-scripts eject"
},
```

Replace `autoplace` with `no-autoplace` in the above example if you prefer to disable Autoprefixer Grid autoplacement support.

Now when you run `npm start` you will see CSS Grid prefixes automatically being applied to your output CSS.

See also [Browserslist environment variables] for more examples on how to use environment variables in your project.

[Browserslist environment variables]: https://github.com/browserslist/browserslist#environment-variables

## Grid Autoplacement support in IE

If the `grid` option is set to `"autoplace"`, limited autoplacement support is added to Autoprefixers grid translations. You can also use
the `/* autoprefixer grid: autoplace */` control comment or
`AUTOPREFIXER_GRID=autoplace npm build` environment variable.

Autoprefixer will only autoplace grid cells if both `grid-template-rows`
and `grid-template-columns` has been set. If `grid-template`
or `grid-template-areas` has been set, Autoprefixer will use area based
cell placement instead.

Autoprefixer supports autoplacement by using `nth-child` CSS selectors.
It creates [number of columns] x [number of rows] `nth-child` selectors.
For this reason Autoplacement is only supported within the explicit grid.

```css
/* Input CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}
```

```css
/* Output CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto 20px auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}

.autoplacement-example > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
}

.autoplacement-example > *:nth-child(3) {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(4) {
  -ms-grid-row: 3;
  -ms-grid-column: 3;
}
```

### Beware of enabling autoplacement in old projects

Be careful about enabling autoplacement in any already established projects that have
previously not used Autoprefixer's grid autoplacement feature before.

If this was your html:

```html
<div class="grid">
  <div class="grid-cell"></div>
</div>
```

The following CSS will not work as expected with the autoplacement feature enabled:

```css
/* Unsafe CSS when Autoplacement is enabled */

.grid-cell {
  grid-column: 2;
  grid-row: 2;
}

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```

Swapping the rules around will not fix the issue either:

```css
/* Also unsafe to use this CSS */

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

.grid-cell {
  grid-column: 2;
  grid-row: 2;
}
```

One way to deal with this issue is to disable autoplacement in the
grid-declaration rule:

```css
/* Disable autoplacement to fix the issue */

.grid {
  /* autoprefixer grid: no-autoplace */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

.grid-cell {
  grid-column: 2;
  grid-row: 2;
}
```

The absolute best way to integrate autoplacement into already existing projects
though is to leave autoplacement turned off by default and then use a control
comment to enable it when needed. This method is far less likely to cause
something on the site to break.

```css
/* Disable autoplacement by default in old projects */
/* autoprefixer grid: no-autoplace */

/* Old code will function the same way it always has */
.old-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
.old-grid-cell {
  grid-column: 2;
  grid-row: 2;
}

/* Enable autoplacement when you want to use it in new code */
.new-autoplace-friendly-grid {
  /* autoprefixer grid: autoplace */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, auto);
}
```

Note that the `grid: "no-autoplace"` setting and the
`/* autoprefixer grid: no-autoplace */` control comment share identical
functionality to the `grid: true` setting and the `/* autoprefixer grid: on */`
control comment. There is no need to refactor old code to use `no-autoplace`
in place of the old `true` and `on` statements.

### Autoplacement limitations

#### Both columns and rows must be defined

Autoplacement only works inside the explicit grid. The columns and rows need to be defined
so that Autoprefixer knows how many `nth-child` selectors to generate.

```css
.not-allowed {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.is-allowed {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(10, auto);
}
```

#### Repeat auto-fit and auto-fill are not supported

The `repeat(auto-fit, ...)` and `repeat(auto-fill, ...)` grid functionality relies on
knowledge from the browser about screen dimensions and the number of available grid
items for it to work properly. Autoprefixer does not have access to this information
so unfortunately this little snippet will _never_ be IE friendly.

```css
.grid {
  /* This will never be IE friendly */
  grid-template-columns: repeat(auto-fit, min-max(200px, 1fr))
}
```

#### No manual cell placement or column/row spans allowed inside an autoplacement grid

Elements must not be manually placed or given column/row spans inside
an autoplacement grid. Only the most basic of autoplacement grids are supported.
Grid cells can still be placed manually outside the the explicit grid though.
Support for manually placing individual grid cells inside an explicit
autoplacement grid is planned for a future release.

```css
.autoplacement-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, auto);
}

/* Grid cells placed inside the explicit grid
   will break the layout in IE */
.not-permitted-grid-cell {
  grid-column: 1;
  grid-row: 1;
}

/* Grid cells placed outside the
   explicit grid will work in IE */
.permitted-grid-cell {
  grid-column: 1 / span 2;
  grid-row: 4;
}
```

If manual cell placement is required, we recommend using `grid-template` or
`grid-template-areas` instead:

```css
.page {
  display: grid;
  grid-gap: 30px;
  grid-template:
      "head head"
      "nav  main" minmax(100px, 1fr)
      "foot foot" /
      200px 1fr;
}
.page__head {
  grid-area: head;
}
.page__nav {
  grid-area: nav;
}
.page__main {
  grid-area: main;
}
.page__footer {
  grid-area: foot;
}
```

#### Do not create `::before` and `::after` pseudo elements

Let's say you have this HTML:

```html
<div class="grid">
  <div class="grid-cell"></div>
</div>
```

And you write this CSS:

```css
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
}

.grid::before {
  content: 'before';
}

.grid::after {
  content: 'after';
}
```

This will be the output:

```css
.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto;
  grid-template-rows: auto;
}

.grid > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}


.grid > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 2;
}

.grid::before {
  content: 'before';
}

.grid::after {
  content: 'after';
}
```

IE will place `.grid-cell`, `::before` and `::after` in row 1 column 1.
Modern browsers on the other hand will place `::before` in row 1 column 1,
`.grid-cell` in row 1 column 2, and `::after` in row 2 column 1.

See this [CodePen](https://codepen.io/daniel-tonon/pen/gBymVw) to see a visualization
of the issue. View the CodePen in both a modern browser and IE to see the difference.

Note that you can still create `::before` and `::after` elements as long as you manually
place them outside the explicit grid.

#### When changing the `grid gap` value, columns and rows must be re-declared

If you wish to change the size of a `grid-gap`, you will need to redeclare the grid columns and rows.

```css
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  grid-gap: 50px;
}

/* This will *NOT* work in IE */
@media (max-width: 600px) {
  .grid {
    grid-gap: 20px;
  }
}

/* This will *NOT* work in IE */
.grid.small-gap {
  grid-gap: 20px;
}
```

```css
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  grid-gap: 50px;
}

/* This *WILL* work in IE */
@media (max-width: 600px) {
  .grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    grid-gap: 20px;
  }
}

/* This *WILL* work in IE */
.grid.small-gap {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  grid-gap: 20px;
}
```

## Debug

Run `npx autoprefixer --info` in your project directory to check
which browsers are selected and which properties will be prefixed:

```console
$ npx autoprefixer --info
Browsers:
  Edge: 16

These browsers account for 0.26% of all users globally

At-Rules:
  @viewport: ms

Selectors:
  ::placeholder: ms

Properties:
  appearance: webkit
  flow-from: ms
  flow-into: ms
  hyphens: ms
  overscroll-behavior: ms
  region-fragment: ms
  scroll-snap-coordinate: ms
  scroll-snap-destination: ms
  scroll-snap-points-x: ms
  scroll-snap-points-y: ms
  scroll-snap-type: ms
  text-size-adjust: ms
  text-spacing: ms
  user-select: ms
```

JS API is also available:

```js
console.log(autoprefixer().info())
```

## Security Contact

To report a security vulnerability, please use the [Tidelift security contact].
Tidelift will coordinate the fix and disclosure.

[Tidelift security contact]: https://tidelift.com/security

## For Enterprise

Available as part of the Tidelift Subscription.

The maintainers of `autoprefixer` and thousands of other packages are working
with Tidelift to deliver commercial support and maintenance for the open source
dependencies you use to build your applications. Save time, reduce risk,
and improve code health, while paying the maintainers of the exact dependencies
you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-autoprefixer?utm_source=npm-autoprefixer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)


================================================
FILE: bin/autoprefixer
================================================
#!/usr/bin/env node

let mode = process.argv[2]
if (mode === '--info') {
  process.stdout.write(require('../')().info() + '\n')
} else if (mode === '--version') {
  process.stdout.write(
    'autoprefixer ' + require('../package.json').version + '\n'
  )
} else {
  process.stdout.write(
    'autoprefix\n' +
      '\n' +
      'Options:\n' +
      '  --info    Show target browsers and used prefixes\n' +
      '  --version Show version number\n' +
      '  --help    Show help\n' +
      '\n' +
      'Usage:\n' +
      '  autoprefixer --info\n'
  )
}


================================================
FILE: data/prefixes.js
================================================
let unpack = require('caniuse-lite/dist/unpacker/feature')

function browsersSort(a, b) {
  a = a.split(' ')
  b = b.split(' ')
  if (a[0] > b[0]) {
    return 1
  } else if (a[0] < b[0]) {
    return -1
  } else {
    return Math.sign(parseFloat(a[1]) - parseFloat(b[1]))
  }
}

// Convert Can I Use data
function f(data, opts, callback) {
  data = unpack(data)

  if (!callback) {
    ;[callback, opts] = [opts, {}]
  }

  let match = opts.match || /\sx($|\s)/
  let need = []

  for (let browser in data.stats) {
    let versions = data.stats[browser]
    for (let version in versions) {
      let support = versions[version]
      if (support.match(match)) {
        need.push(browser + ' ' + version)
      }
    }
  }

  callback(need.sort(browsersSort))
}

// Add data for all properties
let result = {}

function prefix(names, data) {
  for (let name of names) {
    result[name] = Object.assign({}, data)
  }
}

function add(names, data) {
  for (let name of names) {
    result[name].browsers = result[name].browsers
      .concat(data.browsers)
      .sort(browsersSort)
  }
}

module.exports = result

// Border Radius
let prefixBorderRadius = require('caniuse-lite/data/features/border-radius')

f(prefixBorderRadius, browsers =>
  prefix(
    [
      'border-radius',
      'border-top-left-radius',
      'border-top-right-radius',
      'border-bottom-right-radius',
      'border-bottom-left-radius'
    ],
    {
      browsers,
      feature: 'border-radius',
      mistakes: ['-khtml-', '-ms-', '-o-']
    }
  )
)

// Box Shadow
let prefixBoxshadow = require('caniuse-lite/data/features/css-boxshadow')

f(prefixBoxshadow, browsers =>
  prefix(['box-shadow'], {
    browsers,
    feature: 'css-boxshadow',
    mistakes: ['-khtml-']
  })
)

// Animation
let prefixAnimation = require('caniuse-lite/data/features/css-animation')

f(prefixAnimation, browsers =>
  prefix(
    [
      'animation',
      'animation-name',
      'animation-duration',
      'animation-delay',
      'animation-direction',
      'animation-fill-mode',
      'animation-iteration-count',
      'animation-play-state',
      'animation-timing-function',
      '@keyframes'
    ],
    {
      browsers,
      feature: 'css-animation',
      mistakes: ['-khtml-', '-ms-']
    }
  )
)

// Transition
let prefixTransition = require('caniuse-lite/data/features/css-transitions')

f(prefixTransition, browsers =>
  prefix(
    [
      'transition',
      'transition-property',
      'transition-duration',
      'transition-delay',
      'transition-timing-function'
    ],
    {
      browsers,
      feature: 'css-transitions',
      mistakes: ['-khtml-', '-ms-']
    }
  )
)

// Transform 2D
let prefixTransform2d = require('caniuse-lite/data/features/transforms2d')

f(prefixTransform2d, browsers =>
  prefix(['transform', 'transform-origin'], {
    browsers,
    feature: 'transforms2d'
  })
)

// Transform 3D
let prefixTransforms3d = require('caniuse-lite/data/features/transforms3d')

f(prefixTransforms3d, browsers => {
  prefix(['perspective', 'perspective-origin'], {
    browsers,
    feature: 'transforms3d'
  })
  return prefix(['transform-style'], {
    browsers,
    feature: 'transforms3d',
    mistakes: ['-ms-', '-o-']
  })
})

f(prefixTransforms3d, { match: /y\sx|y\s#2/ }, browsers =>
  prefix(['backface-visibility'], {
    browsers,
    feature: 'transforms3d',
    mistakes: ['-ms-', '-o-']
  })
)

// Gradients
let prefixGradients = require('caniuse-lite/data/features/css-gradients')

f(prefixGradients, { match: /y\sx/ }, browsers =>
  prefix(
    [
      'linear-gradient',
      'repeating-linear-gradient',
      'radial-gradient',
      'repeating-radial-gradient'
    ],
    {
      browsers,
      feature: 'css-gradients',
      mistakes: ['-ms-'],
      props: [
        'background',
        'background-image',
        'border-image',
        'mask',
        'list-style',
        'list-style-image',
        'content',
        'mask-image'
      ]
    }
  )
)

f(prefixGradients, { match: /a\sx/ }, browsers => {
  browsers = browsers.map(i => {
    if (/firefox|op/.test(i)) {
      return i
    } else {
      return `${i} old`
    }
  })
  return add(
    [
      'linear-gradient',
      'repeating-linear-gradient',
      'radial-gradient',
      'repeating-radial-gradient'
    ],
    {
      browsers,
      feature: 'css-gradients'
    }
  )
})

// Box sizing
let prefixBoxsizing = require('caniuse-lite/data/features/css3-boxsizing')

f(prefixBoxsizing, browsers =>
  prefix(['box-sizing'], {
    browsers,
    feature: 'css3-boxsizing'
  })
)

// Filter Effects
let prefixFilters = require('caniuse-lite/data/features/css-filters')

f(prefixFilters, browsers =>
  prefix(['filter'], {
    browsers,
    feature: 'css-filters'
  })
)

// filter() function
let prefixFilterFunction = require('caniuse-lite/data/features/css-filter-function')

f(prefixFilterFunction, browsers =>
  prefix(['filter-function'], {
    browsers,
    feature: 'css-filter-function',
    props: [
      'background',
      'background-image',
      'border-image',
      'mask',
      'list-style',
      'list-style-image',
      'content',
      'mask-image'
    ]
  })
)

// Backdrop-filter
let prefixBackdropFilter = require('caniuse-lite/data/features/css-backdrop-filter')

f(prefixBackdropFilter, { match: /y\sx|y\s#2/ }, browsers =>
  prefix(['backdrop-filter'], {
    browsers,
    feature: 'css-backdrop-filter'
  })
)

// element() function
let prefixElementFunction = require('caniuse-lite/data/features/css-element-function')

f(prefixElementFunction, browsers =>
  prefix(['element'], {
    browsers,
    feature: 'css-element-function',
    props: [
      'background',
      'background-image',
      'border-image',
      'mask',
      'list-style',
      'list-style-image',
      'content',
      'mask-image'
    ]
  })
)

// Multicolumns
let prefixMulticolumns = require('caniuse-lite/data/features/multicolumn')

f(prefixMulticolumns, browsers => {
  prefix(
    [
      'columns',
      'column-width',
      'column-gap',
      'column-rule',
      'column-rule-color',
      'column-rule-width',
      'column-count',
      'column-rule-style',
      'column-span',
      'column-fill'
    ],
    {
      browsers,
      feature: 'multicolumn'
    }
  )

  let noff = browsers.filter(i => !/firefox/.test(i))
  prefix(['break-before', 'break-after', 'break-inside'], {
    browsers: noff,
    feature: 'multicolumn'
  })
})

// User select
let prefixUserSelect = require('caniuse-lite/data/features/user-select-none')

f(prefixUserSelect, browsers =>
  prefix(['user-select'], {
    browsers,
    feature: 'user-select-none',
    mistakes: ['-khtml-']
  })
)

// Flexible Box Layout
let prefixFlexbox = require('caniuse-lite/data/features/flexbox')

f(prefixFlexbox, { match: /a\sx/ }, browsers => {
  browsers = browsers.map(i => {
    if (/ie|firefox/.test(i)) {
      return i
    } else {
      return `${i} 2009`
    }
  })
  prefix(['display-flex', 'inline-flex'], {
    browsers,
    feature: 'flexbox',
    props: ['display']
  })
  prefix(['flex', 'flex-grow', 'flex-shrink', 'flex-basis'], {
    browsers,
    feature: 'flexbox'
  })
  prefix(
    [
      'flex-direction',
      'flex-wrap',
      'flex-flow',
      'justify-content',
      'order',
      'align-items',
      'align-self',
      'align-content'
    ],
    {
      browsers,
      feature: 'flexbox'
    }
  )
})

f(prefixFlexbox, { match: /y\sx/ }, browsers => {
  add(['display-flex', 'inline-flex'], {
    browsers,
    feature: 'flexbox'
  })
  add(['flex', 'flex-grow', 'flex-shrink', 'flex-basis'], {
    browsers,
    feature: 'flexbox'
  })
  add(
    [
      'flex-direction',
      'flex-wrap',
      'flex-flow',
      'justify-content',
      'order',
      'align-items',
      'align-self',
      'align-content'
    ],
    {
      browsers,
      feature: 'flexbox'
    }
  )
})

// calc() unit
let prefixCalc = require('caniuse-lite/data/features/calc')

f(prefixCalc, browsers =>
  prefix(['calc'], {
    browsers,
    feature: 'calc',
    props: ['*']
  })
)

// Background options
let prefixBackgroundOptions = require('caniuse-lite/data/features/background-img-opts')

f(prefixBackgroundOptions, browsers =>
  prefix(['background-origin', 'background-size'], {
    browsers,
    feature: 'background-img-opts'
  })
)

// background-clip: text
let prefixBackgroundClipText = require('caniuse-lite/data/features/background-clip-text')

f(prefixBackgroundClipText, browsers =>
  prefix(['background-clip'], {
    browsers,
    feature: 'background-clip-text'
  })
)

// Font feature settings
let prefixFontFeature = require('caniuse-lite/data/features/font-feature')

f(prefixFontFeature, browsers =>
  prefix(
    [
      'font-feature-settings',
      'font-variant-ligatures',
      'font-language-override'
    ],
    {
      browsers,
      feature: 'font-feature'
    }
  )
)

// CSS font-kerning property
let prefixFontKerning = require('caniuse-lite/data/features/font-kerning')

f(prefixFontKerning, browsers =>
  prefix(['font-kerning'], {
    browsers,
    feature: 'font-kerning'
  })
)

// Border image
let prefixBorderImage = require('caniuse-lite/data/features/border-image')

f(prefixBorderImage, browsers =>
  prefix(['border-image'], {
    browsers,
    feature: 'border-image'
  })
)

// Selection selector
let prefixSelection = require('caniuse-lite/data/features/css-selection')

f(prefixSelection, browsers =>
  prefix(['::selection'], {
    browsers,
    feature: 'css-selection',
    selector: true
  })
)

// Placeholder selector
let prefixPlaceholder = require('caniuse-lite/data/features/css-placeholder')

f(prefixPlaceholder, browsers => {
  prefix(['::placeholder'], {
    browsers: browsers.concat(['ie 10 old', 'ie 11 old', 'firefox 18 old']),
    feature: 'css-placeholder',
    selector: true
  })
})

// Placeholder-shown selector
let prefixPlaceholderShown = require('caniuse-lite/data/features/css-placeholder-shown')

f(prefixPlaceholderShown, browsers => {
  prefix([':placeholder-shown'], {
    browsers,
    feature: 'css-placeholder-shown',
    selector: true
  })
})

// Hyphenation
let prefixHyphens = require('caniuse-lite/data/features/css-hyphens')

f(prefixHyphens, browsers =>
  prefix(['hyphens'], {
    browsers,
    feature: 'css-hyphens'
  })
)

// Fullscreen selector
let prefixFullscreen = require('caniuse-lite/data/features/fullscreen')

f(prefixFullscreen, browsers =>
  prefix([':fullscreen'], {
    browsers,
    feature: 'fullscreen',
    selector: true
  })
)

// ::backdrop pseudo-element
// https://caniuse.com/mdn-css_selectors_backdrop
let prefixBackdrop = require('caniuse-lite/data/features/mdn-css-backdrop-pseudo-element')

f(prefixBackdrop, browsers =>
  prefix(['::backdrop'], {
    browsers,
    feature: 'backdrop',
    selector: true
  })
)

// File selector button
let prefixFileSelectorButton = require('caniuse-lite/data/features/css-file-selector-button')

f(prefixFileSelectorButton, browsers =>
  prefix(['::file-selector-button'], {
    browsers,
    feature: 'file-selector-button',
    selector: true
  })
)

// :autofill
let prefixAutofill = require('caniuse-lite/data/features/css-autofill')

f(prefixAutofill, browsers =>
  prefix([':autofill'], {
    browsers,
    feature: 'css-autofill',
    selector: true
  })
)

// Tab size
let prefixTabsize = require('caniuse-lite/data/features/css3-tabsize')

f(prefixTabsize, browsers =>
  prefix(['tab-size'], {
    browsers,
    feature: 'css3-tabsize'
  })
)

// Intrinsic & extrinsic sizing
let prefixIntrinsic = require('caniuse-lite/data/features/intrinsic-width')

let sizeProps = [
  'width',
  'min-width',
  'max-width',
  'height',
  'min-height',
  'max-height',
  'inline-size',
  'min-inline-size',
  'max-inline-size',
  'block-size',
  'min-block-size',
  'max-block-size',
  'grid',
  'grid-template',
  'grid-template-rows',
  'grid-template-columns',
  'grid-auto-columns',
  'grid-auto-rows'
]

f(prefixIntrinsic, browsers =>
  prefix(['max-content', 'min-content'], {
    browsers,
    feature: 'intrinsic-width',
    props: sizeProps
  })
)

f(prefixIntrinsic, { match: /x|\s#4/ }, browsers =>
  prefix(['fill', 'fill-available'], {
    browsers,
    feature: 'intrinsic-width',
    props: sizeProps
  })
)

f(prefixIntrinsic, { match: /x|\s#5/ }, browsers => {
  let ffFix = browsers.filter(i => {
    let [name, version] = i.split(' ')
    if (name === 'firefox' || name === 'and_ff') {
      return parseInt(version) < 94
    } else {
      return true
    }
  })
  return prefix(['fit-content'], {
    browsers: ffFix,
    feature: 'intrinsic-width',
    props: sizeProps
  })
})

// Stretch value

let prefixStretch = require('caniuse-lite/data/features/css-width-stretch')

f(prefixStretch, browsers => {
  f(prefixIntrinsic, { match: /x|\s#2/ }, firefox => {
    browsers = browsers.concat(firefox)
  })
  return prefix(['stretch'], {
    browsers,
    feature: 'css-width-stretch',
    props: sizeProps
  })
})

// Zoom cursors
let prefixCursorsNew = require('caniuse-lite/data/features/css3-cursors-newer')

f(prefixCursorsNew, browsers =>
  prefix(['zoom-in', 'zoom-out'], {
    browsers,
    feature: 'css3-cursors-newer',
    props: ['cursor']
  })
)

// Grab cursors
let prefixCursorsGrab = require('caniuse-lite/data/features/css3-cursors-grab')

f(prefixCursorsGrab, browsers =>
  prefix(['grab', 'grabbing'], {
    browsers,
    feature: 'css3-cursors-grab',
    props: ['cursor']
  })
)

// Sticky position
let prefixSticky = require('caniuse-lite/data/features/css-sticky')

f(prefixSticky, browsers =>
  prefix(['sticky'], {
    browsers,
    feature: 'css-sticky',
    props: ['position']
  })
)

// Pointer Events
let prefixPointer = require('caniuse-lite/data/features/pointer')

f(prefixPointer, browsers =>
  prefix(['touch-action'], {
    browsers,
    feature: 'pointer'
  })
)

// Text decoration
let prefixDecoration = require('caniuse-lite/data/features/text-decoration')

f(prefixDecoration, { match: /x.*#[235]/ }, browsers =>
  prefix(['text-decoration-skip', 'text-decoration-skip-ink'], {
    browsers,
    feature: 'text-decoration'
  })
)

let prefixDecorationShorthand = require('caniuse-lite/data/features/mdn-text-decoration-shorthand')

f(prefixDecorationShorthand, browsers =>
  prefix(['text-decoration'], {
    browsers,
    feature: 'text-decoration'
  })
)

let prefixDecorationColor = require('caniuse-lite/data/features/mdn-text-decoration-color')

f(prefixDecorationColor, browsers =>
  prefix(['text-decoration-color'], {
    browsers,
    feature: 'text-decoration'
  })
)

let prefixDecorationLine = require('caniuse-lite/data/features/mdn-text-decoration-line')

f(prefixDecorationLine, browsers =>
  prefix(['text-decoration-line'], {
    browsers,
    feature: 'text-decoration'
  })
)

let prefixDecorationStyle = require('caniuse-lite/data/features/mdn-text-decoration-style')

f(prefixDecorationStyle, browsers =>
  prefix(['text-decoration-style'], {
    browsers,
    feature: 'text-decoration'
  })
)

// Text Size Adjust
let prefixTextSizeAdjust = require('caniuse-lite/data/features/text-size-adjust')

f(prefixTextSizeAdjust, browsers =>
  prefix(['text-size-adjust'], {
    browsers,
    feature: 'text-size-adjust'
  })
)

// CSS Masks
let prefixCssMasks = require('caniuse-lite/data/features/css-masks')

f(prefixCssMasks, browsers => {
  prefix(
    [
      'mask-clip',
      'mask-composite',
      'mask-image',
      'mask-origin',
      'mask-repeat',
      'mask-border-repeat',
      'mask-border-source'
    ],
    {
      browsers,
      feature: 'css-masks'
    }
  )
  prefix(
    [
      'mask',
      'mask-position',
      'mask-size',
      'mask-border',
      'mask-border-outset',
      'mask-border-width',
      'mask-border-slice'
    ],
    {
      browsers,
      feature: 'css-masks'
    }
  )
})

// CSS clip-path property
let prefixClipPath = require('caniuse-lite/data/features/css-clip-path')

f(prefixClipPath, browsers =>
  prefix(['clip-path'], {
    browsers,
    feature: 'css-clip-path'
  })
)

// Fragmented Borders and Backgrounds
let prefixBoxdecoration = require('caniuse-lite/data/features/css-boxdecorationbreak')

f(prefixBoxdecoration, browsers =>
  prefix(['box-decoration-break'], {
    browsers,
    feature: 'css-boxdecorationbreak'
  })
)

// CSS3 object-fit/object-position
let prefixObjectFit = require('caniuse-lite/data/features/object-fit')

f(prefixObjectFit, browsers =>
  prefix(['object-fit', 'object-position'], {
    browsers,
    feature: 'object-fit'
  })
)

// CSS Shapes
let prefixShapes = require('caniuse-lite/data/features/css-shapes')

f(prefixShapes, browsers =>
  prefix(['shape-margin', 'shape-outside', 'shape-image-threshold'], {
    browsers,
    feature: 'css-shapes'
  })
)

// CSS3 text-overflow
let prefixTextOverflow = require('caniuse-lite/data/features/text-overflow')

f(prefixTextOverflow, browsers =>
  prefix(['text-overflow'], {
    browsers,
    feature: 'text-overflow'
  })
)

// Viewport at-rule
let prefixDeviceadaptation = require('caniuse-lite/data/features/css-deviceadaptation')

f(prefixDeviceadaptation, browsers =>
  prefix(['@viewport'], {
    browsers,
    feature: 'css-deviceadaptation'
  })
)

// Resolution Media Queries
let prefixResolut = require('caniuse-lite/data/features/css-media-resolution')

f(prefixResolut, { match: /( x($| )|a #2)/ }, browsers =>
  prefix(['@resolution'], {
    browsers,
    feature: 'css-media-resolution'
  })
)

// CSS text-align-last
let prefixTextAlignLast = require('caniuse-lite/data/features/css-text-align-last')

f(prefixTextAlignLast, browsers =>
  prefix(['text-align-last'], {
    browsers,
    feature: 'css-text-align-last'
  })
)

// Crisp Edges Image Rendering Algorithm
let prefixCrispedges = require('caniuse-lite/data/features/css-crisp-edges')

f(prefixCrispedges, { match: /y x|a x #1/ }, browsers =>
  prefix(['pixelated'], {
    browsers,
    feature: 'css-crisp-edges',
    props: ['image-rendering']
  })
)

f(prefixCrispedges, { match: /a x #2/ }, browsers =>
  prefix(['image-rendering'], {
    browsers,
    feature: 'css-crisp-edges'
  })
)

// Logical Properties
let prefixLogicalProps = require('caniuse-lite/data/features/css-logical-props')

f(prefixLogicalProps, browsers =>
  prefix(
    [
      'border-inline-start',
      'border-inline-end',
      'margin-inline-start',
      'margin-inline-end',
      'padding-inline-start',
      'padding-inline-end'
    ],
    {
      browsers,
      feature: 'css-logical-props'
    }
  )
)

f(prefixLogicalProps, { match: /x\s#2/ }, browsers =>
  prefix(
    [
      'border-block-start',
      'border-block-end',
      'margin-block-start',
      'margin-block-end',
      'padding-block-start',
      'padding-block-end'
    ],
    {
      browsers,
      feature: 'css-logical-props'
    }
  )
)

// CSS appearance
let prefixAppearance = require('caniuse-lite/data/features/css-appearance')

f(prefixAppearance, { match: /#2|x/ }, browsers =>
  prefix(['appearance'], {
    browsers,
    feature: 'css-appearance'
  })
)

// CSS Scroll snap points
let prefixSnappoints = require('caniuse-lite/data/features/css-snappoints')

f(prefixSnappoints, browsers =>
  prefix(
    [
      'scroll-snap-type',
      'scroll-snap-coordinate',
      'scroll-snap-destination',
      'scroll-snap-points-x',
      'scroll-snap-points-y'
    ],
    {
      browsers,
      feature: 'css-snappoints'
    }
  )
)

// CSS Regions
let prefixRegions = require('caniuse-lite/data/features/css-regions')

f(prefixRegions, browsers =>
  prefix(['flow-into', 'flow-from', 'region-fragment'], {
    browsers,
    feature: 'css-regions'
  })
)

// CSS image-set
let prefixImageSet = require('caniuse-lite/data/features/css-image-set')

f(prefixImageSet, browsers =>
  prefix(['image-set'], {
    browsers,
    feature: 'css-image-set',
    props: [
      'background',
      'background-image',
      'border-image',
      'cursor',
      'mask',
      'mask-image',
      'list-style',
      'list-style-image',
      'content'
    ]
  })
)

// Writing Mode
let prefixWritingMode = require('caniuse-lite/data/features/css-writing-mode')

f(prefixWritingMode, { match: /a|x/ }, browsers =>
  prefix(['writing-mode'], {
    browsers,
    feature: 'css-writing-mode'
  })
)

// Cross-Fade Function
let prefixCrossFade = require('caniuse-lite/data/features/css-cross-fade')

f(prefixCrossFade, browsers =>
  prefix(['cross-fade'], {
    browsers,
    feature: 'css-cross-fade',
    props: [
      'background',
      'background-image',
      'border-image',
      'mask',
      'list-style',
      'list-style-image',
      'content',
      'mask-image'
    ]
  })
)

// Read Only selector
let prefixReadOnly = require('caniuse-lite/data/features/css-read-only-write')

f(prefixReadOnly, browsers =>
  prefix([':read-only', ':read-write'], {
    browsers,
    feature: 'css-read-only-write',
    selector: true
  })
)

// Text Emphasize
let prefixTextEmphasis = require('caniuse-lite/data/features/text-emphasis')

f(prefixTextEmphasis, browsers =>
  prefix(
    [
      'text-emphasis',
      'text-emphasis-position',
      'text-emphasis-style',
      'text-emphasis-color'
    ],
    {
      browsers,
      feature: 'text-emphasis'
    }
  )
)

// CSS Grid Layout
let prefixGrid = require('caniuse-lite/data/features/css-grid')

f(prefixGrid, browsers => {
  prefix(['display-grid', 'inline-grid'], {
    browsers,
    feature: 'css-grid',
    props: ['display']
  })
  prefix(
    [
      'grid-template-columns',
      'grid-template-rows',
      'grid-row-start',
      'grid-column-start',
      'grid-row-end',
      'grid-column-end',
      'grid-row',
      'grid-column',
      'grid-area',
      'grid-template',
      'grid-template-areas',
      'place-self'
    ],
    {
      browsers,
      feature: 'css-grid'
    }
  )
})

f(prefixGrid, { match: /a x/ }, browsers =>
  prefix(['grid-column-align', 'grid-row-align'], {
    browsers,
    feature: 'css-grid'
  })
)

// CSS text-spacing
let prefixTextSpacing = require('caniuse-lite/data/features/css-text-spacing')

f(prefixTextSpacing, browsers =>
  prefix(['text-spacing'], {
    browsers,
    feature: 'css-text-spacing'
  })
)

// :any-link selector
let prefixAnyLink = require('caniuse-lite/data/features/css-any-link')

f(prefixAnyLink, browsers =>
  prefix([':any-link'], {
    browsers,
    feature: 'css-any-link',
    selector: true
  })
)

// unicode-bidi

let bidiIsolate = require('caniuse-lite/data/features/mdn-css-unicode-bidi-isolate')

f(bidiIsolate, browsers =>
  prefix(['isolate'], {
    browsers,
    feature: 'css-unicode-bidi',
    props: ['unicode-bidi']
  })
)

let bidiPlaintext = require('caniuse-lite/data/features/mdn-css-unicode-bidi-plaintext')

f(bidiPlaintext, browsers =>
  prefix(['plaintext'], {
    browsers,
    feature: 'css-unicode-bidi',
    props: ['unicode-bidi']
  })
)

let bidiOverride = require('caniuse-lite/data/features/mdn-css-unicode-bidi-isolate-override')

f(bidiOverride, { match: /y x/ }, browsers =>
  prefix(['isolate-override'], {
    browsers,
    feature: 'css-unicode-bidi',
    props: ['unicode-bidi']
  })
)

// overscroll-behavior selector
let prefixOverscroll = require('caniuse-lite/data/features/css-overscroll-behavior')

f(prefixOverscroll, { match: /a #1/ }, browsers =>
  prefix(['overscroll-behavior'], {
    browsers,
    feature: 'css-overscroll-behavior'
  })
)

// text-orientation
let prefixTextOrientation = require('caniuse-lite/data/features/css-text-orientation')

f(prefixTextOrientation, browsers =>
  prefix(['text-orientation'], {
    browsers,
    feature: 'css-text-orientation'
  })
)

// print-color-adjust
let prefixPrintAdjust = require('caniuse-lite/data/features/css-print-color-adjust')

f(prefixPrintAdjust, browsers =>
  prefix(['print-color-adjust', 'color-adjust'], {
    browsers,
    feature: 'css-print-color-adjust'
  })
)


================================================
FILE: eslint.config.mjs
================================================
import loguxConfig from '@logux/eslint-config'

export default [
  {
    ignores: ['coverage']
  },
  ...loguxConfig,
  {
    rules: {
      'n/prefer-node-protocol': 'off',
      'no-console': 'off'
    }
  },
  {
    files: ['bin/autoprefixer'],
    rules: {
      'n/global-require': 'off',
      'n/no-unsupported-features/es-syntax': 'off'
    }
  },
  {
    files: ['data/prefixes.js'],
    rules: {
      'import/order': 'off'
    }
  }
]


================================================
FILE: lib/at-rule.js
================================================
let Prefixer = require('./prefixer')

class AtRule extends Prefixer {
  /**
   * Clone and add prefixes for at-rule
   */
  add(rule, prefix) {
    let prefixed = prefix + rule.name

    let already = rule.parent.some(
      i => i.name === prefixed && i.params === rule.params
    )
    if (already) {
      return undefined
    }

    let cloned = this.clone(rule, { name: prefixed })
    return rule.parent.insertBefore(rule, cloned)
  }

  /**
   * Clone node with prefixes
   */
  process(node) {
    let parent = this.parentPrefix(node)

    for (let prefix of this.prefixes) {
      if (!parent || parent === prefix) {
        this.add(node, prefix)
      }
    }
  }
}

module.exports = AtRule


================================================
FILE: lib/autoprefixer.d.ts
================================================
import { Plugin } from 'postcss'
import { Stats } from 'browserslist'

declare function autoprefixer<T extends string[]>(
  ...args: [...T, autoprefixer.Options]
): Plugin & autoprefixer.ExportedAPI

declare function autoprefixer(
  browsers: string[],
  options?: autoprefixer.Options
): Plugin & autoprefixer.ExportedAPI

declare function autoprefixer(
  options?: autoprefixer.Options
): Plugin & autoprefixer.ExportedAPI

declare namespace autoprefixer {
  type GridValue = 'autoplace' | 'no-autoplace'

  interface Options {
    /** environment for `Browserslist` */
    env?: string

    /** should Autoprefixer use Visual Cascade, if CSS is uncompressed */
    cascade?: boolean

    /** should Autoprefixer add prefixes. */
    add?: boolean

    /** should Autoprefixer [remove outdated] prefixes */
    remove?: boolean

    /** should Autoprefixer add prefixes for @supports parameters. */
    supports?: boolean

    /** should Autoprefixer add prefixes for flexbox properties */
    flexbox?: boolean | 'no-2009'

    /** should Autoprefixer add IE 10-11 prefixes for Grid Layout properties */
    grid?: boolean | GridValue

    /** custom usage statistics for > 10% in my stats browsers query */
    stats?: Stats

    /**
     * list of queries for target browsers.
     * Try to not use it.
     * The best practice is to use `.browserslistrc` config or `browserslist` key in `package.json`
     * to share target browsers with Babel, ESLint and Stylelint
     */
    overrideBrowserslist?: string | string[]

    /** do not raise error on unknown browser version in `Browserslist` config. */
    ignoreUnknownVersions?: boolean
  }

  interface ExportedAPI {
    /** Autoprefixer data */
    data: {
      browsers: { [browser: string]: object | undefined }
      prefixes: { [prefixName: string]: object | undefined }
    }

    /** Autoprefixer default browsers */
    defaults: string[]

    /** Inspect with default Autoprefixer */
    info(options?: { from?: string }): string

    options: Options

    browsers: string | string[]
  }

  /** Autoprefixer data */
  let data: ExportedAPI['data']

  /** Autoprefixer default browsers */
  let defaults: ExportedAPI['defaults']

  /** Inspect with default Autoprefixer */
  let info: ExportedAPI['info']

  let postcss: true
}

declare global {
  namespace NodeJS {
    interface ProcessEnv {
      AUTOPREFIXER_GRID?: autoprefixer.GridValue
    }
  }
}

export = autoprefixer


================================================
FILE: lib/autoprefixer.js
================================================
let browserslist = require('browserslist')
let { agents } = require('caniuse-lite/dist/unpacker/agents')
let pico = require('picocolors')

let dataPrefixes = require('../data/prefixes')
let Browsers = require('./browsers')
let getInfo = require('./info')
let Prefixes = require('./prefixes')

let autoprefixerData = { browsers: agents, prefixes: dataPrefixes }

const WARNING =
  '\n' +
  '  Replace Autoprefixer `browsers` option to Browserslist config.\n' +
  '  Use `browserslist` key in `package.json` or `.browserslistrc` file.\n' +
  '\n' +
  '  Using `browsers` option can cause errors. Browserslist config can\n' +
  '  be used for Babel, Autoprefixer, postcss-normalize and other tools.\n' +
  '\n' +
  '  If you really need to use option, rename it to `overrideBrowserslist`.\n' +
  '\n' +
  '  Learn more at:\n' +
  '  https://github.com/browserslist/browserslist#readme\n' +
  '  https://twitter.com/browserslist\n' +
  '\n'

function isPlainObject(obj) {
  return Object.prototype.toString.apply(obj) === '[object Object]'
}

let cache = new Map()

function timeCapsule(result, prefixes) {
  if (prefixes.browsers.selected.length === 0) {
    return
  }
  if (prefixes.add.selectors.length > 0) {
    return
  }
  if (Object.keys(prefixes.add).length > 2) {
    return
  }
  /* c8 ignore next 11 */
  result.warn(
    'Autoprefixer target browsers do not need any prefixes.' +
      'You do not need Autoprefixer anymore.\n' +
      'Check your Browserslist config to be sure that your targets ' +
      'are set up correctly.\n' +
      '\n' +
      '  Learn more at:\n' +
      '  https://github.com/postcss/autoprefixer#readme\n' +
      '  https://github.com/browserslist/browserslist#readme\n' +
      '\n'
  )
}

module.exports = plugin

function plugin(...reqs) {
  let options
  if (reqs.length === 1 && isPlainObject(reqs[0])) {
    options = reqs[0]
    reqs = undefined
  } else if (reqs.length === 0 || (reqs.length === 1 && !reqs[0])) {
    reqs = undefined
  } else if (reqs.length <= 2 && (Array.isArray(reqs[0]) || !reqs[0])) {
    options = reqs[1]
    reqs = reqs[0]
  } else if (typeof reqs[reqs.length - 1] === 'object') {
    options = reqs.pop()
  }

  if (!options) {
    options = {}
  }

  if (options.browser) {
    throw new Error(
      'Change `browser` option to `overrideBrowserslist` in Autoprefixer'
    )
  } else if (options.browserslist) {
    throw new Error(
      'Change `browserslist` option to `overrideBrowserslist` in Autoprefixer'
    )
  }

  if (options.overrideBrowserslist) {
    reqs = options.overrideBrowserslist
  } else if (options.browsers) {
    if (typeof console !== 'undefined' && console.warn) {
      console.warn(
        pico.red(WARNING.replace(/`[^`]+`/g, i => pico.yellow(i.slice(1, -1))))
      )
    }
    reqs = options.browsers
  }

  let brwlstOpts = {
    env: options.env,
    ignoreUnknownVersions: options.ignoreUnknownVersions,
    stats: options.stats
  }

  function loadPrefixes(opts) {
    let d = autoprefixerData
    let browsers = new Browsers(d.browsers, reqs, opts, brwlstOpts)
    let key = browsers.selected.join(', ') + JSON.stringify(options)

    if (!cache.has(key)) {
      cache.set(key, new Prefixes(d.prefixes, browsers, options))
    }

    return cache.get(key)
  }

  return {
    browsers: reqs,

    info(opts) {
      opts = opts || {}
      opts.from = opts.from || process.cwd()
      return getInfo(loadPrefixes(opts))
    },

    options,

    postcssPlugin: 'autoprefixer',
    prepare(result) {
      let prefixes = loadPrefixes({
        env: options.env,
        from: result.opts.from
      })

      return {
        OnceExit(root) {
          timeCapsule(result, prefixes)
          if (options.remove !== false) {
            prefixes.processor.remove(root, result)
          }
          if (options.add !== false) {
            prefixes.processor.add(root, result)
          }
        }
      }
    }
  }
}

plugin.postcss = true

/**
 * Autoprefixer data
 */
plugin.data = autoprefixerData

/**
 * Autoprefixer default browsers
 */
plugin.defaults = browserslist.defaults

/**
 * Inspect with default Autoprefixer
 */
plugin.info = () => plugin().info()


================================================
FILE: lib/brackets.js
================================================
function last(array) {
  return array[array.length - 1]
}

let brackets = {
  /**
   * Parse string to nodes tree
   */
  parse(str) {
    let current = ['']
    let stack = [current]

    for (let sym of str) {
      if (sym === '(') {
        current = ['']
        last(stack).push(current)
        stack.push(current)
        continue
      }

      if (sym === ')') {
        stack.pop()
        current = last(stack)
        current.push('')
        continue
      }

      current[current.length - 1] += sym
    }

    return stack[0]
  },

  /**
   * Generate output string by nodes tree
   */
  stringify(ast) {
    let result = ''
    for (let i of ast) {
      if (typeof i === 'object') {
        result += `(${brackets.stringify(i)})`
        continue
      }

      result += i
    }
    return result
  }
}

module.exports = brackets


================================================
FILE: lib/browsers.js
================================================
let browserslist = require('browserslist')
let { agents } = require('caniuse-lite/dist/unpacker/agents')

let utils = require('./utils')

class Browsers {
  constructor(data, requirements, options, browserslistOpts) {
    this.data = data
    this.options = options || {}
    this.browserslistOpts = browserslistOpts || {}
    this.selected = this.parse(requirements)
  }

  /**
   * Return all prefixes for default browser data
   */
  static prefixes() {
    if (this.prefixesCache) {
      return this.prefixesCache
    }

    this.prefixesCache = []
    for (let name in agents) {
      this.prefixesCache.push(`-${agents[name].prefix}-`)
    }

    this.prefixesCache = utils
      .uniq(this.prefixesCache)
      .sort((a, b) => b.length - a.length)

    return this.prefixesCache
  }

  /**
   * Check is value contain any possible prefix
   */
  static withPrefix(value) {
    if (!this.prefixesRegexp) {
      this.prefixesRegexp = new RegExp(this.prefixes().join('|'))
    }

    return this.prefixesRegexp.test(value)
  }

  /**
   * Is browser is selected by requirements
   */
  isSelected(browser) {
    return this.selected.includes(browser)
  }

  /**
   * Return browsers selected by requirements
   */
  parse(requirements) {
    let opts = {}
    for (let i in this.browserslistOpts) {
      opts[i] = this.browserslistOpts[i]
    }
    opts.path = this.options.from
    return browserslist(requirements, opts)
  }

  /**
   * Return prefix for selected browser
   */
  prefix(browser) {
    let [name, version] = browser.split(' ')
    let data = this.data[name]

    let prefix = data.prefix_exceptions && data.prefix_exceptions[version]
    if (!prefix) {
      prefix = data.prefix
    }
    return `-${prefix}-`
  }
}

module.exports = Browsers


================================================
FILE: lib/declaration.js
================================================
let Browsers = require('./browsers')
let Prefixer = require('./prefixer')
let utils = require('./utils')

class Declaration extends Prefixer {
  /**
   * Clone and add prefixes for declaration
   */
  add(decl, prefix, prefixes, result) {
    let prefixed = this.prefixed(decl.prop, prefix)
    if (
      this.isAlready(decl, prefixed) ||
      this.otherPrefixes(decl.value, prefix)
    ) {
      return undefined
    }
    return this.insert(decl, prefix, prefixes, result)
  }

  /**
   * Calculate indentation to create visual cascade
   */
  calcBefore(prefixes, decl, prefix = '') {
    let max = this.maxPrefixed(prefixes, decl)
    let diff = max - utils.removeNote(prefix).length

    let before = decl.raw('before')
    if (diff > 0) {
      before += Array(diff).fill(' ').join('')
    }

    return before
  }

  /**
   * Always true, because we already get prefixer by property name
   */
  check(/* decl */) {
    return true
  }

  /**
   * Clone and insert new declaration
   */
  insert(decl, prefix, prefixes) {
    let cloned = this.set(this.clone(decl), prefix)
    if (!cloned) return undefined

    let already = decl.parent.some(
      i => i.prop === cloned.prop && i.value === cloned.value
    )
    if (already) {
      return undefined
    }

    if (this.needCascade(decl)) {
      cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
    }
    return decl.parent.insertBefore(decl, cloned)
  }

  /**
   * Did this declaration has this prefix above
   */
  isAlready(decl, prefixed) {
    let already = this.all.group(decl).up(i => i.prop === prefixed)
    if (!already) {
      already = this.all.group(decl).down(i => i.prop === prefixed)
    }
    return already
  }

  /**
   * Return maximum length of possible prefixed property
   */
  maxPrefixed(prefixes, decl) {
    if (decl._autoprefixerMax) {
      return decl._autoprefixerMax
    }

    let max = 0
    for (let prefix of prefixes) {
      prefix = utils.removeNote(prefix)
      if (prefix.length > max) {
        max = prefix.length
      }
    }
    decl._autoprefixerMax = max

    return decl._autoprefixerMax
  }

  /**
   * Should we use visual cascade for prefixes
   */
  needCascade(decl) {
    if (!decl._autoprefixerCascade) {
      decl._autoprefixerCascade =
        this.all.options.cascade !== false && decl.raw('before').includes('\n')
    }
    return decl._autoprefixerCascade
  }

  /**
   * Return unprefixed version of property
   */
  normalize(prop) {
    return prop
  }

  /**
   * Return list of prefixed properties to clean old prefixes
   */
  old(prop, prefix) {
    return [this.prefixed(prop, prefix)]
  }

  /**
   * Check `value`, that it contain other prefixes, rather than `prefix`
   */
  otherPrefixes(value, prefix) {
    for (let other of Browsers.prefixes()) {
      if (other === prefix) {
        continue
      }
      if (value.includes(other)) {
        return value.replace(/var\([^)]+\)/, '').includes(other)
      }
    }
    return false
  }

  /**
   * Return prefixed version of property
   */
  prefixed(prop, prefix) {
    return prefix + prop
  }

  /**
   * Add spaces for visual cascade
   */
  process(decl, result) {
    if (!this.needCascade(decl)) {
      super.process(decl, result)
      return
    }

    let prefixes = super.process(decl, result)

    if (!prefixes || !prefixes.length) {
      return
    }

    this.restoreBefore(decl)
    decl.raws.before = this.calcBefore(prefixes, decl)
  }

  /**
   * Remove visual cascade
   */
  restoreBefore(decl) {
    let lines = decl.raw('before').split('\n')
    let min = lines[lines.length - 1]

    this.all.group(decl).up(prefixed => {
      let array = prefixed.raw('before').split('\n')
      let last = array[array.length - 1]
      if (last.length < min.length) {
        min = last
      }
    })

    lines[lines.length - 1] = min
    decl.raws.before = lines.join('\n')
  }

  /**
   * Set prefix to declaration
   */
  set(decl, prefix) {
    decl.prop = this.prefixed(decl.prop, prefix)
    return decl
  }
}

module.exports = Declaration


================================================
FILE: lib/hacks/align-content.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class AlignContent extends Declaration {
  /**
   * Return property name by final spec
   */
  normalize() {
    return 'align-content'
  }

  /**
   * Change property name for 2012 spec
   */
  prefixed(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2012) {
      return prefix + 'flex-line-pack'
    }
    return super.prefixed(prop, prefix)
  }

  /**
   * Change value for 2012 spec and ignore prefix for 2009
   */
  set(decl, prefix) {
    let spec = flexSpec(prefix)[0]
    if (spec === 2012) {
      decl.value = AlignContent.oldValues[decl.value] || decl.value
      return super.set(decl, prefix)
    }
    if (spec === 'final') {
      return super.set(decl, prefix)
    }
    return undefined
  }
}

AlignContent.names = ['align-content', 'flex-line-pack']

AlignContent.oldValues = {
  'flex-end': 'end',
  'flex-start': 'start',
  'space-around': 'distribute',
  'space-between': 'justify'
}

module.exports = AlignContent


================================================
FILE: lib/hacks/align-items.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class AlignItems extends Declaration {
  /**
   * Return property name by final spec
   */
  normalize() {
    return 'align-items'
  }

  /**
   * Change property name for 2009 and 2012 specs
   */
  prefixed(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2009) {
      return prefix + 'box-align'
    }
    if (spec === 2012) {
      return prefix + 'flex-align'
    }
    return super.prefixed(prop, prefix)
  }

  /**
   * Change value for 2009 and 2012 specs
   */
  set(decl, prefix) {
    let spec = flexSpec(prefix)[0]
    if (spec === 2009 || spec === 2012) {
      decl.value = AlignItems.oldValues[decl.value] || decl.value
    }
    return super.set(decl, prefix)
  }
}

AlignItems.names = ['align-items', 'flex-align', 'box-align']

AlignItems.oldValues = {
  'flex-end': 'end',
  'flex-start': 'start'
}

module.exports = AlignItems


================================================
FILE: lib/hacks/align-self.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class AlignSelf extends Declaration {
  check(decl) {
    return (
      decl.parent &&
      !decl.parent.some(i => {
        return i.prop && i.prop.startsWith('grid-')
      })
    )
  }

  /**
   * Return property name by final spec
   */
  normalize() {
    return 'align-self'
  }

  /**
   * Change property name for 2012 specs
   */
  prefixed(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2012) {
      return prefix + 'flex-item-align'
    }
    return super.prefixed(prop, prefix)
  }

  /**
   * Change value for 2012 spec and ignore prefix for 2009
   */
  set(decl, prefix) {
    let spec = flexSpec(prefix)[0]
    if (spec === 2012) {
      decl.value = AlignSelf.oldValues[decl.value] || decl.value
      return super.set(decl, prefix)
    }
    if (spec === 'final') {
      return super.set(decl, prefix)
    }
    return undefined
  }
}

AlignSelf.names = ['align-self', 'flex-item-align']

AlignSelf.oldValues = {
  'flex-end': 'end',
  'flex-start': 'start'
}

module.exports = AlignSelf


================================================
FILE: lib/hacks/animation.js
================================================
let Declaration = require('../declaration')

class Animation extends Declaration {
  /**
   * Don’t add prefixes for modern values.
   */
  check(decl) {
    return !decl.value.split(/\s+/).some(i => {
      let lower = i.toLowerCase()
      return lower === 'reverse' || lower === 'alternate-reverse'
    })
  }
}

Animation.names = ['animation', 'animation-direction']

module.exports = Animation


================================================
FILE: lib/hacks/appearance.js
================================================
let Declaration = require('../declaration')
let utils = require('../utils')

class Appearance extends Declaration {
  constructor(name, prefixes, all) {
    super(name, prefixes, all)

    if (this.prefixes) {
      this.prefixes = utils.uniq(
        this.prefixes.map(i => {
          if (i === '-ms-') {
            return '-webkit-'
          }
          return i
        })
      )
    }
  }
}

Appearance.names = ['appearance']

module.exports = Appearance


================================================
FILE: lib/hacks/autofill.js
================================================
let Selector = require('../selector')
let utils = require('../utils')

class Autofill extends Selector {
  constructor(name, prefixes, all) {
    super(name, prefixes, all)

    if (this.prefixes) {
      this.prefixes = utils.uniq(this.prefixes.map(() => '-webkit-'))
    }
  }

  /**
   * Return different selectors depend on prefix
   */
  prefixed(prefix) {
    if (prefix === '-webkit-') {
      return ':-webkit-autofill'
    }
    return `:${prefix}autofill`
  }
}

Autofill.names = [':autofill']

module.exports = Autofill


================================================
FILE: lib/hacks/backdrop-filter.js
================================================
let Declaration = require('../declaration')
let utils = require('../utils')

class BackdropFilter extends Declaration {
  constructor(name, prefixes, all) {
    super(name, prefixes, all)

    if (this.prefixes) {
      this.prefixes = utils.uniq(
        this.prefixes.map(i => {
          return i === '-ms-' ? '-webkit-' : i
        })
      )
    }
  }
}

BackdropFilter.names = ['backdrop-filter']

module.exports = BackdropFilter


================================================
FILE: lib/hacks/background-clip.js
================================================
let Declaration = require('../declaration')
let utils = require('../utils')

class BackgroundClip extends Declaration {
  constructor(name, prefixes, all) {
    super(name, prefixes, all)

    if (this.prefixes) {
      this.prefixes = utils.uniq(
        this.prefixes.map(i => {
          return i === '-ms-' ? '-webkit-' : i
        })
      )
    }
  }

  check(decl) {
    return decl.value.toLowerCase() === 'text'
  }
}

BackgroundClip.names = ['background-clip']

module.exports = BackgroundClip


================================================
FILE: lib/hacks/background-size.js
================================================
let Declaration = require('../declaration')

class BackgroundSize extends Declaration {
  /**
   * Duplication parameter for -webkit- browsers
   */
  set(decl, prefix) {
    let value = decl.value.toLowerCase()
    if (
      prefix === '-webkit-' &&
      !value.includes(' ') &&
      value !== 'contain' &&
      value !== 'cover'
    ) {
      decl.value = decl.value + ' ' + decl.value
    }
    return super.set(decl, prefix)
  }
}

BackgroundSize.names = ['background-size']

module.exports = BackgroundSize


================================================
FILE: lib/hacks/block-logical.js
================================================
let Declaration = require('../declaration')

class BlockLogical extends Declaration {
  /**
   * Return property name by spec
   */
  normalize(prop) {
    if (prop.includes('-before')) {
      return prop.replace('-before', '-block-start')
    }
    return prop.replace('-after', '-block-end')
  }

  /**
   * Use old syntax for -moz- and -webkit-
   */
  prefixed(prop, prefix) {
    if (prop.includes('-start')) {
      return prefix + prop.replace('-block-start', '-before')
    }
    return prefix + prop.replace('-block-end', '-after')
  }
}

BlockLogical.names = [
  'border-block-start',
  'border-block-end',
  'margin-block-start',
  'margin-block-end',
  'padding-block-start',
  'padding-block-end',
  'border-before',
  'border-after',
  'margin-before',
  'margin-after',
  'padding-before',
  'padding-after'
]

module.exports = BlockLogical


================================================
FILE: lib/hacks/border-image.js
================================================
let Declaration = require('../declaration')

class BorderImage extends Declaration {
  /**
   * Remove fill parameter for prefixed declarations
   */
  set(decl, prefix) {
    decl.value = decl.value.replace(/\s+fill(\s)/, '$1')
    return super.set(decl, prefix)
  }
}

BorderImage.names = ['border-image']

module.exports = BorderImage


================================================
FILE: lib/hacks/border-radius.js
================================================
let Declaration = require('../declaration')

class BorderRadius extends Declaration {
  /**
   * Return unprefixed version of property
   */
  normalize(prop) {
    return BorderRadius.toNormal[prop] || prop
  }

  /**
   * Change syntax, when add Mozilla prefix
   */
  prefixed(prop, prefix) {
    if (prefix === '-moz-') {
      return prefix + (BorderRadius.toMozilla[prop] || prop)
    }
    return super.prefixed(prop, prefix)
  }
}

BorderRadius.names = ['border-radius']

BorderRadius.toMozilla = {}
BorderRadius.toNormal = {}

for (let ver of ['top', 'bottom']) {
  for (let hor of ['left', 'right']) {
    let normal = `border-${ver}-${hor}-radius`
    let mozilla = `border-radius-${ver}${hor}`

    BorderRadius.names.push(normal)
    BorderRadius.names.push(mozilla)

    BorderRadius.toMozilla[normal] = mozilla
    BorderRadius.toNormal[mozilla] = normal
  }
}

module.exports = BorderRadius


================================================
FILE: lib/hacks/break-props.js
================================================
let Declaration = require('../declaration')

class BreakProps extends Declaration {
  /**
   * Don’t prefix some values
   */
  insert(decl, prefix, prefixes) {
    if (decl.prop !== 'break-inside') {
      return super.insert(decl, prefix, prefixes)
    }
    if (/region/i.test(decl.value) || /page/i.test(decl.value)) {
      return undefined
    }
    return super.insert(decl, prefix, prefixes)
  }

  /**
   * Return property name by final spec
   */
  normalize(prop) {
    if (prop.includes('inside')) {
      return 'break-inside'
    }
    if (prop.includes('before')) {
      return 'break-before'
    }
    return 'break-after'
  }

  /**
   * Change name for -webkit- and -moz- prefix
   */
  prefixed(prop, prefix) {
    return `${prefix}column-${prop}`
  }

  /**
   * Change prefixed value for avoid-column and avoid-page
   */
  set(decl, prefix) {
    if (
      (decl.prop === 'break-inside' && decl.value === 'avoid-column') ||
      decl.value === 'avoid-page'
    ) {
      decl.value = 'avoid'
    }
    return super.set(decl, prefix)
  }
}

BreakProps.names = [
  'break-inside',
  'page-break-inside',
  'column-break-inside',
  'break-before',
  'page-break-before',
  'column-break-before',
  'break-after',
  'page-break-after',
  'column-break-after'
]

module.exports = BreakProps


================================================
FILE: lib/hacks/cross-fade.js
================================================
let list = require('postcss').list

let Value = require('../value')

class CrossFade extends Value {
  replace(string, prefix) {
    return list
      .space(string)
      .map(value => {
        if (value.slice(0, +this.name.length + 1) !== this.name + '(') {
          return value
        }

        let close = value.lastIndexOf(')')
        let after = value.slice(close + 1)
        let args = value.slice(this.name.length + 1, close)

        if (prefix === '-webkit-') {
          let match = args.match(/\d*.?\d+%?/)
          if (match) {
            args = args.slice(match[0].length).trim()
            args += `, ${match[0]}`
          } else {
            args += ', 0.5'
          }
        }
        return prefix + this.name + '(' + args + ')' + after
      })
      .join(' ')
  }
}

CrossFade.names = ['cross-fade']

module.exports = CrossFade


================================================
FILE: lib/hacks/display-flex.js
================================================
let OldValue = require('../old-value')
let Value = require('../value')
let flexSpec = require('./flex-spec')

class DisplayFlex extends Value {
  constructor(name, prefixes) {
    super(name, prefixes)
    if (name === 'display-flex') {
      this.name = 'flex'
    }
  }

  /**
   * Faster check for flex value
   */
  check(decl) {
    return decl.prop === 'display' && decl.value === this.name
  }

  /**
   * Change value for old specs
   */
  old(prefix) {
    let prefixed = this.prefixed(prefix)
    if (!prefixed) return undefined
    return new OldValue(this.name, prefixed)
  }

  /**
   * Return value by spec
   */
  prefixed(prefix) {
    let spec, value
    ;[spec, prefix] = flexSpec(prefix)

    if (spec === 2009) {
      if (this.name === 'flex') {
        value = 'box'
      } else {
        value = 'inline-box'
      }
    } else if (spec === 2012) {
      if (this.name === 'flex') {
        value = 'flexbox'
      } else {
        value = 'inline-flexbox'
      }
    } else if (spec === 'final') {
      value = this.name
    }

    return prefix + value
  }

  /**
   * Add prefix to value depend on flebox spec version
   */
  replace(string, prefix) {
    return this.prefixed(prefix)
  }
}

DisplayFlex.names = ['display-flex', 'inline-flex']

module.exports = DisplayFlex


================================================
FILE: lib/hacks/display-grid.js
================================================
let Value = require('../value')

class DisplayGrid extends Value {
  constructor(name, prefixes) {
    super(name, prefixes)
    if (name === 'display-grid') {
      this.name = 'grid'
    }
  }

  /**
   * Faster check for flex value
   */
  check(decl) {
    return decl.prop === 'display' && decl.value === this.name
  }
}

DisplayGrid.names = ['display-grid', 'inline-grid']

module.exports = DisplayGrid


================================================
FILE: lib/hacks/file-selector-button.js
================================================
let Selector = require('../selector')
let utils = require('../utils')

class FileSelectorButton extends Selector {
  constructor(name, prefixes, all) {
    super(name, prefixes, all)

    if (this.prefixes) {
      this.prefixes = utils.uniq(this.prefixes.map(() => '-webkit-'))
    }
  }

  /**
   * Return different selectors depend on prefix
   */
  prefixed(prefix) {
    if (prefix === '-webkit-') {
      return '::-webkit-file-upload-button'
    }
    return `::${prefix}file-selector-button`
  }
}

FileSelectorButton.names = ['::file-selector-button']

module.exports = FileSelectorButton


================================================
FILE: lib/hacks/filter-value.js
================================================
let Value = require('../value')

class FilterValue extends Value {
  constructor(name, prefixes) {
    super(name, prefixes)
    if (name === 'filter-function') {
      this.name = 'filter'
    }
  }
}

FilterValue.names = ['filter', 'filter-function']

module.exports = FilterValue


================================================
FILE: lib/hacks/filter.js
================================================
let Declaration = require('../declaration')

class Filter extends Declaration {
  /**
   * Check is it Internet Explorer filter
   */
  check(decl) {
    let v = decl.value
    return (
      !v.toLowerCase().includes('alpha(') &&
      !v.includes('DXImageTransform.Microsoft') &&
      !v.includes('data:image/svg+xml')
    )
  }
}

Filter.names = ['filter']

module.exports = Filter


================================================
FILE: lib/hacks/flex-basis.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class FlexBasis extends Declaration {
  /**
   * Return property name by final spec
   */
  normalize() {
    return 'flex-basis'
  }

  /**
   * Return flex property for 2012 spec
   */
  prefixed(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2012) {
      return prefix + 'flex-preferred-size'
    }
    return super.prefixed(prop, prefix)
  }

  /**
   * Ignore 2009 spec and use flex property for 2012
   */
  set(decl, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2012 || spec === 'final') {
      return super.set(decl, prefix)
    }
    return undefined
  }
}

FlexBasis.names = ['flex-basis', 'flex-preferred-size']

module.exports = FlexBasis


================================================
FILE: lib/hacks/flex-direction.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class FlexDirection extends Declaration {
  /**
   * Use two properties for 2009 spec
   */
  insert(decl, prefix, prefixes) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec !== 2009) {
      return super.insert(decl, prefix, prefixes)
    }
    let already = decl.parent.some(
      i =>
        i.prop === prefix + 'box-orient' || i.prop === prefix + 'box-direction'
    )
    if (already) {
      return undefined
    }

    let v = decl.value
    let dir, orient
    if (v === 'inherit' || v === 'initial' || v === 'unset') {
      orient = v
      dir = v
    } else {
      orient = v.includes('row') ? 'horizontal' : 'vertical'
      dir = v.includes('reverse') ? 'reverse' : 'normal'
    }

    let cloned = this.clone(decl)
    cloned.prop = prefix + 'box-orient'
    cloned.value = orient
    if (this.needCascade(decl)) {
      cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
    }
    decl.parent.insertBefore(decl, cloned)

    cloned = this.clone(decl)
    cloned.prop = prefix + 'box-direction'
    cloned.value = dir
    if (this.needCascade(decl)) {
      cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
    }
    return decl.parent.insertBefore(decl, cloned)
  }

  /**
   * Return property name by final spec
   */
  normalize() {
    return 'flex-direction'
  }

  /**
   * Clean two properties for 2009 spec
   */
  old(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2009) {
      return [prefix + 'box-orient', prefix + 'box-direction']
    } else {
      return super.old(prop, prefix)
    }
  }
}

FlexDirection.names = ['flex-direction', 'box-direction', 'box-orient']

module.exports = FlexDirection


================================================
FILE: lib/hacks/flex-flow.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class FlexFlow extends Declaration {
  /**
   * Use two properties for 2009 spec
   */
  insert(decl, prefix, prefixes) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec !== 2009) {
      return super.insert(decl, prefix, prefixes)
    }
    let values = decl.value
      .split(/\s+/)
      .filter(i => i !== 'wrap' && i !== 'nowrap' && 'wrap-reverse')
    if (values.length === 0) {
      return undefined
    }

    let already = decl.parent.some(
      i =>
        i.prop === prefix + 'box-orient' || i.prop === prefix + 'box-direction'
    )
    if (already) {
      return undefined
    }

    let value = values[0]
    let orient = value.includes('row') ? 'horizontal' : 'vertical'
    let dir = value.includes('reverse') ? 'reverse' : 'normal'

    let cloned = this.clone(decl)
    cloned.prop = prefix + 'box-orient'
    cloned.value = orient
    if (this.needCascade(decl)) {
      cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
    }
    decl.parent.insertBefore(decl, cloned)

    cloned = this.clone(decl)
    cloned.prop = prefix + 'box-direction'
    cloned.value = dir
    if (this.needCascade(decl)) {
      cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
    }
    return decl.parent.insertBefore(decl, cloned)
  }
}

FlexFlow.names = ['flex-flow', 'box-direction', 'box-orient']

module.exports = FlexFlow


================================================
FILE: lib/hacks/flex-grow.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class Flex extends Declaration {
  /**
   * Return property name by final spec
   */
  normalize() {
    return 'flex'
  }

  /**
   * Return flex property for 2009 and 2012 specs
   */
  prefixed(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2009) {
      return prefix + 'box-flex'
    }
    if (spec === 2012) {
      return prefix + 'flex-positive'
    }
    return super.prefixed(prop, prefix)
  }
}

Flex.names = ['flex-grow', 'flex-positive']

module.exports = Flex


================================================
FILE: lib/hacks/flex-shrink.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class FlexShrink extends Declaration {
  /**
   * Return property name by final spec
   */
  normalize() {
    return 'flex-shrink'
  }

  /**
   * Return flex property for 2012 spec
   */
  prefixed(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2012) {
      return prefix + 'flex-negative'
    }
    return super.prefixed(prop, prefix)
  }

  /**
   * Ignore 2009 spec and use flex property for 2012
   */
  set(decl, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2012 || spec === 'final') {
      return super.set(decl, prefix)
    }
    return undefined
  }
}

FlexShrink.names = ['flex-shrink', 'flex-negative']

module.exports = FlexShrink


================================================
FILE: lib/hacks/flex-spec.js
================================================
/**
 * Return flexbox spec versions by prefix
 */
module.exports = function (prefix) {
  let spec
  if (prefix === '-webkit- 2009' || prefix === '-moz-') {
    spec = 2009
  } else if (prefix === '-ms-') {
    spec = 2012
  } else if (prefix === '-webkit-') {
    spec = 'final'
  }

  if (prefix === '-webkit- 2009') {
    prefix = '-webkit-'
  }

  return [spec, prefix]
}


================================================
FILE: lib/hacks/flex-wrap.js
================================================
let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class FlexWrap extends Declaration {
  /**
   * Don't add prefix for 2009 spec
   */
  set(decl, prefix) {
    let spec = flexSpec(prefix)[0]
    if (spec !== 2009) {
      return super.set(decl, prefix)
    }
    return undefined
  }
}

FlexWrap.names = ['flex-wrap']

module.exports = FlexWrap


================================================
FILE: lib/hacks/flex.js
================================================
let list = require('postcss').list

let Declaration = require('../declaration')
let flexSpec = require('./flex-spec')

class Flex extends Declaration {
  /**
   * Return property name by final spec
   */
  normalize() {
    return 'flex'
  }

  /**
   * Change property name for 2009 spec
   */
  prefixed(prop, prefix) {
    let spec
    ;[spec, prefix] = flexSpec(prefix)
    if (spec === 2009) {
      return prefix + 'box-flex'
    }
    return super.prefixed(prop, prefix)
  }

  /**
   * Spec 2009 supports only first argument
   * Spec 2012 disallows unitless basis
   */
  set(decl, prefix) {
    let spec = flexSpec(prefix)[0]
    if (spec === 2009) {
      decl.value = list.space(decl.value)[0]
      decl.value = Flex.oldValues[decl.value] || decl.value
      return super.set(decl, prefix)
    }
    if (spec === 2012) {
      let components = list.space(decl.value)
      if (components.length === 3 && components[2] === '0') {
        decl.value = components.slice(0, 2).concat('0px').join(' ')
      }
    }
    return super.set(decl, prefix)
  }
}

Flex.names = ['flex', 'box-flex']

Flex.oldValues = {
  auto: '1',
  none: '0'
}

module.exports = Flex


================================================
FILE: lib/hacks/fullscreen.js
================================================
let Selector = require('../selector')

class Fullscreen extends Selector {
  /**
   * Return different selectors depend on prefix
   */
  prefixed(prefix) {
    if (prefix === '-webkit-') {
      return ':-webkit-full-screen'
    }
    if (prefix === '-moz-') {
      return ':-moz-full-screen'
    }
    return `:${prefix}fullscreen`
  }
}

Fullscreen.names = [':fullscreen']

module.exports = Fullscreen


================================================
FILE: lib/hacks/gradient.js
================================================
let parser = require('postcss-value-parser')

let OldValue = require('../old-value')
let utils = require('../utils')
let Value = require('../value')

let IS_DIRECTION = /top|left|right|bottom/gi

class Gradient extends Value {
  /**
   * Do not add non-webkit prefixes for list-style and object
   */
  add(decl, prefix) {
    let p = decl.prop
    if (p.includes('mask')) {
      if (prefix === '-webkit-' || prefix === '-webkit- old') {
        return super.add(decl, prefix)
      }
    } else if (
      p === 'list-style' ||
      p === 'list-style-image' ||
      p === 'content'
    ) {
      if (prefix === '-webkit-' || prefix === '-webkit- old') {
        return super.add(decl, prefix)
      }
    } else {
      return super.add(decl, prefix)
    }
    return undefined
  }

  /**
   * Get div token from exists parameters
   */
  cloneDiv(params) {
    for (let i of params) {
      if (i.type === 'div' && i.value === ',') {
        return i
      }
    }
    return { after: ' ', type: 'div', value: ',' }
  }

  /**
   * Change colors syntax to old webkit
   */
  colorStops(params) {
    let result = []
    for (let i = 0; i < params.length; i++) {
      let pos
      let param = params[i]
      let item
      if (i === 0) {
        continue
      }

      let color = parser.stringify(param[0])
      if (param[1] && param[1].type === 'word') {
        pos = param[1].value
      } else if (param[2] && param[2].type === 'word') {
        pos = param[2].value
      }

      let stop
      if (i === 1 && (!pos || pos === '0%')) {
        stop = `from(${color})`
      } else if (i === params.length - 1 && (!pos || pos === '100%')) {
        stop = `to(${color})`
      } else if (pos) {
        stop = `color-stop(${pos}, ${color})`
      } else {
        stop = `color-stop(${color})`
      }

      let div = param[param.length - 1]
      params[i] = [{ type: 'word', value: stop }]
      if (div.type === 'div' && div.value === ',') {
        item = params[i].push(div)
      }
      result.push(item)
    }
    return result
  }

  /**
   * Change new direction to old
   */
  convertDirection(params) {
    if (params.length > 0) {
      if (params[0].value === 'to') {
        this.fixDirection(params)
      } else if (params[0].value.includes('deg')) {
        this.fixAngle(params)
      } else if (this.isRadial(params)) {
        this.fixRadial(params)
      }
    }
    return params
  }

  /**
   * Add 90 degrees
   */
  fixAngle(params) {
    let first = params[0].value
    first = parseFloat(first)
    first = Math.abs(450 - first) % 360
    first = this.roundFloat(first, 3)
    params[0].value = `${first}deg`
  }

  /**
   * Replace `to top left` to `bottom right`
   */
  fixDirection(params) {
    params.splice(0, 2)

    for (let param of params) {
      if (param.type === 'div') {
        break
      }
      if (param.type === 'word') {
        param.value = this.revertDirection(param.value)
      }
    }
  }

  /**
   * Fix radial direction syntax
   */
  fixRadial(params) {
    let first = []
    let second = []
    let a, b, c, i, next

    for (i = 0; i < params.length - 2; i++) {
      a = params[i]
      b = params[i + 1]
      c = params[i + 2]
      if (a.type === 'space' && b.value === 'at' && c.type === 'space') {
        next = i + 3
        break
      } else {
        first.push(a)
      }
    }

    let div
    for (i = next; i < params.length; i++) {
      if (params[i].type === 'div') {
        div = params[i]
        break
      } else {
        second.push(params[i])
      }
    }

    params.splice(0, i, ...second, div, ...first)
  }

  /**
   * Look for at word
   */
  isRadial(params) {
    let state = 'before'
    for (let param of params) {
      if (state === 'before' && param.type === 'space') {
        state = 'at'
      } else if (state === 'at' && param.value === 'at') {
        state = 'after'
      } else if (state === 'after' && param.type === 'space') {
        return true
      } else if (param.type === 'div') {
        break
      } else {
        state = 'before'
      }
    }
    return false
  }

  /**
   * Replace old direction to new
   */
  newDirection(params) {
    if (params[0].value === 'to') {
      return params
    }
    IS_DIRECTION.lastIndex = 0 // reset search index of global regexp
    if (!IS_DIRECTION.test(params[0].value)) {
      return params
    }

    params.unshift(
      {
        type: 'word',
        value: 'to'
      },
      {
        type: 'space',
        value: ' '
      }
    )

    for (let i = 2; i < params.length; i++) {
      if (params[i].type === 'div') {
        break
      }
      if (params[i].type === 'word') {
        params[i].value = this.revertDirection(params[i].value)
      }
    }

    return params
  }

  /**
   * Normalize angle
   */
  normalize(nodes, gradientName) {
    if (!nodes[0]) return nodes

    if (/-?\d+(.\d+)?grad/.test(nodes[0].value)) {
      nodes[0].value = this.normalizeUnit(nodes[0].value, 400)
    } else if (/-?\d+(.\d+)?rad/.test(nodes[0].value)) {
      nodes[0].value = this.normalizeUnit(nodes[0].value, 2 * Math.PI)
    } else if (/-?\d+(.\d+)?turn/.test(nodes[0].value)) {
      nodes[0].value = this.normalizeUnit(nodes[0].value, 1)
    } else if (nodes[0].value.includes('deg')) {
      let num = parseFloat(nodes[0].value)
      num = (num % 360 + 360) % 360
      nodes[0].value = `${num}deg`
    }

    if (
      gradientName === 'linear-gradient' ||
      gradientName === 'repeating-linear-gradient'
    ) {
      let direction = nodes[0].value

      // Unitless zero for `<angle>` values are allowed in CSS gradients and transforms.
      // Spec: https://github.com/w3c/csswg-drafts/commit/602789171429b2231223ab1e5acf8f7f11652eb3
      if (direction === '0deg' || direction === '0') {
        nodes = this.replaceFirst(nodes, 'to', ' ', 'top')
      } else if (direction === '90deg') {
        nodes = this.replaceFirst(nodes, 'to', ' ', 'right')
      } else if (direction === '180deg') {
        nodes = this.replaceFirst(nodes, 'to', ' ', 'bottom') // default value
      } else if (direction === '270deg') {
        nodes = this.replaceFirst(nodes, 'to', ' ', 'left')
      }
    }

    return nodes
  }

  /**
   * Convert angle unit to deg
   */
  normalizeUnit(str, full) {
    let num = parseFloat(str)
    let deg = (num / full) * 360
    return `${deg}deg`
  }

  /**
   * Remove old WebKit gradient too
   */
  old(prefix) {
    if (prefix === '-webkit-') {
      let type
      if (this.name === 'linear-gradient') {
        type = 'linear'
      } else if (this.name === 'repeating-linear-gradient') {
        type = 'repeating-linear'
      } else if (this.name === 'repeating-radial-gradient') {
        type = 'repeating-radial'
      } else {
        type = 'radial'
      }
      let string = '-gradient'
      let regexp = utils.regexp(
        `-webkit-(${type}-gradient|gradient\\(\\s*${type})`,
        false
      )

      return new OldValue(this.name, prefix + this.name, string, regexp)
    } else {
      return super.old(prefix)
    }
  }

  /**
   * Change direction syntax to old webkit
   */
  oldDirection(params) {
    let div = this.cloneDiv(params[0])

    if (params[0][0].value !== 'to') {
      return params.unshift([
        { type: 'word', value: Gradient.oldDirections.bottom },
        div
      ])
    } else {
      let words = []
      for (let node of params[0].slice(2)) {
        if (node.type === 'word') {
          words.push(node.value.toLowerCase())
        }
      }

      words = words.join(' ')
      let old = Gradient.oldDirections[words] || words

      params[0] = [{ type: 'word', value: old }, div]
      return params[0]
    }
  }

  /**
   * Convert to old webkit syntax
   */
  oldWebkit(node) {
    let { nodes } = node
    let string = parser.stringify(node.nodes)

    if (this.name !== 'linear-gradient') {
      return false
    }
    if (nodes[0] && nodes[0].value.includes('deg')) {
      return false
    }
    if (
      string.includes('px') ||
      string.includes('-corner') ||
      string.includes('-side')
    ) {
      return false
    }
    if (string.includes('var(')) {
      return false
    }

    let params = [[]]
    for (let i of nodes) {
      params[params.length - 1].push(i)
      if (i.type === 'div' && i.value === ',') {
        params.push([])
      }
    }

    this.oldDirection(params)
    this.colorStops(params)

    node.nodes = []
    for (let param of params) {
      node.nodes.push(...param)
    }

    node.nodes.unshift(
      { type: 'word', value: 'linear' },
      this.cloneDiv(node.nodes)
    )
    node.value = '-webkit-gradient'

    return true
  }

  /**
   * Change degrees for webkit prefix
   */
  replace(string, prefix) {
    let ast = parser(string)
    for (let node of ast.nodes) {
      let gradientName = this.name // gradient name
      if (node.type === 'function' && node.value === gradientName) {
        node.nodes = this.newDirection(node.nodes)
        node.nodes = this.normalize(node.nodes, gradientName)
        if (prefix === '-webkit- old') {
          let changes = this.oldWebkit(node)
          if (!changes) {
            return false
          }
        } else {
          node.nodes = this.convertDirection(node.nodes)
          node.value = prefix + node.value
        }
      }
    }
    return ast.toString()
  }

  /**
   * Replace first token
   */
  replaceFirst(params, ...words) {
    let prefix = words.map(i => {
      if (i === ' ') {
        return { type: 'space', value: i }
      }
      return { type: 'word', value: i }
    })
    return prefix.concat(params.slice(1))
  }

  revertDirection(word) {
    return Gradient.directions[word.toLowerCase()] || word
  }

  /**
   * Round float and save digits under dot
   */
  roundFloat(float, digits) {
    return parseFloat(float.toFixed(digits))
  }
}

Gradient.names = [
  'linear-gradient',
  'repeating-linear-gradient',
  'radial-gradient',
  'repeating-radial-gradient'
]

Gradient.directions = {
  bottom: 'top',
  left: 'right',
  right: 'left',
  top: 'bottom' // default value
}

// Direction to replace
Gradient.oldDirections = {
  'bottom': 'left top, left bottom',
  'bottom left': 'right top, left bottom',
  'bottom right': 'left top, right bottom',
  'left': 'right top, left top',

  'left bottom': 'right top, left bottom',
  'left top': 'right bottom, left top',
  'right': 'left top, right top',
  'right bottom': 'left top, right bottom',
  'right top': 'left bottom, right top',
  'top': 'left bottom, left top',
  'top left': 'right bottom, left top',
  'top right': 'left bottom, right top'
}

module.exports = Gradient


================================================
FILE: lib/hacks/grid-area.js
================================================
let Declaration = require('../declaration')
let utils = require('./grid-utils')

class GridArea extends Declaration {
  /**
   * Translate grid-area to separate -ms- prefixed properties
   */
  insert(decl, prefix, prefixes, result) {
    if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)

    let values = utils.parse(decl)

    let [rowStart, rowSpan] = utils.translate(values, 0, 2)
    let [columnStart, columnSpan] = utils.translate(values, 1, 3)

    ;[
      ['grid-row', rowStart],
      ['grid-row-span', rowSpan],
      ['grid-column', columnStart],
      ['grid-column-span', columnSpan]
    ].forEach(([prop, value]) => {
      utils.insertDecl(decl, prop, value)
    })

    utils.warnTemplateSelectorNotFound(decl, result)
    utils.warnIfGridRowColumnExists(decl, result)

    return undefined
  }
}

GridArea.names = ['grid-area']

module.exports = GridArea


================================================
FILE: lib/hacks/grid-column-align.js
================================================
let Declaration = require('../declaration')

class GridColumnAlign extends Declaration {
  /**
   * Do not prefix flexbox values
   */
  check(decl) {
    return !decl.value.includes('flex-') && decl.value !== 'baseline'
  }

  /**
   * Change IE property back
   */
  normalize() {
    return 'justify-self'
  }

  /**
   * Change property name for IE
   */
  prefixed(prop, prefix) {
    return prefix + 'grid-column-align'
  }
}

GridColumnAlign.names = ['grid-column-align']

module.exports = GridColumnAlign


================================================
FILE: lib/hacks/grid-end.js
================================================
let Declaration = require('../declaration')
let { isPureNumber } = require('../utils')

class GridEnd extends Declaration {
  /**
   * Change repeating syntax for IE
   */
  insert(decl, prefix, prefixes, result) {
    if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)

    let clonedDecl = this.clone(decl)

    let startProp = decl.prop.replace(/end$/, 'start')
    let spanProp = prefix + decl.prop.replace(/end$/, 'span')

    if (decl.parent.some(i => i.prop === spanProp)) {
      return undefined
    }

    clonedDecl.prop = spanProp

    if (decl.value.includes('span')) {
      clonedDecl.value = decl.value.replace(/span\s/i, '')
    } else {
      let startDecl
      decl.parent.walkDecls(startProp, d => {
        startDecl = d
      })
      if (startDecl) {
        if (isPureNumber(startDecl.value)) {
          let value = Number(decl.value) - Number(startDecl.value) + ''
          clonedDecl.value = value
        } else {
          return undefined
        }
      } else {
        decl.warn(
          result,
          `Can not prefix ${decl.prop} (${startProp} is not found)`
        )
      }
    }

    decl.cloneBefore(clonedDecl)

    return undefined
  }
}

GridEnd.names = ['grid-row-end', 'grid-column-end']

module.exports = GridEnd


================================================
FILE: lib/hacks/grid-row-align.js
================================================
let Declaration = require('../declaration')

class GridRowAlign extends Declaration {
  /**
   * Do not prefix flexbox values
   */
  check(decl) {
    return !decl.value.includes('flex-') && decl.value !== 'baseline'
  }

  /**
   * Change IE property back
   */
  normalize() {
    return 'align-self'
  }

  /**
   * Change property name for IE
   */
  prefixed(prop, prefix) {
    return prefix + 'grid-row-align'
  }
}

GridRowAlign.names = ['grid-row-align']

module.exports = GridRowAlign


================================================
FILE: lib/hacks/grid-row-column.js
================================================
let Declaration = require('../declaration')
let utils = require('./grid-utils')

class GridRowColumn extends Declaration {
  /**
   * Translate grid-row / grid-column to separate -ms- prefixed properties
   */
  insert(decl, prefix, prefixes) {
    if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)

    let values = utils.parse(decl)
    let [start, span] = utils.translate(values, 0, 1)

    let hasStartValueSpan = values[0] && values[0].includes('span')

    if (hasStartValueSpan) {
      span = values[0].join('').replace(/\D/g, '')
    }

    ;[
      [decl.prop, start],
      [`${decl.prop}-span`, span]
    ].forEach(([prop, value]) => {
      utils.insertDecl(decl, prop, value)
    })

    return undefined
  }
}

GridRowColumn.names = ['grid-row', 'grid-column']

module.exports = GridRowColumn


================================================
FILE: lib/hacks/grid-rows-columns.js
================================================
let Declaration = require('../declaration')
let Processor = require('../processor')
let {
  autoplaceGridItems,
  getGridGap,
  inheritGridGap,
  prefixTrackProp,
  prefixTrackValue
} = require('./grid-utils')

class GridRowsColumns extends Declaration {
  insert(decl, prefix, prefixes, result) {
    if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)

    let { parent, prop, value } = decl
    let isRowProp = prop.includes('rows')
    let isColumnProp = prop.includes('columns')

    let hasGridTemplate = parent.some(
      i => i.prop === 'grid-template' || i.prop === 'grid-template-areas'
    )

    /**
     * Not to prefix rows declaration if grid-template(-areas) is present
     */
    if (hasGridTemplate && isRowProp) {
      return false
    }

    let processor = new Processor({ options: {} })
    let status = processor.gridStatus(parent, result)
    let gap = getGridGap(decl)
    gap = inheritGridGap(decl, gap) || gap

    let gapValue = isRowProp ? gap.row : gap.column

    if ((status === 'no-autoplace' || status === true) && !hasGridTemplate) {
      gapValue = null
    }

    let prefixValue = prefixTrackValue({
      gap: gapValue,
      value
    })

    /**
     * Insert prefixes
     */
    decl.cloneBefore({
      prop: prefixTrackProp({ prefix, prop }),
      value: prefixValue
    })

    let autoflow = parent.nodes.find(i => i.prop === 'grid-auto-flow')
    let autoflowValue = 'row'

    if (autoflow && !processor.disabled(autoflow, result)) {
      autoflowValue = autoflow.value.trim()
    }
    if (status === 'autoplace') {
      /**
       * Show warning if grid-template-rows decl is not found
       */
      let rowDecl = parent.nodes.find(i => i.prop === 'grid-template-rows')

      if (!rowDecl && hasGridTemplate) {
        return undefined
      } else if (!rowDecl && !hasGridTemplate) {
        decl.warn(
          result,
          'Autoplacement does not work without grid-template-rows property'
        )
        return undefined
      }

      /**
       * Show warning if grid-template-columns decl is not found
       */
      let columnDecl = parent.nodes.find(i => {
        return i.prop === 'grid-template-columns'
      })
      if (!columnDecl && !hasGridTemplate) {
        decl.warn(
          result,
          'Autoplacement does not work without grid-template-columns property'
        )
      }

      /**
       * Autoplace grid items
       */
      if (isColumnProp && !hasGridTemplate) {
        autoplaceGridItems(decl, result, gap, autoflowValue)
      }
    }

    return undefined
  }

  /**
   * Change IE property back
   */
  normalize(prop) {
    return prop.replace(/^grid-(rows|columns)/, 'grid-template-$1')
  }

  /**
   * Change property name for IE
   */
  prefixed(prop, prefix) {
    if (prefix === '-ms-') {
      return prefixTrackProp({ prefix, prop })
    }
    return super.prefixed(prop, prefix)
  }
}

GridRowsColumns.names = [
  'grid-template-rows',
  'grid-template-columns',
  'grid-rows',
  'grid-columns'
]

module.exports = GridRowsColumns


================================================
FILE: lib/hacks/grid-start.js
================================================
let Declaration = require('../declaration')

class GridStart extends Declaration {
  /**
   * Do not add prefix for unsupported value in IE
   */
  check(decl) {
    let value = decl.value
    return !value.includes('/') && !value.includes('span')
  }

  /**
   * Return a final spec property
   */
  normalize(prop) {
    return prop.replace('-start', '')
  }

  /**
   * Change property name for IE
   */
  prefixed(prop, prefix) {
    let result = super.prefixed(prop, prefix)
    if (prefix === '-ms-') {
      result = result.replace('-start', '')
    }
    return result
  }
}

GridStart.names = ['grid-row-start', 'grid-column-start']

module.exports = GridStart


================================================
FILE: lib/hacks/grid-template-areas.js
================================================
let Declaration = require('../declaration')
let {
  getGridGap,
  inheritGridGap,
  parseGridAreas,
  prefixTrackProp,
  prefixTrackValue,
  warnGridGap,
  warnMissedAreas
} = require('./grid-utils')

function getGridRows(tpl) {
  return tpl
    .trim()
    .slice(1, -1)
    .split(/["']\s*["']?/g)
}

class GridTemplateAreas extends Declaration {
  /**
   * Translate grid-template-areas to separate -ms- prefixed properties
   */
  insert(decl, prefix, prefixes, result) {
    if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)

    let hasColumns = false
    let hasRows = false
    let parent = decl.parent
    let gap = getGridGap(decl)
    gap = inheritGridGap(decl, gap) || gap

    // remove already prefixed rows
    // to prevent doubling prefixes
    parent.walkDecls(/-ms-grid-rows/, i => i.remove())

    // add empty tracks to rows
    parent.walkDecls(/grid-template-(rows|columns)/, trackDecl => {
      if (trackDecl.prop === 'grid-template-rows') {
        hasRows = true
        let { prop, value } = trackDecl
        trackDecl.cloneBefore({
          prop: prefixTrackProp({ prefix, prop }),
          value: prefixTrackValue({ gap: gap.row, value })
        })
      } else {
        hasColumns = true
      }
    })

    let gridRows = getGridRows(decl.value)

    if (hasColumns && !hasRows && gap.row && gridRows.length > 1) {
      decl.cloneBefore({
        prop: '-ms-grid-rows',
        raws: {},
        value: prefixTrackValue({
          gap: gap.row,
          value: `repeat(${gridRows.length}, auto)`
        })
      })
    }

    // warnings
    warnGridGap({
      decl,
      gap,
      hasColumns,
      result
    })

    let areas = parseGridAreas({
      gap,
      rows: gridRows
    })

    warnMissedAreas(areas, decl, result)

    return decl
  }
}

GridTemplateAreas.names = ['grid-template-areas']

module.exports = GridTemplateAreas


================================================
FILE: lib/hacks/grid-template.js
================================================
let Declaration = require('../declaration')
let {
  getGridGap,
  inheritGridGap,
  parseTemplate,
  warnGridGap,
  warnMissedAreas
} = require('./grid-utils')

class GridTemplate extends Declaration {
  /**
   * Translate grid-template to separate -ms- prefixed properties
   */
  insert(decl, prefix, prefixes, result) {
    if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)

    if (decl.parent.some(i => i.prop === '-ms-grid-rows')) {
      return undefined
    }

    let gap = getGridGap(decl)

    /**
     * we must insert inherited gap values in some cases:
     * if we are inside media query && if we have no grid-gap value
     */
    let inheritedGap = inheritGridGap(decl, gap)

    let { areas, columns, rows } = parseTemplate({
      decl,
      gap: inheritedGap || gap
    })

    let hasAreas = Object.keys(areas).length > 0
    let hasRows = Boolean(rows)
    let hasColumns = Boolean(columns)

    warnGridGap({
      decl,
      gap,
      hasColumns,
      result
    })

    warnMissedAreas(areas, decl, result)

    if ((hasRows && hasColumns) || hasAreas) {
      decl.cloneBefore({
        prop: '-ms-grid-rows',
        raws: {},
        value: rows
      })
    }

    if (hasColumns) {
      decl.cloneBefore({
        prop: '-ms-grid-columns',
        raws: {},
        value: columns
      })
    }

    return decl
  }
}

GridTemplate.names = ['grid-template']

module.exports = GridTemplate


================================================
FILE: lib/hacks/grid-utils.js
================================================
let parser = require('postcss-value-parser')
let list = require('postcss').list

let uniq = require('../utils').uniq
let escapeRegexp = require('../utils').escapeRegexp
let splitSelector = require('../utils').splitSelector

function convert(value) {
  if (
    value &&
    value.length === 2 &&
    value[0] === 'span' &&
    parseInt(value[1], 10) > 0
  ) {
    return [false, parseInt(value[1], 10)]
  }

  if (value && value.length === 1 && parseInt(value[0], 10) > 0) {
    return [parseInt(value[0], 10), false]
  }

  return [false, false]
}

exports.translate = translate

function translate(values, startIndex, endIndex) {
  let startValue = values[startIndex]
  let endValue = values[endIndex]

  if (!startValue) {
    return [false, false]
  }

  let [start, spanStart] = convert(startValue)
  let [end, spanEnd] = convert(endValue)

  if (start && !endValue) {
    return [start, false]
  }

  if (spanStart && end) {
    return [end - spanStart, spanStart]
  }

  if (start && spanEnd) {
    return [start, spanEnd]
  }

  if (start && end) {
    return [start, end - start]
  }

  return [false, false]
}

exports.parse = parse

function parse(decl) {
  let node = parser(decl.value)

  let values = []
  let current = 0
  values[current] = []

  for (let i of node.nodes) {
    if (i.type === 'div') {
      current += 1
      values[current] = []
    } else if (i.type === 'word') {
      values[current].push(i.value)
    }
  }

  return values
}

exports.insertDecl = insertDecl

function insertDecl(decl, prop, value) {
  if (value && !decl.parent.some(i => i.prop === `-ms-${prop}`)) {
    decl.cloneBefore({
      prop: `-ms-${prop}`,
      value: value.toString()
    })
  }
}

// Track transforms

exports.prefixTrackProp = prefixTrackProp

function prefixTrackProp({ prefix, prop }) {
  return prefix + prop.replace('template-', '')
}

function transformRepeat({ nodes }, { gap }) {
  let { count, size } = nodes.reduce(
    (result, node) => {
      if (node.type === 'div' && node.value === ',') {
        result.key = 'size'
      } else {
        result[result.key].push(parser.stringify(node))
      }
      return result
    },
    {
      count: [],
      key: 'count',
      size: []
    }
  )

  // insert gap values
  if (gap) {
    size = size.filter(i => i.trim())
    let val = []
    for (let i = 1; i <= count; i++) {
      size.forEach((item, index) => {
        if (index > 0 || i > 1) {
          val.push(gap)
        }
        val.push(item)
      })
    }

    return val.join(' ')
  }

  return `(${size.join('')})[${count.join('')}]`
}

exports.prefixTrackValue = prefixTrackValue

function prefixTrackValue({ gap, value }) {
  let result = parser(value).nodes.reduce((nodes, node) => {
    if (node.type === 'function' && node.value === 'repeat') {
      nodes.push({
        type: 'word',
        value: transformRepeat(node, { gap })
      })
      return nodes
    }
    if (gap && node.type === 'space') {
      nodes.push(
        {
          type: 'space',
          value: ' '
        },
        {
          type: 'word',
          value: gap
        },
        node
      )
      return nodes
    }
    nodes.push(node)
    return nodes
  }, [])

  return parser.stringify(result)
}

// Parse grid-template-areas

let DOTS = /^\.+$/

function track(start, end) {
  return { end, span: end - start, start }
}

function getColumns(line) {
  return line.trim().split(/\s+/g)
}

exports.parseGridAreas = parseGridAreas

function parseGridAreas({ gap, rows }) {
  return rows.reduce((areas, line, rowIndex) => {
    if (gap.row) rowIndex *= 2

    if (line.trim() === '') return areas

    getColumns(line).forEach((area, columnIndex) => {
      if (DOTS.test(area)) return

      if (gap.column) columnIndex *= 2

      if (typeof areas[area] === 'undefined') {
        areas[area] = {
          column: track(columnIndex + 1, columnIndex + 2),
          row: track(rowIndex + 1, rowIndex + 2)
        }
      } else {
        let { column, row } = areas[area]

        column.start = Math.min(column.start, columnIndex + 1)
        column.end = Math.max(column.end, columnIndex + 2)
        column.span = column.end - column.start

        row.start = Math.min(row.start, rowIndex + 1)
        row.end = Math.max(row.end, rowIndex + 2)
        row.span = row.end - row.start
      }
    })

    return areas
  }, {})
}

// Parse grid-template

function testTrack(node) {
  return node.type === 'word' && /^\[.+]$/.test(node.value)
}

function verifyRowSize(result) {
  if (result.areas.length > result.rows.length) {
    result.rows.push('auto')
  }
  return result
}

exports.parseTemplate = parseTemplate

function parseTemplate({ decl, gap }) {
  let gridTemplate = parser(decl.value).nodes.reduce(
    (result, node) => {
      let { type, value } = node

      if (testTrack(node) || type === 'space') return result

      // area
      if (type === 'string') {
        result = verifyRowSize(result)
        result.areas.push(value)
      }

      // values and function
      if (type === 'word' || type === 'function') {
        result[result.key].push(parser.stringify(node))
      }

      // divider(/)
      if (type === 'div' && value === '/') {
        result.key = 'columns'
        result = verifyRowSize(result)
      }

      return result
    },
    {
      areas: [],
      columns: [],
      key: 'rows',
      rows: []
    }
  )

  return {
    areas: parseGridAreas({
      gap,
      rows: gridTemplate.areas
    }),
    columns: prefixTrackValue({
      gap: gap.column,
      value: gridTemplate.columns.join(' ')
    }),
    rows: prefixTrackValue({
      gap: gap.row,
      value: gridTemplate.rows.join(' ')
    })
  }
}

// Insert parsed grid areas

/**
 * Get an array of -ms- prefixed props and values
 * @param  {Object} [area] area object with column and row data
 * @param  {Boolean} [addRowSpan] should we add grid-column-row value?
 * @param  {Boolean} [addColumnSpan] should we add grid-column-span value?
 * @return {Array<Object>}
 */
function getMSDecls(area, addRowSpan = false, addColumnSpan = false) {
  let result = [
    {
      prop: '-ms-grid-row',
      value: String(area.row.start)
    }
  ]
  if (area.row.span > 1 || addRowSpan) {
    result.push({
      prop: '-ms-grid-row-span',
      value: String(area.row.span)
    })
  }
  result.push({
    prop: '-ms-grid-column',
    value: String(area.column.start)
  })
  if (area.column.span > 1 || addColumnSpan) {
    result.push({
      prop: '-ms-grid-column-span',
      value: String(area.column.span)
    })
  }
  return result
}

function getParentMedia(parent) {
  if (parent.type === 'atrule' && parent.name === 'media') {
    return parent
  }
  if (!parent.parent) {
    return false
  }
  return getParentMedia(parent.parent)
}

/**
 * change selectors for rules with duplicate grid-areas.
 * @param  {Array<Rule>} rules
 * @param  {Array<String>} templateSelectors
 * @return {Array<Rule>} rules with changed selectors
 */
function changeDuplicateAreaSelectors(ruleSelectors, templateSelectors) {
  ruleSelectors = ruleSelectors.map(selector => {
    let selectorBySpace = list.space(selector)
    let selectorByComma = list.comma(selector)

    if (selectorBySpace.length > selectorByComma.length) {
      selector = selectorBySpace.slice(-1).join('')
    }
    return selector
  })

  return ruleSelectors.map(ruleSelector => {
    let newSelector = templateSelectors.map((tplSelector, index) => {
      let space = index === 0 ? '' : ' '
      return `${space}${tplSelector} > ${ruleSelector}`
    })

    return newSelector
  })
}

/**
 * check if selector of rules are equal
 * @param  {Rule} ruleA
 * @param  {Rule} ruleB
 * @return {Boolean}
 */
function selectorsEqual(ruleA, ruleB) {
  return ruleA.selectors.some(sel => {
    return ruleB.selectors.includes(sel)
  })
}

/**
 * Parse data from all grid-template(-areas) declarations
 * @param  {Root} css css root
 * @return {Object} parsed data
 */
function parseGridTemplatesData(css) {
  let parsed = []

  // we walk through every grid-template(-areas) declaration and store
  // data with the same area names inside the item
  css.walkDecls(/grid-template(-areas)?$/, d => {
    let rule = d.parent
    let media = getParentMedia(rule)
    let gap = getGridGap(d)
    let inheritedGap = inheritGridGap(d, gap)
    let { areas } = parseTemplate({ decl: d, gap: inheritedGap || gap })
    let areaNames = Object.keys(areas)

    // skip node if it doesn't have areas
    if (areaNames.length === 0) {
      return true
    }

    // check parsed array for item that include the same area names
    // return index of that item
    let index = parsed.reduce((acc, { allAreas }, idx) => {
      let hasAreas = allAreas && areaNames.some(area => allAreas.includes(area))
      return hasAreas ? idx : acc
    }, null)

    if (index !== null) {
      // index is found, add the grid-template data to that item
      let { allAreas, rules } = parsed[index]

      // check if rule has no duplicate area names
      let hasNoDuplicates = rules.some(r => {
        return r.hasDuplicates === false && selectorsEqual(r, rule)
      })

      let duplicatesFound = false

      // check need to gather all duplicate area names
      let duplicateAreaNames = rules.reduce((acc, r) => {
        if (!r.params && selectorsEqual(r, rule)) {
          duplicatesFound = true
          return r.duplicateAreaNames
        }
        if (!duplicatesFound) {
          areaNames.forEach(name => {
            if (r.areas[name]) {
              acc.push(name)
            }
          })
        }
        return uniq(acc)
      }, [])

      // update grid-row/column-span values for areas with duplicate
      // area names. @see #1084 and #1146
      rules.forEach(r => {
        areaNames.forEach(name => {
          let area = r.areas[name]
          if (area && area.row.span !== areas[name].row.span) {
            areas[name].row.updateSpan = true
          }

          if (area && area.column.span !== areas[name].column.span) {
            areas[name].column.updateSpan = true
          }
        })
      })

      parsed[index].allAreas = uniq([...allAreas, ...areaNames])
      parsed[index].rules.push({
        areas,
        duplicateAreaNames,
        hasDuplicates: !hasNoDuplicates,
        node: rule,
        params: media.params,
        selectors: rule.selectors
      })
    } else {
      // index is NOT found, push the new item to the parsed array
      parsed.push({
        allAreas: areaNames,
        areasCount: 0,
        rules: [
          {
            areas,
            duplicateAreaNames: [],
            duplicateRules: [],
            hasDuplicates: false,
            node: rule,
            params: media.params,
            selectors: rule.selectors
          }
        ]
      })
    }

    return undefined
  })

  return parsed
}

/**
 * insert prefixed grid-area declarations
 * @param  {Root}  css css root
 * @param  {Function} isDisabled check if the rule is disabled
 * @return {void}
 */
exports.insertAreas = insertAreas

function insertAreas(css, isDisabled) {
  // parse grid-template declarations
  let gridTemplatesData = parseGridTemplatesData(css)

  // return undefined if no declarations found
  if (gridTemplatesData.length === 0) {
    return undefined
  }

  // we need to store the rules that we will insert later
  let rulesToInsert = {}

  css.walkDecls('grid-area', gridArea => {
    let gridAreaRule = gridArea.parent
    let hasPrefixedRow = gridAreaRule.first.prop === '-ms-grid-row'
    let gridAreaMedia = getParentMedia(gridAreaRule)

    if (isDisabled(gridArea)) {
      return undefined
    }

    let gridAreaRuleIndex = css.index(gridAreaMedia || gridAreaRule)

    let value = gridArea.value
    // found the data that matches grid-area identifier
    let data = gridTemplatesData.filter(d => d.allAreas.includes(value))[0]

    if (!data) {
      return true
    }

    let lastArea = data.allAreas[data.allAreas.length - 1]
    let selectorBySpace = list.space(gridAreaRule.selector)
    let selectorByComma = list.comma(gridAreaRule.selector)
    let selectorIsComplex =
      selectorBySpace.length > 1 &&
      selectorBySpace.length > selectorByComma.length

    // prevent doubling of prefixes
    if (hasPrefixedRow) {
      return false
    }

    // create the empty object with the key as the last area name
    // e.g if we have templates with "a b c" values, "c" will be the last area
    if (!rulesToInsert[lastArea]) {
      rulesToInsert[lastArea] = {}
    }

    let lastRuleIsSet = false

    // walk through every grid-template rule data
    for (let rule of data.rules) {
      let area = rule.areas[value]
      let hasDuplicateName = rule.duplicateAreaNames.includes(value)

      // if we can't find the area name, update lastRule and continue
      if (!area) {
        let lastRule = rulesToInsert[lastArea].lastRule
        let lastRuleIndex
        if (lastRule) {
          lastRuleIndex = css.index(lastRule)
        } else {
          /* c8 ignore next 2 */
          lastRuleIndex = -1
        }

        if (gridAreaRuleIndex > lastRuleIndex) {
          rulesToInsert[lastArea].lastRule = gridAreaMedia || gridAreaRule
        }
        continue
      }

      // for grid-templates inside media rule we need to create empty
      // array to push prefixed grid-area rules later
      if (rule.params && !rulesToInsert[lastArea][rule.params]) {
        rulesToInsert[lastArea][rule.params] = []
      }

      if ((!rule.hasDuplicates || !hasDuplicateName) && !rule.params) {
        // grid-template has no duplicates and not inside media rule

        getMSDecls(area, false, false)
          .reverse()
          .forEach(i =>
            gridAreaRule.prepend(
              Object.assign(i, {
                raws: {
                  between: gridArea.raws.between
                }
              })
            )
          )

        rulesToInsert[lastArea].lastRule = gridAreaRule
        lastRuleIsSet = true
      } else if (rule.hasDuplicates && !rule.params && !selectorIsComplex) {
        // grid-template has duplicates and not inside media rule
        let cloned = gridAreaRule.clone()
        cloned.removeAll()

        getMSDecls(area, area.row.updateSpan, area.column.updateSpan)
          .reverse()
          .forEach(i =>
            cloned.prepend(
              Object.assign(i, {
                raws: {
                  between: gridArea.raws.between
                }
              })
            )
          )

        cloned.selectors = changeDuplicateAreaSelectors(
          cloned.selectors,
          rule.selectors
        )

        if (rulesToInsert[lastArea].lastRule) {
          rulesToInsert[lastArea].lastRule.after(cloned)
        }
        rulesToInsert[lastArea].lastRule = cloned
        lastRuleIsSet = true
      } else if (
        rule.hasDuplicates &&
        !rule.params &&
        selectorIsComplex &&
        gridAreaRule.selector.includes(rule.selectors[0])
      ) {
        // grid-template has duplicates and not inside media rule
        // and the selector is complex
        gridAreaRule.walkDecls(/-ms-grid-(row|column)/, d => d.remove())
        getMSDecls(area, area.row.updateSpan, area.column.updateSpan)
          .reverse()
          .forEach(i =>
            gridAreaRule.prepend(
              Object.assign(i, {
                raws: {
                  between: gridArea.raws.between
                }
              })
            )
          )
      } else if (rule.params) {
        // grid-template is inside media rule
        // if we're inside media rule, we need to store prefixed rules
        // inside rulesToInsert object to be able to preserve the order of media
        // rules and merge them easily
        let cloned = gridAreaRule.clone()
        cloned.removeAll()

        getMSDecls(area, area.row.updateSpan, area.column.updateSpan)
          .reverse()
          .forEach(i =>
            cloned.prepend(
              Object.assign(i, {
                raws: {
                  between: gridArea.raws.between
                }
              })
            )
          )

        if (rule.hasDuplicates && hasDuplicateName) {
          cloned.selectors = changeDuplicateAreaSelectors(
            cloned.selectors,
            rule.selectors
          )
        }

        cloned.raws = rule.node.raws

        if (css.index(rule.node.parent) > gridAreaRuleIndex) {
          // append the prefixed rules right inside media rule
          // with grid-template
          rule.node.parent.append(cloned)
        } else {
          // store the rule to insert later
          rulesToInsert[lastArea][rule.params].push(cloned)
        }

        // set new rule as last rule ONLY if we didn't set lastRule for
        // this grid-area before
        if (!lastRuleIsSet) {
          rulesToInsert[lastArea].lastRule = gridAreaMedia || gridAreaRule
        }
      }
    }

    return undefined
  })

  // append stored rules inside the media rules
  Object.keys(rulesToInsert).forEach(area => {
    let data = rulesToInsert[area]
    let lastRule = data.lastRule
    Object.keys(data)
      .reverse()
      .filter(p => p !== 'lastRule')
      .forEach(params => {
        if (data[params].length > 0 && lastRule) {
          lastRule.after({ name: 'media', params })
          lastRule.next().append(data[params])
        }
      })
  })

  return undefined
}

/**
 * Warn user if grid area identifiers are not found
 * @param  {Object} areas
 * @param  {Declaration} decl
 * @param  {Result} result
 * @return {void}
 */
exports.warnMissedAreas = warnMissedAreas

function warnMissedAreas(areas, decl, result) {
  let missed = Object.keys(areas)

  decl.root().walkDecls('grid-area', gridArea => {
    missed = missed.filter(e => e !== gridArea.value)
  })

  if (missed.length > 0) {
    decl.warn(result, 'Can not find grid areas: ' + missed.join(', '))
  }

  return undefined
}

/**
 * compare selectors with grid-area rule and grid-template rule
 * show warning if grid-template selector is not found
 * (this function used for grid-area rule)
 * @param  {Declaration} decl
 * @param  {Result} result
 * @return {void}
 */
exports.warnTemplateSelectorNotFound = warnTemplateSelectorNotFound

function warnTemplateSelectorNotFound(decl, result) {
  let rule = decl.parent
  let root = decl.root()
  let duplicatesFound = false

  // slice selector array. Remove the last part (for comparison)
  let slicedSelectorArr = list
    .space(rule.selector)
    .filter(str => str !== '>')
    .slice(0, -1)

  // we need to compare only if selector is complex.
  // e.g '.grid-cell' is simple, but '.parent > .grid-cell' is complex
  if (slicedSelectorArr.length > 0) {
    let gridTemplateFound = false
    let foundAreaSelector = null

    root.walkDecls(/grid-template(-areas)?$/, d => {
      let parent = d.parent
      let templateSelectors = parent.selectors

      let { areas } = parseTemplate({ decl: d, gap: getGridGap(d) })
      let hasArea = areas[decl.value]

      // find the the matching selectors
      for (let tplSelector of templateSelectors) {
        if (gridTemplateFound) {
          break
        }
        let tplSelectorArr = list.space(tplSelector).filter(str => str !== '>')

        gridTemplateFound = tplSelectorArr.every(
          (item, idx) => item === slicedSelectorArr[idx]
        )
      }

      if (gridTemplateFound || !hasArea) {
        return true
      }

      if (!foundAreaSelector) {
        foundAreaSelector = parent.selector
      }

      // if we found the duplicate area with different selector
      if (foundAreaSelector && foundAreaSelector !== parent.selector) {
        duplicatesFound = true
      }

      return undefined
    })

    // warn user if we didn't find template
    if (!gridTemplateFound && duplicatesFound) {
      decl.warn(
        result,
        'Autoprefixer cannot find a grid-template ' +
          `containing the duplicate grid-area "${decl.value}" ` +
          `with full selector matching: ${slicedSelectorArr.join(' ')}`
      )
    }
  }
}

/**
 * warn user if both grid-area and grid-(row|column)
 * declarations are present in the same rule
 * @param  {Declaration} decl
 * @param  {Result} result
 * @return {void}
 */
exports.warnIfGridRowColumnExists = warnIfGridRowColumnExists

function warnIfGridRowColumnExists(decl, result) {
  let rule = decl.parent
  let decls = []
  rule.walkDecls(/^grid-(row|column)/, d => {
    if (
      !d.prop.endsWith('-end') &&
      !d.value.startsWith('span') &&
      !d.prop.endsWith('-gap')
    ) {
      decls.push(d)
    }
  })
  if (decls.length > 0) {
    decls.forEach(d => {
      d.warn(
        result,
        'You already have a grid-area declaration present in the rule. ' +
          `You should use either grid-area or ${d.prop}, not both`
      )
    })
  }

  return undefined
}

// Gap utils

exports.getGridGap = getGridGap

function getGridGap(decl) {
  let gap = {}

  // try to find gap
  let testGap = /^(grid-)?((row|column)-)?gap$/
  decl.parent.walkDecls(testGap, ({ prop, value }) => {
    if (/^(grid-)?gap$/.test(prop)) {
      let [row, , column] = parser(value).nodes

      gap.row = row && parser.stringify(row)
      gap.column = column ? parser.stringify(column) : gap.row
    }
    if (/^(grid-)?row-gap$/.test(prop)) gap.row = value
    if (/^(grid-)?column-gap$/.test(prop)) gap.column = value
  })

  return gap
}

/**
 * parse media parameters (for example 'min-width: 500px')
 * @param  {String} params parameter to parse
 * @return {}
 */
function parseMediaParams(params) {
  if (!params) {
    return []
  }
  let parsed = parser(params)
  let prop
  let value

  parsed.walk(node => {
    if (node.type === 'word' && /min|max/g.test(node.value)) {
      prop = node.value
    } else if (node.value.includes('px')) {
      value = parseInt(node.value.replace(/\D/g, ''))
    }
  })

  return [prop, value]
}

/**
 * Compare the selectors and decide if we
 * need to inherit gap from compared selector or not.
 * @type {String} selA
 * @type {String} selB
 * @return {Boolean}
 */
function shouldInheritGap(selA, selB) {
  let result

  // get arrays of selector split in 3-deep array
  let splitSelectorArrA = splitSelector(selA)
  let splitSelectorArrB = splitSelector(selB)

  if (splitSelectorArrA[0].length < splitSelectorArrB[0].length) {
    // abort if selectorA has lower descendant specificity then selectorB
    // (e.g '.grid' and '.hello .world .grid')
    return false
  } else if (splitSelectorArrA[0].length > splitSelectorArrB[0].length) {
    // if selectorA has higher descendant specificity then selectorB
    // (e.g '.foo .bar .grid' and '.grid')

    let idx = splitSelectorArrA[0].reduce((res, [item], index) => {
      let firstSelectorPart = splitSelectorArrB[0][0][0]
      if (item === firstSelectorPart) {
        return index
      }
      return false
    }, false)

    if (idx) {
      result = splitSelectorArrB[0].every((arr, index) => {
        return arr.every(
          (part, innerIndex) =>
            // because selectorA has more space elements, we need to slice
            // selectorA array by 'idx' number to compare them
            splitSelectorArrA[0].slice(idx)[index][innerIndex] === part
        )
      })
    }
  } else {
    // if selectorA has the same descendant specificity as selectorB
    // this condition covers cases such as: '.grid.foo.bar' and '.grid'
    result = splitSelectorArrB.some(byCommaArr => {
      return byCommaArr.every((bySpaceArr, index) => {
        return bySpaceArr.every(
          (part, innerIndex) => splitSelectorArrA[0][index][innerIndex] === part
        )
      })
    })
  }

  return result
}
/**
 * inherit grid gap values from the closest rule above
 * with the same selector
 * @param  {Declaration} decl
 * @param  {Object} gap gap values
 * @return {Object | Boolean} return gap values or false (if not found)
 */
exports.inheritGridGap = inheritGridGap

function inheritGridGap(decl, gap) {
  let rule = decl.parent
  let mediaRule = getParentMedia(rule)
  let root = rule.root()

  // get an array of selector split in 3-deep array
  let splitSelectorArr = splitSelector(rule.selector)

  // abort if the rule already has gaps
  if (Object.keys(gap).length > 0) {
    return false
  }

  // e.g ['min-width']
  let [prop] = parseMediaParams(mediaRule.params)

  let lastBySpace = splitSelectorArr[0]

  // get escaped value from the selector
  // if we have '.grid-2.foo.bar' selector, will be '\.grid\-2'
  let escaped = escapeRegexp(lastBySpace[lastBySpace.length - 1][0])

  let regexp = new RegExp(`(${escaped}$)|(${escaped}[,.])`)

  // find the closest rule with the same selector
  let closestRuleGap
  root.walkRules(regexp, r => {
    let gridGap

    // abort if are checking the same rule
    if (rule.toString() === r.toString()) {
      return false
    }

    // find grid-gap values
    r.walkDecls('grid-gap', d => (gridGap = getGridGap(d)))

    // skip rule without gaps
    if (!gridGap || Object.keys(gridGap).length === 0) {
      return true
    }

    // skip rules that should not be inherited from
    if (!shouldInheritGap(rule.selector, r.selector)) {
      return true
    }

    let media = getParentMedia(r)
    if (media) {
      // if we are inside media, we need to check that media props match
      // e.g ('min-width' === 'min-width')
      let propToCompare = parseMediaParams(media.params)[0]
      if (propToCompare === prop) {
        closestRuleGap = gridGap
        return true
      }
    } else {
      closestRuleGap = gridGap
      return true
    }

    return undefined
  })

  // if we find the closest gap object
  if (closestRuleGap && Object.keys(closestRuleGap).length > 0) {
    return closestRuleGap
  }
  return false
}

exports.warnGridGap = warnGridGap

function warnGridGap({ decl, gap, hasColumns, result }) {
  let hasBothGaps = gap.row && gap.column
  if (!hasColumns && (hasBothGaps || (gap.column && !gap.row))) {
    delete gap.column
    decl.warn(
      result,
      'Can not implement grid-gap without grid-template-columns'
    )
  }
}

/**
 * normalize the grid-template-rows/columns values
 * @param  {String} str grid-template-rows/columns value
 * @return {Array} normalized array with values
 * @example
 * let normalized = normalizeRowColumn('1fr repeat(2, 20px 50px) 1fr')
 * normalized // <= ['1fr', '20px', '50px', '20px', '50px', '1fr']
 */
function normalizeRowColumn(str) {
  let normalized = parser(str).nodes.reduce((result, node) => {
    if (node.type === 'function' && node.value === 'repeat') {
      let key = 'count'

      let [count, value] = node.nodes.reduce(
        (acc, n) => {
          if (n.type === 'word' && key === 'count') {
            acc[0] = Math.abs(parseInt(n.value))
            return acc
          }
          if (n.type === 'div' && n.value === ',') {
            key = 'value'
            return acc
          }
          if (key === 'value') {
            acc[1] += parser.stringify(n)
          }
          return acc
        },
        [0, '']
      )

      if (count) {
        for (let i = 0; i < count; i++) {
          result.push(value)
        }
      }

      return result
    }
    if (node.type === 'space') {
      return result
    }
    result.push(parser.stringify(node))
    return result
  }, [])

  return normalized
}

exports.autoplaceGridItems = autoplaceGridItems

/**
 * Autoplace grid items
 * @param {Declaration} decl
 * @param {Result} result
 * @param {Object} gap gap values
 * @param {String} autoflowValue grid-auto-flow value
 * @return {void}
 * @see https://github.com/postcss/autoprefixer/issues/1148
 */
function autoplaceGridItems(decl, result, gap, autoflowValue = 'row') {
  let { parent } = decl

  let rowDecl = parent.nodes.find(i => i.prop === 'grid-template-rows')
  let rows = normalizeRowColumn(rowDecl.value)
  let columns = normalizeRowColumn(decl.value)

  // Build array of area names with dummy values. If we have 3 columns and
  // 2 rows, filledRows will be equal to ['1 2 3', '4 5 6']
  let filledRows = rows.map((_, rowIndex) => {
    return Array.from(
      { length: columns.length },
      (v, k) => k + rowIndex * columns.length + 1
    ).join(' ')
  })

  let areas = parseGridAreas({ gap, rows: filledRows })
  let keys = Object.keys(areas)
  let items = keys.map(i => areas[i])

  // Change the order of cells if grid-auto-flow value is 'column'
  if (autoflowValue.includes('column')) {
    items = items.sort((a, b) => a.column.start - b.column.start)
  }

  // Insert new rules
  items.reverse().forEach((item, index) => {
    let { column, row } = item
    let nodeSelector = parent.selectors
      .map(sel => sel + ` > *:nth-child(${keys.length - index})`)
      .join(', ')

    // create new rule
    let node = parent.clone().removeAll()

    // change rule selector
    node.selector = nodeSelector

    // insert prefixed row/column values
    node.append({ prop: '-ms-grid-row', value: row.start })
    node.append({ prop: '-ms-grid-column', value: column.start })

    // insert rule
    parent.after(node)
  })

  return undefined
}


================================================
FILE: lib/hacks/image-rendering.js
================================================
let Declaration = require('../declaration')

class ImageRendering extends Declaration {
  /**
   * Add hack only for crisp-edges
   */
  check(decl) {
    return decl.value === 'pixelated'
  }

  /**
   * Return property name by spec
   */
  normalize() {
    return 'image-rendering'
  }

  /**
   * Change property name for IE
   */
  prefixed(prop, prefix) {
    if (prefix === '-ms-') {
      return '-ms-interpolation-mode'
    }
    return super.prefixed(prop, prefix)
  }

  /**
   * Warn on old value
   */
  process(node, result) {
    return super.process(node, result)
  }

  /**
   * Change property and value for IE
   */
  set(decl, prefix) {
    if (prefix !== '-ms-') return super.set(decl, prefix)
    decl.prop = '-ms-interpolation-mode'
    decl.value = 'nearest-neighbor'
    return decl
  }
}

ImageRendering.names = ['image-rendering', 'interpolation-mode']

module.exports = ImageRendering


================================================
FILE: lib/hacks/image-set.js
================================================
let Value = require('../value')

class ImageSet extends Value {
  /**
   * Use non-standard name for We
Download .txt
gitextract_70q035xe/

├── .editorconfig
├── .github/
│   ├── CONTRIBUTING.md
│   ├── FUNDING.yml
│   └── workflows/
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .npmignore
├── AUTHORS
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin/
│   └── autoprefixer
├── data/
│   └── prefixes.js
├── eslint.config.mjs
├── lib/
│   ├── at-rule.js
│   ├── autoprefixer.d.ts
│   ├── autoprefixer.js
│   ├── brackets.js
│   ├── browsers.js
│   ├── declaration.js
│   ├── hacks/
│   │   ├── align-content.js
│   │   ├── align-items.js
│   │   ├── align-self.js
│   │   ├── animation.js
│   │   ├── appearance.js
│   │   ├── autofill.js
│   │   ├── backdrop-filter.js
│   │   ├── background-clip.js
│   │   ├── background-size.js
│   │   ├── block-logical.js
│   │   ├── border-image.js
│   │   ├── border-radius.js
│   │   ├── break-props.js
│   │   ├── cross-fade.js
│   │   ├── display-flex.js
│   │   ├── display-grid.js
│   │   ├── file-selector-button.js
│   │   ├── filter-value.js
│   │   ├── filter.js
│   │   ├── flex-basis.js
│   │   ├── flex-direction.js
│   │   ├── flex-flow.js
│   │   ├── flex-grow.js
│   │   ├── flex-shrink.js
│   │   ├── flex-spec.js
│   │   ├── flex-wrap.js
│   │   ├── flex.js
│   │   ├── fullscreen.js
│   │   ├── gradient.js
│   │   ├── grid-area.js
│   │   ├── grid-column-align.js
│   │   ├── grid-end.js
│   │   ├── grid-row-align.js
│   │   ├── grid-row-column.js
│   │   ├── grid-rows-columns.js
│   │   ├── grid-start.js
│   │   ├── grid-template-areas.js
│   │   ├── grid-template.js
│   │   ├── grid-utils.js
│   │   ├── image-rendering.js
│   │   ├── image-set.js
│   │   ├── inline-logical.js
│   │   ├── intrinsic.js
│   │   ├── justify-content.js
│   │   ├── mask-border.js
│   │   ├── mask-composite.js
│   │   ├── order.js
│   │   ├── overscroll-behavior.js
│   │   ├── pixelated.js
│   │   ├── place-self.js
│   │   ├── placeholder-shown.js
│   │   ├── placeholder.js
│   │   ├── print-color-adjust.js
│   │   ├── text-decoration-skip-ink.js
│   │   ├── text-decoration.js
│   │   ├── text-emphasis-position.js
│   │   ├── transform-decl.js
│   │   ├── user-select.js
│   │   └── writing-mode.js
│   ├── info.js
│   ├── old-selector.js
│   ├── old-value.js
│   ├── prefixer.js
│   ├── prefixes.js
│   ├── processor.js
│   ├── resolution.js
│   ├── selector.js
│   ├── supports.js
│   ├── transition.js
│   ├── utils.js
│   ├── value.js
│   └── vendor.js
├── package.json
├── patches/
│   └── yargs@17.7.2.patch
└── test/
    ├── at-rule.test.js
    ├── autoprefixer.test.js
    ├── brackets.test.js
    ├── browsers.test.js
    ├── cases/
    │   ├── 3d-transform.css
    │   ├── 3d-transform.out.css
    │   ├── advanced-filter.css
    │   ├── advanced-filter.out.css
    │   ├── animation.css
    │   ├── animation.out.css
    │   ├── appearance.css
    │   ├── appearance.out.css
    │   ├── at-rules.css
    │   ├── at-rules.out.css
    │   ├── autofill.css
    │   ├── autofill.out.css
    │   ├── backdrop-filter.css
    │   ├── backdrop-filter.out.css
    │   ├── backdrop.css
    │   ├── backdrop.out.css
    │   ├── background-clip.css
    │   ├── background-clip.out.css
    │   ├── background-size.css
    │   ├── background-size.out.css
    │   ├── border-image.css
    │   ├── border-image.out.css
    │   ├── border-radius.css
    │   ├── border-radius.out.css
    │   ├── cascade.css
    │   ├── cascade.out.css
    │   ├── check-down.css
    │   ├── check-down.out.css
    │   ├── comments.css
    │   ├── comments.out.css
    │   ├── config/
    │   │   ├── browserslist
    │   │   ├── test.css
    │   │   ├── test.out.css
    │   │   └── test.production.css
    │   ├── content.css
    │   ├── cross-fade.css
    │   ├── cross-fade.out.css
    │   ├── custom-prefix.css
    │   ├── custom-prefix.out.css
    │   ├── disabled.css
    │   ├── disabled.out.css
    │   ├── double.css
    │   ├── double.out.css
    │   ├── element.css
    │   ├── element.out.css
    │   ├── example.css
    │   ├── example.out.css
    │   ├── file-selector-button.css
    │   ├── file-selector-button.out.css
    │   ├── filter.css
    │   ├── filter.out.css
    │   ├── flex-rewrite.css
    │   ├── flex-rewrite.out.css
    │   ├── flexbox.css
    │   ├── flexbox.out.css
    │   ├── fullscreen.css
    │   ├── fullscreen.out.css
    │   ├── gradient-fix.css
    │   ├── gradient-fix.out.css
    │   ├── gradient.css
    │   ├── gradient.out.css
    │   ├── grid-area-media-sequence.css
    │   ├── grid-area-media-sequence.out.css
    │   ├── grid-area.css
    │   ├── grid-area.out.css
    │   ├── grid-areas-duplicate-complex.css
    │   ├── grid-areas-duplicate-complex.out.css
    │   ├── grid-autoplacement.css
    │   ├── grid-autoplacement.out.css
    │   ├── grid-gap.css
    │   ├── grid-gap.out.css
    │   ├── grid-media-rules.css
    │   ├── grid-media-rules.out.css
    │   ├── grid-options.autoplace.out.css
    │   ├── grid-options.css
    │   ├── grid-options.disabled.out.css
    │   ├── grid-options.no-autoplace.out.css
    │   ├── grid-status.css
    │   ├── grid-status.out.css
    │   ├── grid-template-areas.css
    │   ├── grid-template-areas.out.css
    │   ├── grid-template.css
    │   ├── grid-template.out.css
    │   ├── grid.css
    │   ├── grid.disabled.css
    │   ├── grid.out.css
    │   ├── grouping-rule.css
    │   ├── grouping-rule.out.css
    │   ├── ignore-next.css
    │   ├── ignore-next.out.css
    │   ├── image-rendering.css
    │   ├── image-rendering.out.css
    │   ├── image-set.css
    │   ├── image-set.out.css
    │   ├── intrinsic.css
    │   ├── intrinsic.ff.css
    │   ├── intrinsic.out.css
    │   ├── keyframes.css
    │   ├── keyframes.out.css
    │   ├── logical.css
    │   ├── logical.out.css
    │   ├── mask-border.css
    │   ├── mask-border.out.css
    │   ├── mask-composite.css
    │   ├── mask-composite.out.css
    │   ├── mistakes.css
    │   ├── mistakes.out.css
    │   ├── multicolumn.css
    │   ├── multicolumn.out.css
    │   ├── notes.css
    │   ├── notes.out.css
    │   ├── overscroll-behavior.css
    │   ├── overscroll-behavior.out.css
    │   ├── pie.css
    │   ├── placeholder-shown.css
    │   ├── placeholder-shown.out.css
    │   ├── placeholder.css
    │   ├── placeholder.out.css
    │   ├── print-color-adjust.css
    │   ├── print-color-adjust.out.css
    │   ├── resolution.css
    │   ├── resolution.out.css
    │   ├── scope.css
    │   ├── scope.out.css
    │   ├── selectors.css
    │   ├── selectors.out.css
    │   ├── style.css
    │   ├── style.out.css
    │   ├── supports.css
    │   ├── supports.out.css
    │   ├── syntax.css
    │   ├── text-decoration.css
    │   ├── text-decoration.out.css
    │   ├── text-decoration.shorthand.out.css
    │   ├── text-emphasis-position.css
    │   ├── text-emphasis-position.out.css
    │   ├── transition-no-warning.css
    │   ├── transition-no-warning.out.css
    │   ├── transition-spec.css
    │   ├── transition-spec.out.css
    │   ├── transition.css
    │   ├── transition.out.css
    │   ├── trim.css
    │   ├── uncascade.css
    │   ├── uncascade.out.css
    │   ├── user-select.css
    │   ├── user-select.out.css
    │   ├── value-hack.css
    │   ├── value-hack.out.css
    │   ├── values.css
    │   ├── values.out.css
    │   ├── vendor-hack.css
    │   ├── vendor-hack.out.css
    │   ├── viewport.css
    │   ├── viewport.out.css
    │   ├── webkit-line-clamp.css
    │   ├── webkit-line-clamp.out.css
    │   ├── writing-mode.css
    │   └── writing-mode.out.css
    ├── declaration.test.js
    ├── info.test.js
    ├── old-selector.test.js
    ├── old-value.test.js
    ├── postcss.test.js
    ├── prefixer.test.js
    ├── prefixes.test.js
    ├── selector.test.js
    ├── supports.test.js
    ├── utils.test.js
    └── value.test.js
Download .txt
SYMBOL INDEX (398 symbols across 83 files)

FILE: data/prefixes.js
  function browsersSort (line 3) | function browsersSort(a, b) {
  function f (line 16) | function f(data, opts, callback) {
  function prefix (line 42) | function prefix(names, data) {
  function add (line 48) | function add(names, data) {

FILE: lib/at-rule.js
  class AtRule (line 3) | class AtRule extends Prefixer {
    method add (line 7) | add(rule, prefix) {
    method process (line 24) | process(node) {

FILE: lib/autoprefixer.d.ts
  type GridValue (line 18) | type GridValue = 'autoplace' | 'no-autoplace'
  type Options (line 20) | interface Options {
  type ExportedAPI (line 57) | interface ExportedAPI {
  type ProcessEnv (line 89) | interface ProcessEnv {

FILE: lib/autoprefixer.js
  constant WARNING (line 12) | const WARNING =
  function isPlainObject (line 27) | function isPlainObject(obj) {
  function timeCapsule (line 33) | function timeCapsule(result, prefixes) {
  function plugin (line 59) | function plugin(...reqs) {

FILE: lib/brackets.js
  function last (line 1) | function last(array) {
  method parse (line 9) | parse(str) {
  method stringify (line 37) | stringify(ast) {

FILE: lib/browsers.js
  class Browsers (line 6) | class Browsers {
    method constructor (line 7) | constructor(data, requirements, options, browserslistOpts) {
    method prefixes (line 17) | static prefixes() {
    method withPrefix (line 37) | static withPrefix(value) {
    method isSelected (line 48) | isSelected(browser) {
    method parse (line 55) | parse(requirements) {
    method prefix (line 67) | prefix(browser) {

FILE: lib/declaration.js
  class Declaration (line 5) | class Declaration extends Prefixer {
    method add (line 9) | add(decl, prefix, prefixes, result) {
    method calcBefore (line 23) | calcBefore(prefixes, decl, prefix = '') {
    method check (line 38) | check(/* decl */) {
    method insert (line 45) | insert(decl, prefix, prefixes) {
    method isAlready (line 65) | isAlready(decl, prefixed) {
    method maxPrefixed (line 76) | maxPrefixed(prefixes, decl) {
    method needCascade (line 96) | needCascade(decl) {
    method normalize (line 107) | normalize(prop) {
    method old (line 114) | old(prop, prefix) {
    method otherPrefixes (line 121) | otherPrefixes(value, prefix) {
    method prefixed (line 136) | prefixed(prop, prefix) {
    method process (line 143) | process(decl, result) {
    method restoreBefore (line 162) | restoreBefore(decl) {
    method set (line 181) | set(decl, prefix) {

FILE: lib/hacks/align-content.js
  class AlignContent (line 4) | class AlignContent extends Declaration {
    method normalize (line 8) | normalize() {
    method prefixed (line 15) | prefixed(prop, prefix) {
    method set (line 27) | set(decl, prefix) {

FILE: lib/hacks/align-items.js
  class AlignItems (line 4) | class AlignItems extends Declaration {
    method normalize (line 8) | normalize() {
    method prefixed (line 15) | prefixed(prop, prefix) {
    method set (line 30) | set(decl, prefix) {

FILE: lib/hacks/align-self.js
  class AlignSelf (line 4) | class AlignSelf extends Declaration {
    method check (line 5) | check(decl) {
    method normalize (line 17) | normalize() {
    method prefixed (line 24) | prefixed(prop, prefix) {
    method set (line 36) | set(decl, prefix) {

FILE: lib/hacks/animation.js
  class Animation (line 3) | class Animation extends Declaration {
    method check (line 7) | check(decl) {

FILE: lib/hacks/appearance.js
  class Appearance (line 4) | class Appearance extends Declaration {
    method constructor (line 5) | constructor(name, prefixes, all) {

FILE: lib/hacks/autofill.js
  class Autofill (line 4) | class Autofill extends Selector {
    method constructor (line 5) | constructor(name, prefixes, all) {
    method prefixed (line 16) | prefixed(prefix) {

FILE: lib/hacks/backdrop-filter.js
  class BackdropFilter (line 4) | class BackdropFilter extends Declaration {
    method constructor (line 5) | constructor(name, prefixes, all) {

FILE: lib/hacks/background-clip.js
  class BackgroundClip (line 4) | class BackgroundClip extends Declaration {
    method constructor (line 5) | constructor(name, prefixes, all) {
    method check (line 17) | check(decl) {

FILE: lib/hacks/background-size.js
  class BackgroundSize (line 3) | class BackgroundSize extends Declaration {
    method set (line 7) | set(decl, prefix) {

FILE: lib/hacks/block-logical.js
  class BlockLogical (line 3) | class BlockLogical extends Declaration {
    method normalize (line 7) | normalize(prop) {
    method prefixed (line 17) | prefixed(prop, prefix) {

FILE: lib/hacks/border-image.js
  class BorderImage (line 3) | class BorderImage extends Declaration {
    method set (line 7) | set(decl, prefix) {

FILE: lib/hacks/border-radius.js
  class BorderRadius (line 3) | class BorderRadius extends Declaration {
    method normalize (line 7) | normalize(prop) {
    method prefixed (line 14) | prefixed(prop, prefix) {

FILE: lib/hacks/break-props.js
  class BreakProps (line 3) | class BreakProps extends Declaration {
    method insert (line 7) | insert(decl, prefix, prefixes) {
    method normalize (line 20) | normalize(prop) {
    method prefixed (line 33) | prefixed(prop, prefix) {
    method set (line 40) | set(decl, prefix) {

FILE: lib/hacks/cross-fade.js
  class CrossFade (line 5) | class CrossFade extends Value {
    method replace (line 6) | replace(string, prefix) {

FILE: lib/hacks/display-flex.js
  class DisplayFlex (line 5) | class DisplayFlex extends Value {
    method constructor (line 6) | constructor(name, prefixes) {
    method check (line 16) | check(decl) {
    method old (line 23) | old(prefix) {
    method prefixed (line 32) | prefixed(prefix) {
    method replace (line 58) | replace(string, prefix) {

FILE: lib/hacks/display-grid.js
  class DisplayGrid (line 3) | class DisplayGrid extends Value {
    method constructor (line 4) | constructor(name, prefixes) {
    method check (line 14) | check(decl) {

FILE: lib/hacks/file-selector-button.js
  class FileSelectorButton (line 4) | class FileSelectorButton extends Selector {
    method constructor (line 5) | constructor(name, prefixes, all) {
    method prefixed (line 16) | prefixed(prefix) {

FILE: lib/hacks/filter-value.js
  class FilterValue (line 3) | class FilterValue extends Value {
    method constructor (line 4) | constructor(name, prefixes) {

FILE: lib/hacks/filter.js
  class Filter (line 3) | class Filter extends Declaration {
    method check (line 7) | check(decl) {

FILE: lib/hacks/flex-basis.js
  class FlexBasis (line 4) | class FlexBasis extends Declaration {
    method normalize (line 8) | normalize() {
    method prefixed (line 15) | prefixed(prop, prefix) {
    method set (line 27) | set(decl, prefix) {

FILE: lib/hacks/flex-direction.js
  class FlexDirection (line 4) | class FlexDirection extends Declaration {
    method insert (line 8) | insert(decl, prefix, prefixes) {
    method normalize (line 52) | normalize() {
    method old (line 59) | old(prop, prefix) {

FILE: lib/hacks/flex-flow.js
  class FlexFlow (line 4) | class FlexFlow extends Declaration {
    method insert (line 8) | insert(decl, prefix, prefixes) {

FILE: lib/hacks/flex-grow.js
  class Flex (line 4) | class Flex extends Declaration {
    method normalize (line 8) | normalize() {
    method prefixed (line 15) | prefixed(prop, prefix) {

FILE: lib/hacks/flex-shrink.js
  class FlexShrink (line 4) | class FlexShrink extends Declaration {
    method normalize (line 8) | normalize() {
    method prefixed (line 15) | prefixed(prop, prefix) {
    method set (line 27) | set(decl, prefix) {

FILE: lib/hacks/flex-wrap.js
  class FlexWrap (line 4) | class FlexWrap extends Declaration {
    method set (line 8) | set(decl, prefix) {

FILE: lib/hacks/flex.js
  class Flex (line 6) | class Flex extends Declaration {
    method normalize (line 10) | normalize() {
    method prefixed (line 17) | prefixed(prop, prefix) {
    method set (line 30) | set(decl, prefix) {

FILE: lib/hacks/fullscreen.js
  class Fullscreen (line 3) | class Fullscreen extends Selector {
    method prefixed (line 7) | prefixed(prefix) {

FILE: lib/hacks/gradient.js
  constant IS_DIRECTION (line 7) | let IS_DIRECTION = /top|left|right|bottom/gi
  class Gradient (line 9) | class Gradient extends Value {
    method add (line 13) | add(decl, prefix) {
    method cloneDiv (line 36) | cloneDiv(params) {
    method colorStops (line 48) | colorStops(params) {
    method convertDirection (line 89) | convertDirection(params) {
    method fixAngle (line 105) | fixAngle(params) {
    method fixDirection (line 116) | fixDirection(params) {
    method fixRadial (line 132) | fixRadial(params) {
    method isRadial (line 165) | isRadial(params) {
    method newDirection (line 186) | newDirection(params) {
    method normalize (line 221) | normalize(nodes, gradientName) {
    method normalizeUnit (line 261) | normalizeUnit(str, full) {
    method old (line 270) | old(prefix) {
    method oldDirection (line 297) | oldDirection(params) {
    method oldWebkit (line 324) | oldWebkit(node) {
    method replace (line 373) | replace(string, prefix) {
    method replaceFirst (line 397) | replaceFirst(params, ...words) {
    method revertDirection (line 407) | revertDirection(word) {
    method roundFloat (line 414) | roundFloat(float, digits) {

FILE: lib/hacks/grid-area.js
  class GridArea (line 4) | class GridArea extends Declaration {
    method insert (line 8) | insert(decl, prefix, prefixes, result) {

FILE: lib/hacks/grid-column-align.js
  class GridColumnAlign (line 3) | class GridColumnAlign extends Declaration {
    method check (line 7) | check(decl) {
    method normalize (line 14) | normalize() {
    method prefixed (line 21) | prefixed(prop, prefix) {

FILE: lib/hacks/grid-end.js
  class GridEnd (line 4) | class GridEnd extends Declaration {
    method insert (line 8) | insert(decl, prefix, prefixes, result) {

FILE: lib/hacks/grid-row-align.js
  class GridRowAlign (line 3) | class GridRowAlign extends Declaration {
    method check (line 7) | check(decl) {
    method normalize (line 14) | normalize() {
    method prefixed (line 21) | prefixed(prop, prefix) {

FILE: lib/hacks/grid-row-column.js
  class GridRowColumn (line 4) | class GridRowColumn extends Declaration {
    method insert (line 8) | insert(decl, prefix, prefixes) {

FILE: lib/hacks/grid-rows-columns.js
  class GridRowsColumns (line 11) | class GridRowsColumns extends Declaration {
    method insert (line 12) | insert(decl, prefix, prefixes, result) {
    method normalize (line 103) | normalize(prop) {
    method prefixed (line 110) | prefixed(prop, prefix) {

FILE: lib/hacks/grid-start.js
  class GridStart (line 3) | class GridStart extends Declaration {
    method check (line 7) | check(decl) {
    method normalize (line 15) | normalize(prop) {
    method prefixed (line 22) | prefixed(prop, prefix) {

FILE: lib/hacks/grid-template-areas.js
  function getGridRows (line 12) | function getGridRows(tpl) {
  class GridTemplateAreas (line 19) | class GridTemplateAreas extends Declaration {
    method insert (line 23) | insert(decl, prefix, prefixes, result) {

FILE: lib/hacks/grid-template.js
  class GridTemplate (line 10) | class GridTemplate extends Declaration {
    method insert (line 14) | insert(decl, prefix, prefixes, result) {

FILE: lib/hacks/grid-utils.js
  function convert (line 8) | function convert(value) {
  function translate (line 27) | function translate(values, startIndex, endIndex) {
  function parse (line 59) | function parse(decl) {
  function insertDecl (line 80) | function insertDecl(decl, prop, value) {
  function prefixTrackProp (line 93) | function prefixTrackProp({ prefix, prop }) {
  function transformRepeat (line 97) | function transformRepeat({ nodes }, { gap }) {
  function prefixTrackValue (line 135) | function prefixTrackValue({ gap, value }) {
  constant DOTS (line 167) | let DOTS = /^\.+$/
  function track (line 169) | function track(start, end) {
  function getColumns (line 173) | function getColumns(line) {
  function parseGridAreas (line 179) | function parseGridAreas({ gap, rows }) {
  function testTrack (line 214) | function testTrack(node) {
  function verifyRowSize (line 218) | function verifyRowSize(result) {
  function parseTemplate (line 227) | function parseTemplate({ decl, gap }) {
  function getMSDecls (line 286) | function getMSDecls(area, addRowSpan = false, addColumnSpan = false) {
  function getParentMedia (line 312) | function getParentMedia(parent) {
  function changeDuplicateAreaSelectors (line 328) | function changeDuplicateAreaSelectors(ruleSelectors, templateSelectors) {
  function selectorsEqual (line 355) | function selectorsEqual(ruleA, ruleB) {
  function parseGridTemplatesData (line 366) | function parseGridTemplatesData(css) {
  function insertAreas (line 475) | function insertAreas(css, isDisabled) {
  function warnMissedAreas (line 694) | function warnMissedAreas(areas, decl, result) {
  function warnTemplateSelectorNotFound (line 718) | function warnTemplateSelectorNotFound(decl, result) {
  function warnIfGridRowColumnExists (line 791) | function warnIfGridRowColumnExists(decl, result) {
  function getGridGap (line 820) | function getGridGap(decl) {
  function parseMediaParams (line 844) | function parseMediaParams(params) {
  function shouldInheritGap (line 870) | function shouldInheritGap(selA, selB) {
  function inheritGridGap (line 926) | function inheritGridGap(decl, gap) {
  function warnGridGap (line 999) | function warnGridGap({ decl, gap, hasColumns, result }) {
  function normalizeRowColumn (line 1018) | function normalizeRowColumn(str) {
  function autoplaceGridItems (line 1070) | function autoplaceGridItems(decl, result, gap, autoflowValue = 'row') {

FILE: lib/hacks/image-rendering.js
  class ImageRendering (line 3) | class ImageRendering extends Declaration {
    method check (line 7) | check(decl) {
    method normalize (line 14) | normalize() {
    method prefixed (line 21) | prefixed(prop, prefix) {
    method process (line 31) | process(node, result) {
    method set (line 38) | set(decl, prefix) {

FILE: lib/hacks/image-set.js
  class ImageSet (line 3) | class ImageSet extends Value {
    method replace (line 7) | replace(string, prefix) {

FILE: lib/hacks/inline-logical.js
  class InlineLogical (line 3) | class InlineLogical extends Declaration {
    method normalize (line 7) | normalize(prop) {
    method prefixed (line 14) | prefixed(prop, prefix) {

FILE: lib/hacks/intrinsic.js
  function regexp (line 4) | function regexp(name) {
  class Intrinsic (line 8) | class Intrinsic extends Value {
    method add (line 9) | add(decl, prefix) {
    method isStretch (line 16) | isStretch() {
    method old (line 24) | old(prefix) {
    method regexp (line 36) | regexp() {
    method replace (line 41) | replace(string, prefix) {

FILE: lib/hacks/justify-content.js
  class JustifyContent (line 4) | class JustifyContent extends Declaration {
    method normalize (line 8) | normalize() {
    method prefixed (line 15) | prefixed(prop, prefix) {
    method set (line 30) | set(decl, prefix) {

FILE: lib/hacks/mask-border.js
  class MaskBorder (line 3) | class MaskBorder extends Declaration {
    method normalize (line 7) | normalize() {
    method prefixed (line 14) | prefixed(prop, prefix) {

FILE: lib/hacks/mask-composite.js
  class MaskComposite (line 3) | class MaskComposite extends Declaration {
    method insert (line 7) | insert(decl, prefix, prefixes) {

FILE: lib/hacks/order.js
  class Order (line 4) | class Order extends Declaration {
    method normalize (line 8) | normalize() {
    method prefixed (line 15) | prefixed(prop, prefix) {
    method set (line 30) | set(decl, prefix) {

FILE: lib/hacks/overscroll-behavior.js
  class OverscrollBehavior (line 3) | class OverscrollBehavior extends Declaration {
    method normalize (line 7) | normalize() {
    method prefixed (line 14) | prefixed(prop, prefix) {
    method set (line 21) | set(decl, prefix) {

FILE: lib/hacks/pixelated.js
  class Pixelated (line 4) | class Pixelated extends Value {
    method old (line 8) | old(prefix) {
    method replace (line 21) | replace(string, prefix) {

FILE: lib/hacks/place-self.js
  class PlaceSelf (line 4) | class PlaceSelf extends Declaration {
    method insert (line 8) | insert(decl, prefix, prefixes) {

FILE: lib/hacks/placeholder-shown.js
  class PlaceholderShown (line 3) | class PlaceholderShown extends Selector {
    method prefixed (line 7) | prefixed(prefix) {

FILE: lib/hacks/placeholder.js
  class Placeholder (line 3) | class Placeholder extends Selector {
    method possible (line 7) | possible() {
    method prefixed (line 14) | prefixed(prefix) {

FILE: lib/hacks/print-color-adjust.js
  class PrintColorAdjust (line 3) | class PrintColorAdjust extends Declaration {
    method normalize (line 7) | normalize() {
    method prefixed (line 14) | prefixed(prop, prefix) {

FILE: lib/hacks/text-decoration-skip-ink.js
  class TextDecorationSkipInk (line 3) | class TextDecorationSkipInk extends Declaration {
    method set (line 7) | set(decl, prefix) {

FILE: lib/hacks/text-decoration.js
  constant BASIC (line 3) | const BASIC = [
  class TextDecoration (line 14) | class TextDecoration extends Declaration {
    method check (line 18) | check(decl) {

FILE: lib/hacks/text-emphasis-position.js
  class TextEmphasisPosition (line 3) | class TextEmphasisPosition extends Declaration {
    method set (line 4) | set(decl, prefix) {

FILE: lib/hacks/transform-decl.js
  class TransformDecl (line 3) | class TransformDecl extends Declaration {
    method contain3d (line 7) | contain3d(decl) {
    method insert (line 24) | insert(decl, prefix, prefixes) {
    method keyframeParents (line 42) | keyframeParents(decl) {
    method set (line 56) | set(decl, prefix) {

FILE: lib/hacks/user-select.js
  class UserSelect (line 3) | class UserSelect extends Declaration {
    method insert (line 7) | insert(decl, prefix, prefixes) {
    method set (line 23) | set(decl, prefix) {

FILE: lib/hacks/writing-mode.js
  class WritingMode (line 3) | class WritingMode extends Declaration {
    method insert (line 4) | insert(decl, prefix, prefixes) {

FILE: lib/info.js
  function capitalize (line 3) | function capitalize(str) {
  constant NAMES (line 7) | const NAMES = {
  function prefix (line 22) | function prefix(name, prefixes, note) {

FILE: lib/old-selector.js
  class OldSelector (line 1) | class OldSelector {
    method constructor (line 2) | constructor(selector, prefix) {
    method check (line 18) | check(rule) {
    method isHack (line 34) | isHack(rule) {

FILE: lib/old-value.js
  class OldValue (line 3) | class OldValue {
    method constructor (line 4) | constructor(unprefixed, prefixed, string, regexp) {
    method check (line 14) | check(value) {

FILE: lib/prefixer.js
  function clone (line 8) | function clone(obj, parent) {
  class Prefixer (line 36) | class Prefixer {
    method constructor (line 37) | constructor(name, prefixes, all) {
    method clone (line 46) | static clone(node, overrides) {
    method hack (line 57) | static hack(klass) {
    method load (line 70) | static load(name, prefixes, all) {
    method clone (line 82) | clone(node, overrides) {
    method parentPrefix (line 89) | parentPrefix(node) {
    method process (line 122) | process(node, result) {

FILE: lib/prefixes.js
  class Prefixes (line 130) | class Prefixes {
    method constructor (line 131) | constructor(data, browsers, options = {}) {
    method cleaner (line 143) | cleaner() {
    method decl (line 161) | decl(prop) {
    method group (line 172) | group(decl) {
    method normalize (line 220) | normalize(prop) {
    method prefixed (line 227) | prefixed(prop, prefix) {
    method preprocess (line 235) | preprocess(selected) {
    method select (line 330) | select(list) {
    method sort (line 387) | sort(prefixes) {
    method unprefixed (line 403) | unprefixed(prop) {
    method values (line 414) | values(type, prop) {

FILE: lib/processor.js
  constant OLD_LINEAR (line 6) | const OLD_LINEAR = /(^|[^-])linear-gradient\(\s*(top|left|right|bottom)/i
  constant OLD_RADIAL (line 7) | const OLD_RADIAL = /(^|[^-])radial-gradient\(\s*\d+(\w*|%)\s+\d+(\w*|%)\...
  constant IGNORE_NEXT (line 8) | const IGNORE_NEXT = /(!\s*)?autoprefixer:\s*ignore\s+next/i
  constant GRID_REGEX (line 9) | const GRID_REGEX = /(!\s*)?autoprefixer\s*grid:\s*(on|off|(no-)?autoplac...
  constant SIZES (line 11) | const SIZES = [
  function hasGridTemplate (line 26) | function hasGridTemplate(decl) {
  function hasRowsAndColumns (line 32) | function hasRowsAndColumns(decl) {
  class Processor (line 38) | class Processor {
    method constructor (line 39) | constructor(prefixes) {
    method add (line 46) | add(css, result) {
    method disabled (line 386) | disabled(node, result) {
    method disabledDecl (line 444) | disabledDecl(node, result) {
    method disabledValue (line 463) | disabledValue(node, result) {
    method displayType (line 484) | displayType(decl) {
    method gridStatus (line 505) | gridStatus(node, result) {
    method reduceSpaces (line 577) | reduceSpaces(decl) {
    method remove (line 609) | remove(css, result) {
    method withHackValue (line 698) | withHackValue(decl) {

FILE: lib/resolution.js
  constant REGEXP (line 6) | const REGEXP = /(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi
  constant SPLIT (line 7) | const SPLIT = /(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i
  class Resolution (line 9) | class Resolution extends Prefixer {
    method clean (line 13) | clean(rule) {
    method prefixName (line 30) | prefixName(prefix, name) {
    method prefixQuery (line 41) | prefixQuery(prefix, name, colon, value, units) {
    method process (line 62) | process(rule) {

FILE: lib/selector.js
  class Selector (line 8) | class Selector extends Prefixer {
    method constructor (line 9) | constructor(name, prefixes, all) {
    method add (line 17) | add(rule, prefix) {
    method already (line 31) | already(rule, prefixeds, prefix) {
    method check (line 66) | check(rule) {
    method old (line 77) | old(prefix) {
    method possible (line 84) | possible() {
    method prefixed (line 91) | prefixed(prefix) {
    method prefixeds (line 98) | prefixeds(rule) {
    method regexp (line 130) | regexp(prefix) {
    method replace (line 145) | replace(selector, prefix) {

FILE: lib/supports.js
  class Supports (line 23) | class Supports {
    method constructor (line 24) | constructor(Prefixes, all) {
    method add (line 32) | add(nodes, all) {
    method cleanBrackets (line 54) | cleanBrackets(nodes) {
    method convert (line 71) | convert(progress) {
    method disabled (line 84) | disabled(node) {
    method isHack (line 110) | isHack(all, unprefixed) {
    method isNot (line 118) | isNot(node) {
    method isOr (line 125) | isOr(node) {
    method isProp (line 132) | isProp(node) {
    method normalize (line 143) | normalize(nodes) {
    method parse (line 167) | parse(str) {
    method prefixed (line 178) | prefixed(str) {
    method prefixer (line 202) | prefixer() {
    method process (line 227) | process(rule) {
    method remove (line 239) | remove(nodes, all) {
    method toRemove (line 268) | toRemove(str, all) {
    method virtual (line 294) | virtual(str) {

FILE: lib/transition.js
  class Transition (line 7) | class Transition {
    method constructor (line 8) | constructor(prefixes) {
    method add (line 16) | add(decl, result) {
    method already (line 85) | already(decl, prop, value) {
    method checkForWarning (line 92) | checkForWarning(result, decl) {
    method cleanFromUnprefixed (line 137) | cleanFromUnprefixed(params, prefix) {
    method cleanOtherPrefixes (line 154) | cleanOtherPrefixes(params, prefix) {
    method clone (line 164) | clone(origin, name, param) {
    method cloneBefore (line 181) | cloneBefore(decl, prop, value) {
    method disabled (line 190) | disabled(prop, prefix) {
    method div (line 207) | div(params) {
    method findProp (line 221) | findProp(param) {
    method parse (line 236) | parse(value) {
    method remove (line 254) | remove(decl) {
    method ruleVendorPrefixes (line 289) | ruleVendorPrefixes(decl) {
    method stringify (line 308) | stringify(params) {

FILE: lib/value.js
  class Value (line 6) | class Value extends Prefixer {
    method save (line 10) | static save(prefixes, decl) {
    method add (line 64) | add(decl, prefix) {
    method check (line 83) | check(decl) {
    method old (line 95) | old(prefix) {
    method regexp (line 102) | regexp() {
    method replace (line 109) | replace(string, prefix) {
    method value (line 116) | value(decl) {

FILE: lib/vendor.js
  method prefix (line 2) | prefix(prop) {
  method unprefixed (line 11) | unprefixed(prop) {

FILE: test/autoprefixer.test.js
  function prefixer (line 109) | function prefixer(name) {
  function read (line 201) | function read(name) {
  function universalizer (line 206) | function universalizer(string) {
  function check (line 210) | function check(from, instance = prefixer(from)) {
  constant COMMONS (line 218) | const COMMONS = [
  function isContainerNode (line 558) | function isContainerNode(node) {
  function checkParent (line 563) | function checkParent(node) {
  function plugin (line 611) | function plugin(root) {
  function ap (line 639) | function ap(gridValue) {
  function ap (line 666) | function ap(gridValue) {

FILE: test/postcss.test.js
  method Rule (line 18) | Rule(rule) {

FILE: test/prefixer.test.js
  class A (line 18) | class A extends Prefixer {}
    method constructor (line 30) | constructor() {
  class Hack (line 19) | class Hack extends A {}
    method constructor (line 36) | constructor() {
  class A (line 29) | class A extends Prefixer {
    method constructor (line 30) | constructor() {
  class Hack (line 35) | class Hack extends A {
    method constructor (line 36) | constructor() {

FILE: test/prefixes.test.js
  function old (line 43) | function old(prefixed) {

FILE: test/supports.test.js
  function rm (line 32) | function rm(str) {
  function clean (line 37) | function clean(str) {

FILE: test/utils.test.js
  function check (line 38) | function check(string) {
  function check (line 56) | function check(string) {
Condensed preview — 268 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (535K chars).
[
  {
    "path": ".editorconfig",
    "chars": 147,
    "preview": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ni"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 3386,
    "preview": "<img width=\"94\" height=\"71\" src=\"../logo.svg\" title=\"Autoprefixer logo by Anton Lovchikov\">\n\n# Contributing to Autoprefi"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 63,
    "preview": "open_collective: postcss\ntidelift: npm/autoprefixer\ngithub: ai\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1479,
    "preview": "name: Release\non:\n  push:\n    tags:\n      - '*'\npermissions:\n  contents: write\njobs:\n  release:\n    name: Release On Tag"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 2528,
    "preview": "name: Test\non:\n  push:\n    branches:\n      - main\n  pull_request:\npermissions:\n  contents: read\njobs:\n  full:\n    name: "
  },
  {
    "path": ".gitignore",
    "chars": 25,
    "preview": "node_modules/\n\ncoverage/\n"
  },
  {
    "path": ".npmignore",
    "chars": 60,
    "preview": "test/\ncoverage/\n\nlogo.svg\nAUTHORS\neslint.config.mjs\npatches\n"
  },
  {
    "path": "AUTHORS",
    "chars": 6735,
    "preview": "# This is the official list of Autoprefixer authors for copyright purposes.\n#\n# This does not necessarily list everyone "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 33687,
    "preview": "# Change Log\nThis project adheres to [Semantic Versioning](http://semver.org/).\n\n## 10.4.27\n* Removed development key fr"
  },
  {
    "path": "LICENSE",
    "chars": 1095,
    "preview": "The MIT License (MIT)\n\nCopyright 2013 Andrey Sitnik <andrey@sitnik.ru>\n\nPermission is hereby granted, free of charge, to"
  },
  {
    "path": "README.md",
    "chars": 30940,
    "preview": "# Autoprefixer [![Cult Of Martians][cult-img]][cult]\n\n<img align=\"right\" width=\"94\" height=\"71\"\n     src=\"https://postcs"
  },
  {
    "path": "bin/autoprefixer",
    "chars": 554,
    "preview": "#!/usr/bin/env node\n\nlet mode = process.argv[2]\nif (mode === '--info') {\n  process.stdout.write(require('../')().info() "
  },
  {
    "path": "data/prefixes.js",
    "chars": 23938,
    "preview": "let unpack = require('caniuse-lite/dist/unpacker/feature')\n\nfunction browsersSort(a, b) {\n  a = a.split(' ')\n  b = b.spl"
  },
  {
    "path": "eslint.config.mjs",
    "chars": 446,
    "preview": "import loguxConfig from '@logux/eslint-config'\n\nexport default [\n  {\n    ignores: ['coverage']\n  },\n  ...loguxConfig,\n  "
  },
  {
    "path": "lib/at-rule.js",
    "chars": 702,
    "preview": "let Prefixer = require('./prefixer')\n\nclass AtRule extends Prefixer {\n  /**\n   * Clone and add prefixes for at-rule\n   *"
  },
  {
    "path": "lib/autoprefixer.d.ts",
    "chars": 2448,
    "preview": "import { Plugin } from 'postcss'\nimport { Stats } from 'browserslist'\n\ndeclare function autoprefixer<T extends string[]>"
  },
  {
    "path": "lib/autoprefixer.js",
    "chars": 4182,
    "preview": "let browserslist = require('browserslist')\nlet { agents } = require('caniuse-lite/dist/unpacker/agents')\nlet pico = requ"
  },
  {
    "path": "lib/brackets.js",
    "chars": 849,
    "preview": "function last(array) {\n  return array[array.length - 1]\n}\n\nlet brackets = {\n  /**\n   * Parse string to nodes tree\n   */\n"
  },
  {
    "path": "lib/browsers.js",
    "chars": 1769,
    "preview": "let browserslist = require('browserslist')\nlet { agents } = require('caniuse-lite/dist/unpacker/agents')\n\nlet utils = re"
  },
  {
    "path": "lib/declaration.js",
    "chars": 4068,
    "preview": "let Browsers = require('./browsers')\nlet Prefixer = require('./prefixer')\nlet utils = require('./utils')\n\nclass Declarat"
  },
  {
    "path": "lib/hacks/align-content.js",
    "chars": 1058,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass AlignContent extends Declaratio"
  },
  {
    "path": "lib/hacks/align-items.js",
    "chars": 968,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass AlignItems extends Declaration "
  },
  {
    "path": "lib/hacks/align-self.js",
    "chars": 1131,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass AlignSelf extends Declaration {"
  },
  {
    "path": "lib/hacks/animation.js",
    "chars": 399,
    "preview": "let Declaration = require('../declaration')\n\nclass Animation extends Declaration {\n  /**\n   * Don’t add prefixes for mod"
  },
  {
    "path": "lib/hacks/appearance.js",
    "chars": 463,
    "preview": "let Declaration = require('../declaration')\nlet utils = require('../utils')\n\nclass Appearance extends Declaration {\n  co"
  },
  {
    "path": "lib/hacks/autofill.js",
    "chars": 531,
    "preview": "let Selector = require('../selector')\nlet utils = require('../utils')\n\nclass Autofill extends Selector {\n  constructor(n"
  },
  {
    "path": "lib/hacks/backdrop-filter.js",
    "chars": 436,
    "preview": "let Declaration = require('../declaration')\nlet utils = require('../utils')\n\nclass BackdropFilter extends Declaration {\n"
  },
  {
    "path": "lib/hacks/background-clip.js",
    "chars": 504,
    "preview": "let Declaration = require('../declaration')\nlet utils = require('../utils')\n\nclass BackgroundClip extends Declaration {\n"
  },
  {
    "path": "lib/hacks/background-size.js",
    "chars": 516,
    "preview": "let Declaration = require('../declaration')\n\nclass BackgroundSize extends Declaration {\n  /**\n   * Duplication parameter"
  },
  {
    "path": "lib/hacks/block-logical.js",
    "chars": 857,
    "preview": "let Declaration = require('../declaration')\n\nclass BlockLogical extends Declaration {\n  /**\n   * Return property name by"
  },
  {
    "path": "lib/hacks/border-image.js",
    "chars": 338,
    "preview": "let Declaration = require('../declaration')\n\nclass BorderImage extends Declaration {\n  /**\n   * Remove fill parameter fo"
  },
  {
    "path": "lib/hacks/border-radius.js",
    "chars": 907,
    "preview": "let Declaration = require('../declaration')\n\nclass BorderRadius extends Declaration {\n  /**\n   * Return unprefixed versi"
  },
  {
    "path": "lib/hacks/break-props.js",
    "chars": 1311,
    "preview": "let Declaration = require('../declaration')\n\nclass BreakProps extends Declaration {\n  /**\n   * Don’t prefix some values\n"
  },
  {
    "path": "lib/hacks/cross-fade.js",
    "chars": 863,
    "preview": "let list = require('postcss').list\n\nlet Value = require('../value')\n\nclass CrossFade extends Value {\n  replace(string, p"
  },
  {
    "path": "lib/hacks/display-flex.js",
    "chars": 1303,
    "preview": "let OldValue = require('../old-value')\nlet Value = require('../value')\nlet flexSpec = require('./flex-spec')\n\nclass Disp"
  },
  {
    "path": "lib/hacks/display-grid.js",
    "chars": 409,
    "preview": "let Value = require('../value')\n\nclass DisplayGrid extends Value {\n  constructor(name, prefixes) {\n    super(name, prefi"
  },
  {
    "path": "lib/hacks/file-selector-button.js",
    "chars": 598,
    "preview": "let Selector = require('../selector')\nlet utils = require('../utils')\n\nclass FileSelectorButton extends Selector {\n  con"
  },
  {
    "path": "lib/hacks/filter-value.js",
    "chars": 283,
    "preview": "let Value = require('../value')\n\nclass FilterValue extends Value {\n  constructor(name, prefixes) {\n    super(name, prefi"
  },
  {
    "path": "lib/hacks/filter.js",
    "chars": 386,
    "preview": "let Declaration = require('../declaration')\n\nclass Filter extends Declaration {\n  /**\n   * Check is it Internet Explorer"
  },
  {
    "path": "lib/hacks/flex-basis.js",
    "chars": 808,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass FlexBasis extends Declaration {"
  },
  {
    "path": "lib/hacks/flex-direction.js",
    "chars": 1791,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass FlexDirection extends Declarati"
  },
  {
    "path": "lib/hacks/flex-flow.js",
    "chars": 1455,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass FlexFlow extends Declaration {\n"
  },
  {
    "path": "lib/hacks/flex-grow.js",
    "chars": 595,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass Flex extends Declaration {\n  /*"
  },
  {
    "path": "lib/hacks/flex-shrink.js",
    "chars": 801,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass FlexShrink extends Declaration "
  },
  {
    "path": "lib/hacks/flex-spec.js",
    "chars": 375,
    "preview": "/**\n * Return flexbox spec versions by prefix\n */\nmodule.exports = function (prefix) {\n  let spec\n  if (prefix === '-web"
  },
  {
    "path": "lib/hacks/flex-wrap.js",
    "chars": 379,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass FlexWrap extends Declaration {\n"
  },
  {
    "path": "lib/hacks/flex.js",
    "chars": 1170,
    "preview": "let list = require('postcss').list\n\nlet Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nc"
  },
  {
    "path": "lib/hacks/fullscreen.js",
    "chars": 406,
    "preview": "let Selector = require('../selector')\n\nclass Fullscreen extends Selector {\n  /**\n   * Return different selectors depend "
  },
  {
    "path": "lib/hacks/gradient.js",
    "chars": 10674,
    "preview": "let parser = require('postcss-value-parser')\n\nlet OldValue = require('../old-value')\nlet utils = require('../utils')\nlet"
  },
  {
    "path": "lib/hacks/grid-area.js",
    "chars": 891,
    "preview": "let Declaration = require('../declaration')\nlet utils = require('./grid-utils')\n\nclass GridArea extends Declaration {\n  "
  },
  {
    "path": "lib/hacks/grid-column-align.js",
    "chars": 513,
    "preview": "let Declaration = require('../declaration')\n\nclass GridColumnAlign extends Declaration {\n  /**\n   * Do not prefix flexbo"
  },
  {
    "path": "lib/hacks/grid-end.js",
    "chars": 1282,
    "preview": "let Declaration = require('../declaration')\nlet { isPureNumber } = require('../utils')\n\nclass GridEnd extends Declaratio"
  },
  {
    "path": "lib/hacks/grid-row-align.js",
    "chars": 496,
    "preview": "let Declaration = require('../declaration')\n\nclass GridRowAlign extends Declaration {\n  /**\n   * Do not prefix flexbox v"
  },
  {
    "path": "lib/hacks/grid-row-column.js",
    "chars": 825,
    "preview": "let Declaration = require('../declaration')\nlet utils = require('./grid-utils')\n\nclass GridRowColumn extends Declaration"
  },
  {
    "path": "lib/hacks/grid-rows-columns.js",
    "chars": 3068,
    "preview": "let Declaration = require('../declaration')\nlet Processor = require('../processor')\nlet {\n  autoplaceGridItems,\n  getGri"
  },
  {
    "path": "lib/hacks/grid-start.js",
    "chars": 670,
    "preview": "let Declaration = require('../declaration')\n\nclass GridStart extends Declaration {\n  /**\n   * Do not add prefix for unsu"
  },
  {
    "path": "lib/hacks/grid-template-areas.js",
    "chars": 1900,
    "preview": "let Declaration = require('../declaration')\nlet {\n  getGridGap,\n  inheritGridGap,\n  parseGridAreas,\n  prefixTrackProp,\n "
  },
  {
    "path": "lib/hacks/grid-template.js",
    "chars": 1442,
    "preview": "let Declaration = require('../declaration')\nlet {\n  getGridGap,\n  inheritGridGap,\n  parseTemplate,\n  warnGridGap,\n  warn"
  },
  {
    "path": "lib/hacks/grid-utils.js",
    "chars": 29231,
    "preview": "let parser = require('postcss-value-parser')\nlet list = require('postcss').list\n\nlet uniq = require('../utils').uniq\nlet"
  },
  {
    "path": "lib/hacks/image-rendering.js",
    "chars": 913,
    "preview": "let Declaration = require('../declaration')\n\nclass ImageRendering extends Declaration {\n  /**\n   * Add hack only for cri"
  },
  {
    "path": "lib/hacks/image-set.js",
    "chars": 395,
    "preview": "let Value = require('../value')\n\nclass ImageSet extends Value {\n  /**\n   * Use non-standard name for WebKit and Firefox\n"
  },
  {
    "path": "lib/hacks/inline-logical.js",
    "chars": 681,
    "preview": "let Declaration = require('../declaration')\n\nclass InlineLogical extends Declaration {\n  /**\n   * Return property name b"
  },
  {
    "path": "lib/hacks/intrinsic.js",
    "chars": 1396,
    "preview": "let OldValue = require('../old-value')\nlet Value = require('../value')\n\nfunction regexp(name) {\n  return new RegExp(`(^|"
  },
  {
    "path": "lib/hacks/justify-content.js",
    "chars": 1236,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass JustifyContent extends Declarat"
  },
  {
    "path": "lib/hacks/mask-border.js",
    "chars": 790,
    "preview": "let Declaration = require('../declaration')\n\nclass MaskBorder extends Declaration {\n  /**\n   * Return property name by f"
  },
  {
    "path": "lib/hacks/mask-composite.js",
    "chars": 2109,
    "preview": "let Declaration = require('../declaration')\n\nclass MaskComposite extends Declaration {\n  /**\n   * Prefix mask-composite "
  },
  {
    "path": "lib/hacks/order.js",
    "chars": 907,
    "preview": "let Declaration = require('../declaration')\nlet flexSpec = require('./flex-spec')\n\nclass Order extends Declaration {\n  /"
  },
  {
    "path": "lib/hacks/overscroll-behavior.js",
    "chars": 677,
    "preview": "let Declaration = require('../declaration')\n\nclass OverscrollBehavior extends Declaration {\n  /**\n   * Return property n"
  },
  {
    "path": "lib/hacks/pixelated.js",
    "chars": 819,
    "preview": "let OldValue = require('../old-value')\nlet Value = require('../value')\n\nclass Pixelated extends Value {\n  /**\n   * Diffe"
  },
  {
    "path": "lib/hacks/place-self.js",
    "chars": 830,
    "preview": "let Declaration = require('../declaration')\nlet utils = require('./grid-utils')\n\nclass PlaceSelf extends Declaration {\n "
  },
  {
    "path": "lib/hacks/placeholder-shown.js",
    "chars": 437,
    "preview": "let Selector = require('../selector')\n\nclass PlaceholderShown extends Selector {\n  /**\n   * Return different selectors d"
  },
  {
    "path": "lib/hacks/placeholder.js",
    "chars": 711,
    "preview": "let Selector = require('../selector')\n\nclass Placeholder extends Selector {\n  /**\n   * Add old mozilla to possible prefi"
  },
  {
    "path": "lib/hacks/print-color-adjust.js",
    "chars": 506,
    "preview": "let Declaration = require('../declaration')\n\nclass PrintColorAdjust extends Declaration {\n  /**\n   * Return property nam"
  },
  {
    "path": "lib/hacks/text-decoration-skip-ink.js",
    "chars": 524,
    "preview": "let Declaration = require('../declaration')\n\nclass TextDecorationSkipInk extends Declaration {\n  /**\n   * Change prefix "
  },
  {
    "path": "lib/hacks/text-decoration.js",
    "chars": 430,
    "preview": "let Declaration = require('../declaration')\n\nconst BASIC = [\n  'none',\n  'underline',\n  'overline',\n  'line-through',\n  "
  },
  {
    "path": "lib/hacks/text-emphasis-position.js",
    "chars": 357,
    "preview": "let Declaration = require('../declaration')\n\nclass TextEmphasisPosition extends Declaration {\n  set(decl, prefix) {\n    "
  },
  {
    "path": "lib/hacks/transform-decl.js",
    "chars": 1614,
    "preview": "let Declaration = require('../declaration')\n\nclass TransformDecl extends Declaration {\n  /**\n   * Is transform contain 3"
  },
  {
    "path": "lib/hacks/user-select.js",
    "chars": 711,
    "preview": "let Declaration = require('../declaration')\n\nclass UserSelect extends Declaration {\n  /**\n   * Avoid prefixing all in IE"
  },
  {
    "path": "lib/hacks/writing-mode.js",
    "chars": 1002,
    "preview": "let Declaration = require('../declaration')\n\nclass WritingMode extends Declaration {\n  insert(decl, prefix, prefixes) {\n"
  },
  {
    "path": "lib/info.js",
    "chars": 3165,
    "preview": "let browserslist = require('browserslist')\n\nfunction capitalize(str) {\n  return str.slice(0, 1).toUpperCase() + str.slic"
  },
  {
    "path": "lib/old-selector.js",
    "chars": 1389,
    "preview": "class OldSelector {\n  constructor(selector, prefix) {\n    this.prefix = prefix\n    this.prefixed = selector.prefixed(thi"
  },
  {
    "path": "lib/old-value.js",
    "chars": 463,
    "preview": "let utils = require('./utils')\n\nclass OldValue {\n  constructor(unprefixed, prefixed, string, regexp) {\n    this.unprefix"
  },
  {
    "path": "lib/prefixer.js",
    "chars": 3127,
    "preview": "let Browsers = require('./browsers')\nlet utils = require('./utils')\nlet vendor = require('./vendor')\n\n/**\n * Recursively"
  },
  {
    "path": "lib/prefixes.js",
    "chars": 13100,
    "preview": "let AtRule = require('./at-rule')\nlet Browsers = require('./browsers')\nlet Declaration = require('./declaration')\nlet ha"
  },
  {
    "path": "lib/processor.js",
    "chars": 21543,
    "preview": "let parser = require('postcss-value-parser')\n\nlet Value = require('./value')\nlet insertAreas = require('./hacks/grid-uti"
  },
  {
    "path": "lib/resolution.js",
    "chars": 2308,
    "preview": "let FractionJs = require('fraction.js')\n\nlet Prefixer = require('./prefixer')\nlet utils = require('./utils')\n\nconst REGE"
  },
  {
    "path": "lib/selector.js",
    "chars": 3221,
    "preview": "let { list } = require('postcss')\n\nlet Browsers = require('./browsers')\nlet OldSelector = require('./old-selector')\nlet "
  },
  {
    "path": "lib/supports.js",
    "chars": 6388,
    "preview": "let featureQueries = require('caniuse-lite/data/features/css-featurequeries.js')\nlet feature = require('caniuse-lite/dis"
  },
  {
    "path": "lib/transition.js",
    "chars": 8186,
    "preview": "let { list } = require('postcss')\nlet parser = require('postcss-value-parser')\n\nlet Browsers = require('./browsers')\nlet"
  },
  {
    "path": "lib/utils.js",
    "chars": 2019,
    "preview": "let { list } = require('postcss')\n\n/**\n * Throw special error, to tell beniary,\n * that this error is from Autoprefixer."
  },
  {
    "path": "lib/value.js",
    "chars": 2574,
    "preview": "let OldValue = require('./old-value')\nlet Prefixer = require('./prefixer')\nlet utils = require('./utils')\nlet vendor = r"
  },
  {
    "path": "lib/vendor.js",
    "chars": 206,
    "preview": "module.exports = {\n  prefix(prop) {\n    let match = prop.match(/^(-\\w+-)/)\n    if (match) {\n      return match[0]\n    }\n"
  },
  {
    "path": "package.json",
    "chars": 2274,
    "preview": "{\n  \"name\": \"autoprefixer\",\n  \"version\": \"10.4.27\",\n  \"description\": \"Parse CSS and add vendor prefixes to CSS rules usi"
  },
  {
    "path": "patches/yargs@17.7.2.patch",
    "chars": 694,
    "preview": "diff --git a/browser.d.ts b/browser.d.ts\ndeleted file mode 100644\nindex 21f3fc69190b574ab8456514d3da1972afa53973..000000"
  },
  {
    "path": "test/at-rule.test.js",
    "chars": 528,
    "preview": "let { parse } = require('postcss')\nlet { test } = require('uvu')\nlet { equal } = require('uvu/assert')\n\nlet AtRule = req"
  },
  {
    "path": "test/autoprefixer.test.js",
    "chars": 34686,
    "preview": "let { readFileSync } = require('fs')\nlet { restoreAll, spyOn } = require('nanospy')\nlet { join } = require('path')\nlet p"
  },
  {
    "path": "test/brackets.test.js",
    "chars": 812,
    "preview": "let { test } = require('uvu')\nlet { equal } = require('uvu/assert')\n\nlet brackets = require('../lib/brackets')\n\ntest('pa"
  },
  {
    "path": "test/browsers.test.js",
    "chars": 2008,
    "preview": "let { agents } = require('caniuse-lite/dist/unpacker/agents')\nlet { join } = require('path')\nlet { test } = require('uvu"
  },
  {
    "path": "test/cases/3d-transform.css",
    "chars": 225,
    "preview": "a {\n  transition: transform 1s;\n  transform: rotateX(45deg);\n}\nb {\n  transform: translateX(45deg);\n  transform-origin: 0"
  },
  {
    "path": "test/cases/3d-transform.out.css",
    "chars": 649,
    "preview": "a {\n  -o-transition: -o-transform 1s;\n  transition: transform 1s;\n  transition: transform 1s, -o-transform 1s;\n  transfo"
  },
  {
    "path": "test/cases/advanced-filter.css",
    "chars": 174,
    "preview": "div {\n  backdrop-filter: blur(2px);\n}\n\ndiv {\n  background: filter(url('image.jpg'), blur(2px));\n}\n\ndiv {\n  background: u"
  },
  {
    "path": "test/cases/advanced-filter.out.css",
    "chars": 354,
    "preview": "div {\n  -webkit-backdrop-filter: blur(2px);\n          backdrop-filter: blur(2px);\n}\n\ndiv {\n  background: -webkit-filter("
  },
  {
    "path": "test/cases/animation.css",
    "chars": 216,
    "preview": "a {\n  animation-direction: alternate;\n  animation-direction: reverse;\n  animation-direction: REVERSE;\n  animation-direct"
  },
  {
    "path": "test/cases/animation.out.css",
    "chars": 394,
    "preview": "a {\n  -webkit-animation-direction: alternate;\n       -o-animation-direction: alternate;\n          animation-direction: a"
  },
  {
    "path": "test/cases/appearance.css",
    "chars": 53,
    "preview": "a {\n  appearance: none;\n}\n\nb {\n  appearance: auto;\n}\n"
  },
  {
    "path": "test/cases/appearance.out.css",
    "chars": 181,
    "preview": "a {\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none;\n}\n\nb {\n  -webkit-appearance: aut"
  },
  {
    "path": "test/cases/at-rules.css",
    "chars": 336,
    "preview": "body {\n  appearance: none;\n}\n\n.block {\n  transform: translate(20px, 30px);\n}\n\n@-webkit-region .region {\n  .block {\n    t"
  },
  {
    "path": "test/cases/at-rules.out.css",
    "chars": 576,
    "preview": "body {\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none;\n}\n\n.block {\n  -webkit-transfo"
  },
  {
    "path": "test/cases/autofill.css",
    "chars": 44,
    "preview": "input:autofill {\n  background-color: red;\n}\n"
  },
  {
    "path": "test/cases/autofill.out.css",
    "chars": 97,
    "preview": "input:-webkit-autofill {\n  background-color: red;\n}\n\ninput:autofill {\n  background-color: red;\n}\n"
  },
  {
    "path": "test/cases/backdrop-filter.css",
    "chars": 36,
    "preview": "a {\n  backdrop-filter: blur(2px);\n}\n"
  },
  {
    "path": "test/cases/backdrop-filter.out.css",
    "chars": 82,
    "preview": "a {\n  -webkit-backdrop-filter: blur(2px);\n          backdrop-filter: blur(2px);\n}\n"
  },
  {
    "path": "test/cases/backdrop.css",
    "chars": 31,
    "preview": "::backdrop {\n  color: green;\n}\n"
  },
  {
    "path": "test/cases/backdrop.out.css",
    "chars": 66,
    "preview": "::-ms-backdrop {\n  color: green;\n}\n::backdrop {\n  color: green;\n}\n"
  },
  {
    "path": "test/cases/background-clip.css",
    "chars": 70,
    "preview": "a {\n  background-clip: text;\n}\n\nb {\n  background-clip: content-box;\n}\n"
  },
  {
    "path": "test/cases/background-clip.out.css",
    "chars": 111,
    "preview": "a {\n  -webkit-background-clip: text;\n          background-clip: text;\n}\n\nb {\n  background-clip: content-box;\n}\n"
  },
  {
    "path": "test/cases/background-size.css",
    "chars": 64,
    "preview": "a {\n  background-size: 20px\n}\n\nb {\n  background-size: contain\n}\n"
  },
  {
    "path": "test/cases/background-size.out.css",
    "chars": 223,
    "preview": "a {\n  -webkit-background-size: 20px 20px;\n     -moz-background-size: 20px;\n          background-size: 20px\n}\n\nb {\n  -web"
  },
  {
    "path": "test/cases/border-image.css",
    "chars": 78,
    "preview": "a {\n  border-image: linear-gradient(black, white) 20% fill stretch stretch;\n}\n"
  },
  {
    "path": "test/cases/border-image.out.css",
    "chars": 237,
    "preview": "a {\n  -o-border-image: -o-linear-gradient(black, white) 20% stretch stretch;\n     border-image: -webkit-linear-gradient("
  },
  {
    "path": "test/cases/border-radius.css",
    "chars": 94,
    "preview": "a {\n  border-radius: 5px;\n  border-top-left-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n"
  },
  {
    "path": "test/cases/border-radius.out.css",
    "chars": 340,
    "preview": "a {\n  -webkit-border-radius: 5px;\n     -moz-border-radius: 5px;\n          border-radius: 5px;\n  -webkit-border-top-left-"
  },
  {
    "path": "test/cases/cascade.css",
    "chars": 60,
    "preview": "a {\n  flex-direction: row;\n  mask: none\n}\n\nb { mask: none }\n"
  },
  {
    "path": "test/cases/cascade.out.css",
    "chars": 314,
    "preview": "a {\n  -webkit-box-orient: horizontal;\n  -webkit-box-direction: normal;\n  -webkit-flex-direction: row;\n     -moz-box-orie"
  },
  {
    "path": "test/cases/check-down.css",
    "chars": 52,
    "preview": "* {\n  transition: all 1s;\n  -o-transition: all 1s\n}\n"
  },
  {
    "path": "test/cases/check-down.out.css",
    "chars": 82,
    "preview": "* {\n  -webkit-transition: all 1s;\n  transition: all 1s;\n  -o-transition: all 1s\n}\n"
  },
  {
    "path": "test/cases/comments.css",
    "chars": 173,
    "preview": "a {\n  /* transition */\n  transition: all 1s;\n  height: calc(/* comment before */100% - /* comment inside */ 10px/* comme"
  },
  {
    "path": "test/cases/comments.out.css",
    "chars": 357,
    "preview": "a {\n  /* transition */\n  -webkit-transition: all 1s;\n  -o-transition: all 1s;\n  transition: all 1s;\n  height: -webkit-ca"
  },
  {
    "path": "test/cases/config/browserslist",
    "chars": 31,
    "preview": "ie 10\n\n[development]\nchrome 25\n"
  },
  {
    "path": "test/cases/config/test.css",
    "chars": 23,
    "preview": "a {\n  display: flex;\n}\n"
  },
  {
    "path": "test/cases/config/test.out.css",
    "chars": 47,
    "preview": "a {\n  display: -ms-flexbox;\n  display: flex;\n}\n"
  },
  {
    "path": "test/cases/config/test.production.css",
    "chars": 48,
    "preview": "a {\n  display: -webkit-flex;\n  display: flex;\n}\n"
  },
  {
    "path": "test/cases/content.css",
    "chars": 90,
    "preview": "a {\n  content: \"Element 'div' not allowed as child of element 'span' in this context.\";\n}\n"
  },
  {
    "path": "test/cases/cross-fade.css",
    "chars": 489,
    "preview": "a {\n  background-image: cross-fade(20% url(foo.png), url(bar.png));\n}\n\nb {\n  background-image: cross-fade(url(foo.png), "
  },
  {
    "path": "test/cases/cross-fade.out.css",
    "chars": 989,
    "preview": "a {\n  background-image: -webkit-cross-fade(url(foo.png), url(bar.png), 20%);\n  background-image: cross-fade(20% url(foo."
  },
  {
    "path": "test/cases/custom-prefix.css",
    "chars": 34,
    "preview": "a {\n  -evil-up: calc(10px + 1);\n}\n"
  },
  {
    "path": "test/cases/custom-prefix.out.css",
    "chars": 70,
    "preview": "a {\n  -evil-up: -webkit-calc(10px + 1);\n  -evil-up: calc(10px + 1);\n}\n"
  },
  {
    "path": "test/cases/disabled.css",
    "chars": 692,
    "preview": "a {\n  -webkit-border-radius: 4px;\n          border-radius: 4px;\n  mask: none;\n}\n\nb {\n  /* autoprefixer: off */\n  -webkit"
  },
  {
    "path": "test/cases/disabled.out.css",
    "chars": 810,
    "preview": "a {\n  border-radius: 4px;\n  -webkit-mask: none;\n          mask: none;\n}\n\nb {\n  /* autoprefixer: off */\n  -webkit-border-"
  },
  {
    "path": "test/cases/double.css",
    "chars": 64,
    "preview": "a {\n  flex-basis: 8.33333%;\n  flex-basis: calc(100% / 12 * 1)\n}\n"
  },
  {
    "path": "test/cases/double.out.css",
    "chars": 256,
    "preview": "a {\n  -webkit-flex-basis: 8.33333%;\n      -ms-flex-preferred-size: 8.33333%;\n          flex-basis: 8.33333%;\n  -webkit-f"
  },
  {
    "path": "test/cases/element.css",
    "chars": 89,
    "preview": "div {\n  background: element(#id);\n}\n\ndiv {\n  background: url(image.jpg), element(#id);\n}\n"
  },
  {
    "path": "test/cases/element.out.css",
    "chars": 171,
    "preview": "div {\n  background: -moz-element(#id);\n  background: element(#id);\n}\n\ndiv {\n  background: url(image.jpg), -moz-element(#"
  },
  {
    "path": "test/cases/example.css",
    "chars": 63,
    "preview": "::placeholder {\n  color: gray;\n}\n\n.image {\n  width: stretch;\n}\n"
  },
  {
    "path": "test/cases/example.out.css",
    "chars": 160,
    "preview": "::-moz-placeholder {\n  color: gray;\n}\n\n::placeholder {\n  color: gray;\n}\n\n.image {\n  width: -webkit-fill-available;\n  wid"
  },
  {
    "path": "test/cases/file-selector-button.css",
    "chars": 149,
    "preview": "::file-selector-button {\n  background: black\n}\n\ninput::file-selector-button {\n\tcolor: black;\n}\n\ninput:hover::file-select"
  },
  {
    "path": "test/cases/file-selector-button.out.css",
    "chars": 317,
    "preview": "::-webkit-file-upload-button {\n  background: black\n}\n\n::file-selector-button {\n  background: black\n}\n\ninput::-webkit-fil"
  },
  {
    "path": "test/cases/filter.css",
    "chars": 200,
    "preview": "a {\n  filter: blur(10px);\n  transition: filter 2s;\n}\n\ndiv {\n  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50"
  },
  {
    "path": "test/cases/filter.out.css",
    "chars": 356,
    "preview": "a {\n  -webkit-filter: blur(10px);\n          filter: blur(10px);\n  -webkit-transition: -webkit-filter 2s;\n  transition: -"
  },
  {
    "path": "test/cases/flex-rewrite.css",
    "chars": 23,
    "preview": ".a {\n  flex-grow: 0;\n}\n"
  },
  {
    "path": "test/cases/flex-rewrite.out.css",
    "chars": 129,
    "preview": ".a {\n  -webkit-box-flex: 0;\n  -webkit-flex-grow: 0;\n     -moz-box-flex: 0;\n      -ms-flex-positive: 0;\n          flex-gr"
  },
  {
    "path": "test/cases/flexbox.css",
    "chars": 1396,
    "preview": "a {\n  -js-display: flex;\n  display: flex;\n  flex-flow: row;\n  order: 0;\n  flex: 0 1 2;\n  transition: flex 200ms;\n}\n.inli"
  },
  {
    "path": "test/cases/flexbox.out.css",
    "chars": 7422,
    "preview": "a {\n  -js-display: flex;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -ms-flexbox;\n "
  },
  {
    "path": "test/cases/fullscreen.css",
    "chars": 36,
    "preview": ":fullscreen {\n  background: black\n}\n"
  },
  {
    "path": "test/cases/fullscreen.out.css",
    "chars": 81,
    "preview": ":-webkit-full-screen {\n  background: black\n}\n:fullscreen {\n  background: black\n}\n"
  },
  {
    "path": "test/cases/gradient-fix.css",
    "chars": 129,
    "preview": ".test {\n  background-image: -webkit-linear-gradient(yellow 50%, red 50%);\n  background-image: linear-gradient(to   , red"
  },
  {
    "path": "test/cases/gradient-fix.out.css",
    "chars": 283,
    "preview": ".test {\n  background-image: -webkit-linear-gradient(yellow 50%, red 50%);\n  background-image: -webkit-linear-gradient(re"
  },
  {
    "path": "test/cases/gradient.css",
    "chars": 3410,
    "preview": "a {\n  background: linear-gradient(350.5deg, white, black), linear-gradient(-130deg, black, white), linear-gradient(45deg"
  },
  {
    "path": "test/cases/gradient.out.css",
    "chars": 11591,
    "preview": "a {\n  background: -webkit-linear-gradient(99.5deg, white, black), -webkit-linear-gradient(220deg, black, white), -webkit"
  },
  {
    "path": "test/cases/grid-area-media-sequence.css",
    "chars": 875,
    "preview": ".grid-template-sequence {\n  display: grid;\n  grid-template:\n      \"foo foo\"\n      \"bar bar\"\n      \"baz baz\"\n      / 1fr "
  },
  {
    "path": "test/cases/grid-area-media-sequence.out.css",
    "chars": 2114,
    "preview": ".grid-template-sequence {\n  display: -ms-grid;\n  display: grid;\n  -ms-grid-rows: auto auto auto;\n  -ms-grid-columns: 1fr"
  },
  {
    "path": "test/cases/grid-area.css",
    "chars": 499,
    "preview": ".a {\n  grid-area: 5 / 1 / span 1 / span 5;\n}\n\n.b {\n  grid-area: span 1 / span 3 / 4 / 4;\n}\n\n.c {\n  grid-area: 2 / 2;\n}\n\n"
  },
  {
    "path": "test/cases/grid-area.out.css",
    "chars": 1123,
    "preview": ".a {\n  -ms-grid-row: 5;\n  -ms-grid-row-span: 1;\n  -ms-grid-column: 1;\n  -ms-grid-column-span: 5;\n  grid-area: 5 / 1 / sp"
  },
  {
    "path": "test/cases/grid-areas-duplicate-complex.css",
    "chars": 3189,
    "preview": "/*******************************\\\n  COMPLEX DUPLICATE AREAS TEST 1\n\\*******************************/\n\n#main > #content {"
  },
  {
    "path": "test/cases/grid-areas-duplicate-complex.out.css",
    "chars": 8346,
    "preview": "/*******************************\\\n  COMPLEX DUPLICATE AREAS TEST 1\n\\*******************************/\n\n#main > #content {"
  },
  {
    "path": "test/cases/grid-autoplacement.css",
    "chars": 1371,
    "preview": "\n.grid-basic {\n  display: grid;\n  grid-template-columns: 1fr 1fr 1fr;\n  grid-template-rows: auto;\n  grid-gap: 30px;\n}\n\n/"
  },
  {
    "path": "test/cases/grid-autoplacement.out.css",
    "chars": 4533,
    "preview": "\n.grid-basic {\n  display: -ms-grid;\n  display: grid;\n  -ms-grid-columns: 1fr 30px 1fr 30px 1fr;\n  grid-template-columns:"
  },
  {
    "path": "test/cases/grid-gap.css",
    "chars": 5731,
    "preview": ".a {\n  grid-gap: 1rem;\n  grid-template-rows: 1fr minmax(100px, 1fr) 2fr;\n  grid-template-columns: repeat(3, 1fr);\n  grid"
  },
  {
    "path": "test/cases/grid-gap.out.css",
    "chars": 9517,
    "preview": ".a {\n  grid-gap: 1rem;\n  -ms-grid-rows: 1fr 1rem minmax(100px, 1fr) 1rem 2fr;\n  grid-template-rows: 1fr minmax(100px, 1f"
  },
  {
    "path": "test/cases/grid-media-rules.css",
    "chars": 294,
    "preview": "@media (min-width: 30em) {\n  .wrapper {\n    display: grid;\n    grid-template-areas: \"a b\";\n  }\n}\n\n@media (min-width: 60e"
  },
  {
    "path": "test/cases/grid-media-rules.out.css",
    "chars": 601,
    "preview": "@media (min-width: 30em) {\n  .wrapper {\n    display: -ms-grid;\n    display: grid;\n    grid-template-areas: \"a b\";\n  }\n}\n"
  },
  {
    "path": "test/cases/grid-options.autoplace.out.css",
    "chars": 3137,
    "preview": "/*****************\\\n  AREAS ALGORITHM\n\\*****************/\n\n.grid-template-areas {\n  display: -ms-grid;\n  display: grid;\n"
  },
  {
    "path": "test/cases/grid-options.css",
    "chars": 1297,
    "preview": "/*****************\\\n  AREAS ALGORITHM\n\\*****************/\n\n.grid-template-areas {\n  display: grid;\n  grid-template-areas"
  },
  {
    "path": "test/cases/grid-options.disabled.out.css",
    "chars": 1297,
    "preview": "/*****************\\\n  AREAS ALGORITHM\n\\*****************/\n\n.grid-template-areas {\n  display: grid;\n  grid-template-areas"
  },
  {
    "path": "test/cases/grid-options.no-autoplace.out.css",
    "chars": 2890,
    "preview": "/*****************\\\n  AREAS ALGORITHM\n\\*****************/\n\n.grid-template-areas {\n  display: -ms-grid;\n  display: grid;\n"
  },
  {
    "path": "test/cases/grid-status.css",
    "chars": 1101,
    "preview": "/* autoprefixer grid: on */\n/* autoprefixer grid: off */\n\n.grid-disabled {\n  /* autoprefixer: off */\n  display: grid;\n  "
  },
  {
    "path": "test/cases/grid-status.out.css",
    "chars": 1610,
    "preview": "/* autoprefixer grid: on */\n/* autoprefixer grid: off */\n\n.grid-disabled {\n  /* autoprefixer: off */\n  display: grid;\n  "
  },
  {
    "path": "test/cases/grid-template-areas.css",
    "chars": 3431,
    "preview": ".a {\n  grid-template-areas:\n      \"head head\"\n      \"nav  main\"\n      \"nav  foot\"\n      \"another\";\n}\n\n@media (max-width:"
  },
  {
    "path": "test/cases/grid-template-areas.out.css",
    "chars": 6200,
    "preview": ".a {\n  grid-template-areas:\n      \"head head\"\n      \"nav  main\"\n      \"nav  foot\"\n      \"another\";\n}\n\n@media (max-width:"
  },
  {
    "path": "test/cases/grid-template.css",
    "chars": 3769,
    "preview": ".a {\n  grid-template: 10px repeat(4, 250px 10px) 20px / auto 1fr;\n}\n\n.b {\n  grid-template:\n      [header-left] \"head hea"
  },
  {
    "path": "test/cases/grid-template.out.css",
    "chars": 9211,
    "preview": ".a {\n  -ms-grid-rows: 10px (250px 10px)[4] 20px;\n  -ms-grid-columns: auto 1fr;\n  grid-template: 10px repeat(4, 250px 10p"
  },
  {
    "path": "test/cases/grid.css",
    "chars": 3439,
    "preview": ".a {\n  display: grid;\n  grid-template-columns: auto 1fr;\n  justify-self: stretch;\n  align-self: stretch;\n  grid-column-s"
  },
  {
    "path": "test/cases/grid.disabled.css",
    "chars": 3620,
    "preview": ".a {\n  display: grid;\n  grid-template-columns: auto 1fr;\n  justify-self: stretch;\n  align-self: stretch;\n  grid-column-s"
  },
  {
    "path": "test/cases/grid.out.css",
    "chars": 5575,
    "preview": ".a {\n  display: -ms-grid;\n  display: grid;\n  -ms-grid-columns: auto 1fr;\n  grid-template-columns: auto 1fr;\n  -ms-grid-c"
  },
  {
    "path": "test/cases/grouping-rule.css",
    "chars": 219,
    "preview": ".grid {\n  display: grid;\n}\n\n.a,\n.b,\n.c::selection,\n.d:read-only,\n.e::placeholder {\n  color: yellow;\n}\n\n::selection {\n  c"
  },
  {
    "path": "test/cases/grouping-rule.out.css",
    "chars": 690,
    "preview": ".grid {\n  display: -ms-grid;\n  display: grid;\n}\n\n.c::-moz-selection {\n  color: yellow;\n}\n\n.e::-webkit-input-placeholder "
  },
  {
    "path": "test/cases/ignore-next.css",
    "chars": 465,
    "preview": ".ignore-property {\n  /* autoprefixer: ignore next */\n  mask: none;\n  background: linear-gradient(to bottom, white, black"
  },
  {
    "path": "test/cases/ignore-next.out.css",
    "chars": 848,
    "preview": ".ignore-property {\n  /* autoprefixer: ignore next */\n  mask: none;\n  background: -webkit-linear-gradient(top, white, bla"
  },
  {
    "path": "test/cases/image-rendering.css",
    "chars": 226,
    "preview": "img {\n  image-rendering: crisp-edges;\n}\n\nimg.other {\n  image-rendering: pixelated;\n}\n\nimg.already {\n  -ms-interpolation-"
  },
  {
    "path": "test/cases/image-rendering.out.css",
    "chars": 518,
    "preview": "img {\n  image-rendering: crisp-edges;\n}\n\nimg.other {\n  -ms-interpolation-mode: nearest-neighbor;\n      image-rendering: "
  },
  {
    "path": "test/cases/image-set.css",
    "chars": 150,
    "preview": "a {\n  background-image: image-set(url(foo@1x.png) 1x, url(foo@2x.png) 2x);\n}\n\nh1 {\n  background-image: image-set('foo@1x"
  },
  {
    "path": "test/cases/image-set.out.css",
    "chars": 312,
    "preview": "a {\n  background-image: -webkit-image-set(url(foo@1x.png) 1x, url(foo@2x.png) 2x);\n  background-image: image-set(url(foo"
  },
  {
    "path": "test/cases/intrinsic.css",
    "chars": 680,
    "preview": "a {\n  width: stretch;\n}\n\nb {\n  height: max-content;\n}\n\np {\n  block-size: min-content;\n  min-inline-size: fit-content;\n}\n"
  },
  {
    "path": "test/cases/intrinsic.ff.css",
    "chars": 742,
    "preview": "a {\n  width: -moz-available;\n  width: stretch;\n}\n\nb {\n  height: max-content;\n}\n\np {\n  block-size: min-content;\n  min-inl"
  },
  {
    "path": "test/cases/intrinsic.out.css",
    "chars": 1510,
    "preview": "a {\n  width: -webkit-fill-available;\n  width: -moz-available;\n  width: stretch;\n}\n\nb {\n  height: -webkit-max-content;\n  "
  },
  {
    "path": "test/cases/keyframes.css",
    "chars": 292,
    "preview": "@keyframes anim {\n  from {\n    top: calc(10% + 10px);\n    transform: rotate(10deg)\n  }\n  50% {\n    top: 0;\n    display: "
  },
  {
    "path": "test/cases/keyframes.out.css",
    "chars": 1421,
    "preview": "@-webkit-keyframes anim {\n  from {\n    top: -webkit-calc(10% + 10px);\n    top: calc(10% + 10px);\n    -webkit-transform: "
  },
  {
    "path": "test/cases/logical.css",
    "chars": 152,
    "preview": "a {\n  margin-block-start: 1px;\n  margin-inline-start: 1px;\n  padding-inline-end: 1px;\n}\n\n.border {\n  border-block-end: 1"
  },
  {
    "path": "test/cases/logical.out.css",
    "chars": 419,
    "preview": "a {\n  -webkit-margin-before: 1px;\n          margin-block-start: 1px;\n  -webkit-margin-start: 1px;\n     -moz-margin-start"
  },
  {
    "path": "test/cases/mask-border.css",
    "chars": 206,
    "preview": "a {\n  mask-border-source: url(image.png);\n  mask-border-slice: 50% fill;\n  mask-border-width: auto 1 50%;\n  mask-border-"
  }
]

// ... and 68 more files (download for full content)

About this extraction

This page contains the full source code of the postcss/autoprefixer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 268 files (485.9 KB), approximately 148.8k tokens, and a symbol index with 398 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!