postcss-sort-media-queries 6.4.4 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # PostCSS Sort Media Queries
2
2
 
3
- [PostCSS]: https://github.com/postcss/postcss
4
- [official docs]: https://github.com/postcss/postcss#usage
5
- [Online Demo]: https://yunusga.uz/postcss-sort-media-queries/
6
- [MIT]: https://github.com/yunusga/postcss-sort-media-queries/blob/master/LICENSE
3
+ [PostCSS]: https://github.com/postcss/postcss
4
+ [official docs]: https://github.com/postcss/postcss#usage
5
+ [Online Demo]: https://yunusga.uz/postcss-sort-media-queries/
6
+ [MIT]: https://github.com/yunusga/postcss-sort-media-queries/blob/master/LICENSE
7
7
  [Releases history]: https://github.com/yunusga/postcss-sort-media-queries/blob/master/CHANGELOG.md
8
8
 
9
9
  [![npm](https://img.shields.io/npm/v/postcss-sort-media-queries.svg)](https://www.npmjs.com/package/postcss-sort-media-queries) [![Node.js CI](https://github.com/yunusga/postcss-sort-media-queries/actions/workflows/test.yml/badge.svg?branch=main&event=status)](https://github.com/yunusga/postcss-sort-media-queries/actions/workflows/test.yml)
@@ -12,7 +12,7 @@
12
12
 
13
13
  <img src="logo.svg?sanitize=true" align="right" title="PostCSS sort media queries logotype" width="100" height="100">
14
14
 
15
- 🌏 **English** ▫ [**O'zbek**](README-UZ.md)
15
+ 🌏 **English** ▫ [**O'zbek**](README-UZ.md) ▫ [**简体中文**](README-ZH.md)
16
16
 
17
17
  **PostcSS Sort Qedia Queries** is a powerful and flexible [PostCSS] plugin for sorting and combining CSS media queries using **mobile-first** or **desktop-first** methodologies. It helps maintain a clean, predictable stylesheet structure, improves readability, and prevents unexpected style overrides.
18
18
 
@@ -24,24 +24,23 @@ Sorting works based on [OlehDutchenko/sort-css-media-queries](https://github.com
24
24
 
25
25
  ## Table of Contents
26
26
 
27
- - [Install](#install)
28
- - [Usage](#usage)
29
- - [Options](#options)
30
- - [sort](#sort)
31
- - [Custom sort function](#custom-sort-function)
32
- - [Sort configuration](#sort-configuration)
33
- - [Online demo](#online-demo)
34
- - [Examples (with nested media queries)](#examples)
35
- - [Sorting options](#mobile-first-sorting)
36
- - [Desktop first sorting](#desktop-first-sorting)
37
- - [Changelog](#changelog)
38
- - [License](#license)
39
- - [Other PostCSS plugins](#other-postcss-plugins)
40
- - [Thanks 💪](#thanks)
27
+ - [Install](#install)
28
+ - [Usage](#usage)
29
+ - [Options](#options)
30
+ - [sort](#sort)
31
+ - [Custom sort function](#custom-sort-function)
32
+ - [Sort configuration](#sort-configuration)
33
+ - [Online demo](#online-demo)
34
+ - [Examples (with nested media queries)](#examples)
35
+ - [Sorting options](#mobile-first-sorting)
36
+ - [Desktop first sorting](#desktop-first-sorting)
37
+ - [Changelog](#changelog)
38
+ - [License](#license)
39
+ - [Other PostCSS plugins](#other-postcss-plugins)
40
+ - [Thanks 💪](#thanks)
41
41
 
42
42
  ## Install
43
43
 
44
-
45
44
  ```
46
45
  npm install postcss postcss-sort-media-queries --save-dev
47
46
  ```
@@ -52,13 +51,12 @@ Check you project for existed PostCSS config: `postcss.config.js`
52
51
  in the project root, `"postcss"` section in `package.json`
53
52
  or `postcss` in bundle config.
54
53
 
55
-
56
54
  ```js
57
55
  // CJS
58
- let sortCssMq = require('postcss-sort-media-queries');
56
+ let sortCssMq = require("postcss-sort-media-queries");
59
57
 
60
58
  // ESM
61
- import sortCssMq from 'postcss-sort-media-queries';
59
+ import sortCssMq from "postcss-sort-media-queries";
62
60
  ```
63
61
 
64
62
  If you already use PostCSS, add the plugin to plugins list:
@@ -74,6 +72,7 @@ module.exports = {
74
72
  ```
75
73
 
76
74
  or with custom sort function
75
+
77
76
  ```diff
78
77
  module.exports = {
79
78
  plugins: [
@@ -106,18 +105,20 @@ This option support **string** or **function** values.
106
105
  ```js
107
106
  postcss([
108
107
  sortMediaQueries({
109
- sort: 'mobile-first' | 'desktop-first' // default (mobile-first)
110
- })
108
+ sort: "mobile-first" | "desktop-first", // default (mobile-first)
109
+ }),
111
110
  ]).process(css);
112
111
  ```
112
+
113
113
  ### Custom sort function
114
+
114
115
  ```js
115
116
  postcss([
116
117
  sortMediaQueries({
117
118
  function(a, b) {
118
119
  return a.localeCompare(b);
119
- }
120
- })
120
+ },
121
+ }),
121
122
  ]).process(css);
122
123
  ```
123
124
 
@@ -134,8 +135,8 @@ postcss([
134
135
  sortMediaQueries({
135
136
  configuration: {
136
137
  unitlessMqAlwaysFirst: true, // or false
137
- }
138
- })
138
+ },
139
+ }),
139
140
  ]).process(css);
140
141
  ```
141
142
 
@@ -190,6 +191,7 @@ root
190
191
  ### Desktop first sorting
191
192
 
192
193
  **Before**
194
+
193
195
  ```css
194
196
  root
195
197
 
@@ -237,3 +239,4 @@ See [Releases history]
237
239
  - Khayot Razzakov [@Khayotbek1](https://github.com/Khayotbek1)
238
240
  - ReindDooyeweerd [@ReindDooyeweerd](https://github.com/ReindDooyeweerd)
239
241
  - msev [@msev](https://github.com/msev)
242
+ - ajiho [@ajiho](https://github.com/ajiho)
@@ -234,36 +234,6 @@ function createSort(configuration) {
234
234
  return sortCSSmq;
235
235
  }
236
236
 
237
- // node_modules/nanoid/index.js
238
- var import_node_crypto = require("node:crypto");
239
-
240
- // node_modules/nanoid/url-alphabet/index.js
241
- var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
242
-
243
- // node_modules/nanoid/index.js
244
- var POOL_SIZE_MULTIPLIER = 128;
245
- var pool;
246
- var poolOffset;
247
- function fillPool(bytes) {
248
- if (!pool || pool.length < bytes) {
249
- pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
250
- import_node_crypto.webcrypto.getRandomValues(pool);
251
- poolOffset = 0;
252
- } else if (poolOffset + bytes > pool.length) {
253
- import_node_crypto.webcrypto.getRandomValues(pool);
254
- poolOffset = 0;
255
- }
256
- poolOffset += bytes;
257
- }
258
- function nanoid(size = 21) {
259
- fillPool(size |= 0);
260
- let id = "";
261
- for (let i = poolOffset - size; i < poolOffset; i++) {
262
- id += urlAlphabet[pool[i] & 63];
263
- }
264
- return id;
265
- }
266
-
267
237
  // src/index.js
268
238
  function sortAtRules(queries, options, sortCSSmq) {
269
239
  if (typeof options.sort !== "function") {
@@ -291,28 +261,22 @@ function plugin(options = {}) {
291
261
  postcssPlugin: "postcss-sort-media-queries",
292
262
  // Execute once after the entire tree has been parsed
293
263
  OnceExit(root, { AtRule }) {
294
- let parents = [];
264
+ const parents = /* @__PURE__ */ new Map();
295
265
  root.walkAtRules("media", (atRule) => {
296
- if (!atRule.parent.groupId) {
297
- let groupId = nanoid();
298
- atRule.parent.groupId = groupId;
299
- parents[groupId] = {
266
+ if (!parents.has(atRule.parent)) {
267
+ parents.set(atRule.parent, {
300
268
  parent: atRule.parent,
301
269
  depth: getDepth(atRule.parent)
302
- };
270
+ });
303
271
  }
304
- return;
305
272
  });
306
- if (!parents) {
273
+ if (parents.size === 0) {
307
274
  return;
308
275
  }
309
- parents = Object.fromEntries(
310
- Object.entries(parents).sort(([, a], [, b]) => {
311
- return b.depth - a.depth;
312
- })
313
- );
314
- Object.keys(parents).forEach((groupId) => {
315
- let { parent } = parents[groupId];
276
+ const sortedParents = [...parents.values()].sort((a, b) => {
277
+ return b.depth - a.depth;
278
+ });
279
+ sortedParents.forEach(({ parent }) => {
316
280
  let medias = parent.nodes.filter(
317
281
  (node) => node.type === "atrule" && node.name === "media"
318
282
  );
@@ -334,9 +298,11 @@ function plugin(options = {}) {
334
298
  atRule.remove();
335
299
  });
336
300
  if (atRules) {
337
- sortAtRules(Object.keys(atRules), options, sortCSSmq).forEach((query) => {
338
- parent.append(atRules[query]);
339
- });
301
+ sortAtRules(Object.keys(atRules), options, sortCSSmq).forEach(
302
+ (query) => {
303
+ parent.append(atRules[query]);
304
+ }
305
+ );
340
306
  }
341
307
  });
342
308
  root.walkAtRules("media", (parent) => {
@@ -0,0 +1,17 @@
1
+ import { Plugin } from "postcss";
2
+
3
+ type SortOption =
4
+ | "mobile-first"
5
+ | "desktop-first"
6
+ | ((a: string, b: string) => number);
7
+
8
+ interface Options {
9
+ sort?: SortOption;
10
+ configuration?: {
11
+ unitlessMqAlwaysFirst?: boolean;
12
+ };
13
+ }
14
+
15
+ declare const plugin: (options?: Options) => Plugin;
16
+
17
+ export default plugin;
package/dist/index.js ADDED
@@ -0,0 +1,128 @@
1
+ import createSort from "sort-css-media-queries/create-sort";
2
+
3
+ // PostCSS plugin to sort CSS @media rules according to a configurable order.
4
+ // The plugin groups top-level and nested media at-rules, merges rules
5
+ // with identical queries, and re-inserts them in the desired order.
6
+
7
+ // Helper that ensures `options.sort` is a function and sorts queries.
8
+ function sortAtRules(queries, options, sortCSSmq) {
9
+ if (typeof options.sort !== "function") {
10
+ options.sort =
11
+ options.sort === "desktop-first" ? sortCSSmq.desktopFirst : sortCSSmq;
12
+ }
13
+
14
+ return queries.sort(options.sort);
15
+ }
16
+
17
+ function getDepth(node) {
18
+ let depth = 0;
19
+
20
+ for (let p = node.parent; p; p = p.parent) {
21
+ depth++;
22
+ }
23
+
24
+ return depth;
25
+ }
26
+
27
+ function plugin(options = {}) {
28
+ // Set default options and allow user overrides
29
+ options = Object.assign(
30
+ {
31
+ sort: "mobile-first",
32
+ configuration: false,
33
+ },
34
+ options,
35
+ );
36
+
37
+ // Create a sorter based on configuration (from sort-css-media-queries)
38
+ const sortCSSmq = createSort(options.configuration);
39
+
40
+ return {
41
+ postcssPlugin: "postcss-sort-media-queries",
42
+
43
+ // Execute once after the entire tree has been parsed
44
+ OnceExit(root, { AtRule }) {
45
+ // Collect parent nodes that contain media at-rules. We separate
46
+ // top-level (`root`) parents from nested parents so ordering
47
+ // semantics can be preserved independently.
48
+ const parents = new Map();
49
+
50
+ // Walk all @media at-rules and group their parents
51
+ root.walkAtRules("media", (atRule) => {
52
+ if (!parents.has(atRule.parent)) {
53
+ parents.set(atRule.parent, {
54
+ parent: atRule.parent,
55
+ depth: getDepth(atRule.parent),
56
+ });
57
+ }
58
+ });
59
+
60
+ if (parents.size === 0) {
61
+ return;
62
+ }
63
+
64
+ const sortedParents = [...parents.values()].sort((a, b) => {
65
+ return b.depth - a.depth;
66
+ });
67
+
68
+ sortedParents.forEach(({ parent }) => {
69
+ // Filter only @media nodes from the parent's children
70
+ let medias = parent.nodes.filter(
71
+ (node) => node.type === "atrule" && node.name === "media",
72
+ );
73
+
74
+ if (!medias) {
75
+ return;
76
+ }
77
+
78
+ let atRules = [];
79
+
80
+ medias.forEach((atRule) => {
81
+ if (!atRules[atRule.params]) {
82
+ atRules[atRule.params] = new AtRule({
83
+ name: atRule.name,
84
+ params: atRule.params,
85
+ source: atRule.source,
86
+ });
87
+ }
88
+
89
+ [...atRule.nodes].forEach((node) => {
90
+ atRules[atRule.params].append(node);
91
+ });
92
+
93
+ // Remove the original at-rule since its contents have been
94
+ // merged into `atRules[atRule.params]`.
95
+ atRule.remove();
96
+ });
97
+
98
+ // Sort query keys and append merged at-rules back to the parent
99
+ if (atRules) {
100
+ sortAtRules(Object.keys(atRules), options, sortCSSmq).forEach(
101
+ (query) => {
102
+ parent.append(atRules[query]);
103
+ },
104
+ );
105
+ }
106
+ });
107
+
108
+ root.walkAtRules("media", (parent) => {
109
+ // Filter only @media nodes from the parent's children
110
+ let medias = parent.nodes.filter(
111
+ (node) => node.type === "atrule" && node.name === "media",
112
+ );
113
+
114
+ if (!medias) {
115
+ return;
116
+ }
117
+
118
+ medias.forEach((atRule) => {
119
+ parent.append(atRule);
120
+ });
121
+ });
122
+ },
123
+ };
124
+ }
125
+
126
+ plugin.postcss = true;
127
+
128
+ export default plugin;
@@ -1,6 +1,6 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
- const mod = require('./index.cjs');
3
+ const mod = require("./index.cjs");
4
4
 
5
5
  const plugin = mod.default;
6
6
 
package/package.json CHANGED
@@ -1,75 +1,76 @@
1
- {
2
- "name": "postcss-sort-media-queries",
3
- "description": "PostCSS plugin for sorting and combining CSS media queries with mobile first / **desktop first methodologies",
4
- "version": "6.4.4",
5
- "engines": {
6
- "node": ">=20.0.0"
7
- },
8
- "keywords": [
9
- "postcss",
10
- "postcss-plugin",
11
- "css",
12
- "css-optimizations",
13
- "sort",
14
- "mobile-first",
15
- "desktop-first",
16
- "mediaquery",
17
- "media-queries",
18
- "mq",
19
- "responsive-css",
20
- "combine-media-query",
21
- "sort-media-query",
22
- "css-mqpacker",
23
- "node-css-mqpacker"
24
- ],
25
- "author": "Yunus Gaziyev <yunusga@yandex.ru>",
26
- "license": "MIT",
27
- "repository": {
28
- "type": "git",
29
- "url": "https://github.com/yunusga/postcss-sort-media-queries.git"
30
- },
31
- "bugs": {
32
- "url": "https://github.com/yunusga/postcss-sort-media-queries/issues"
33
- },
34
- "homepage": "https://yunusga.uz/postcss-sort-media-queries",
35
- "type": "module",
36
- "main": "src/index.js",
37
- "module": "src/index.js",
38
- "exports": {
39
- ".": {
40
- "types": "./src/index.d.ts",
41
- "require": "./build/wrapper.cjs",
42
- "import": "./src/index.js",
43
- "default": "./src/index.js"
44
- }
45
- },
46
- "files": [
47
- "build"
48
- ],
49
- "scripts": {
50
- "test": "npm run build && vitest run",
51
- "test:watch": "vitest --watch",
52
- "coverage": "vitest --coverage",
53
- "lint": "eslint",
54
- "prepare": "husky",
55
- "build": "npm run build:cjs",
56
- "build:cjs": "esbuild src/index.js --outfile=build/index.cjs --format=cjs --bundle --platform=node --external:postcss"
57
- },
58
- "devDependencies": {
59
- "@eslint/js": "^10.0.1",
60
- "@vitest/coverage-v8": "^4.1.2",
61
- "esbuild": "^0.28.0",
62
- "eslint": "^10.2.0",
63
- "globals": "^17.4.0",
64
- "husky": "^9.1.7",
65
- "prettier": "3.8.1",
66
- "vitest": "^4.1.2"
67
- },
68
- "peerDependencies": {
69
- "nanoid": "^5.1.6",
70
- "postcss": "^8.5.6"
71
- },
72
- "dependencies": {
73
- "sort-css-media-queries": "^3.0.3"
74
- }
75
- }
1
+ {
2
+ "name": "postcss-sort-media-queries",
3
+ "description": "PostCSS plugin for sorting and combining CSS media queries with mobile first / **desktop first methodologies",
4
+ "version": "6.6.0",
5
+ "engines": {
6
+ "node": ">=20.0.0"
7
+ },
8
+ "keywords": [
9
+ "postcss",
10
+ "postcss-plugin",
11
+ "css",
12
+ "css-optimizations",
13
+ "sort",
14
+ "mobile-first",
15
+ "desktop-first",
16
+ "mediaquery",
17
+ "media-queries",
18
+ "mq",
19
+ "responsive-css",
20
+ "combine-media-query",
21
+ "sort-media-query",
22
+ "css-mqpacker",
23
+ "node-css-mqpacker"
24
+ ],
25
+ "author": "Yunus Gaziyev <yunusga@yandex.ru>",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/yunusga/postcss-sort-media-queries.git"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/yunusga/postcss-sort-media-queries/issues"
33
+ },
34
+ "homepage": "https://yunusga.uz/postcss-sort-media-queries",
35
+ "type": "module",
36
+ "main": "src/index.js",
37
+ "module": "src/index.js",
38
+ "exports": {
39
+ ".": {
40
+ "types": "./dist/index.d.ts",
41
+ "require": "./dist/wrapper.cjs",
42
+ "import": "./dist/index.js",
43
+ "default": "./dist/index.js"
44
+ }
45
+ },
46
+ "files": [
47
+ "dist"
48
+ ],
49
+ "scripts": {
50
+ "test": "npm run build && vitest run",
51
+ "test:watch": "vitest --watch",
52
+ "coverage": "vitest --coverage",
53
+ "lint": "eslint",
54
+ "format": "prettier --write .",
55
+ "prepare": "husky",
56
+ "build": "npm run build:cjs && cpy \"src/**/*\" dist",
57
+ "build:cjs": "esbuild src/index.js --outfile=dist/index.cjs --format=cjs --bundle --platform=node --external:postcss"
58
+ },
59
+ "devDependencies": {
60
+ "@eslint/js": "^10.0.1",
61
+ "@vitest/coverage-v8": "^4.1.2",
62
+ "cpy-cli": "^7.0.0",
63
+ "esbuild": "^0.28.0",
64
+ "eslint": "^10.2.0",
65
+ "globals": "^17.4.0",
66
+ "husky": "^9.1.7",
67
+ "prettier": "3.8.1",
68
+ "vitest": "^4.1.2"
69
+ },
70
+ "peerDependencies": {
71
+ "postcss": "^8.5.6"
72
+ },
73
+ "dependencies": {
74
+ "sort-css-media-queries": "^3.0.5"
75
+ }
76
+ }
package/src/index.js CHANGED
@@ -1,5 +1,4 @@
1
- import createSort from 'sort-css-media-queries/create-sort';
2
- import { nanoid } from 'nanoid';
1
+ import createSort from "sort-css-media-queries/create-sort";
3
2
 
4
3
  // PostCSS plugin to sort CSS @media rules according to a configurable order.
5
4
  // The plugin groups top-level and nested media at-rules, merges rules
@@ -7,8 +6,9 @@ import { nanoid } from 'nanoid';
7
6
 
8
7
  // Helper that ensures `options.sort` is a function and sorts queries.
9
8
  function sortAtRules(queries, options, sortCSSmq) {
10
- if (typeof options.sort !== 'function') {
11
- options.sort = options.sort === 'desktop-first' ? sortCSSmq.desktopFirst : sortCSSmq;
9
+ if (typeof options.sort !== "function") {
10
+ options.sort =
11
+ options.sort === "desktop-first" ? sortCSSmq.desktopFirst : sortCSSmq;
12
12
  }
13
13
 
14
14
  return queries.sort(options.sort);
@@ -25,61 +25,50 @@ function getDepth(node) {
25
25
  }
26
26
 
27
27
  function plugin(options = {}) {
28
-
29
28
  // Set default options and allow user overrides
30
29
  options = Object.assign(
31
30
  {
32
- sort: 'mobile-first',
31
+ sort: "mobile-first",
33
32
  configuration: false,
34
33
  },
35
- options
34
+ options,
36
35
  );
37
36
 
38
37
  // Create a sorter based on configuration (from sort-css-media-queries)
39
38
  const sortCSSmq = createSort(options.configuration);
40
39
 
41
40
  return {
42
- postcssPlugin: 'postcss-sort-media-queries',
41
+ postcssPlugin: "postcss-sort-media-queries",
43
42
 
44
43
  // Execute once after the entire tree has been parsed
45
44
  OnceExit(root, { AtRule }) {
46
45
  // Collect parent nodes that contain media at-rules. We separate
47
46
  // top-level (`root`) parents from nested parents so ordering
48
47
  // semantics can be preserved independently.
49
- let parents = [];
48
+ const parents = new Map();
50
49
 
51
50
  // Walk all @media at-rules and group their parents
52
- root.walkAtRules('media', (atRule) => {
53
- if (!atRule.parent.groupId) {
54
- let groupId = nanoid();
55
-
56
- atRule.parent.groupId = groupId;
57
-
58
- parents[groupId] = {
51
+ root.walkAtRules("media", (atRule) => {
52
+ if (!parents.has(atRule.parent)) {
53
+ parents.set(atRule.parent, {
59
54
  parent: atRule.parent,
60
55
  depth: getDepth(atRule.parent),
61
- }
56
+ });
62
57
  }
63
-
64
- return;
65
58
  });
66
59
 
67
- if (!parents) {
60
+ if (parents.size === 0) {
68
61
  return;
69
62
  }
70
63
 
71
- parents = Object.fromEntries(
72
- Object.entries(parents).sort(([, a], [, b]) => {
73
- return b.depth - a.depth;
74
- })
75
- );
76
-
77
- Object.keys(parents).forEach((groupId) => {
78
- let { parent } = parents[groupId];
64
+ const sortedParents = [...parents.values()].sort((a, b) => {
65
+ return b.depth - a.depth;
66
+ });
79
67
 
68
+ sortedParents.forEach(({ parent }) => {
80
69
  // Filter only @media nodes from the parent's children
81
70
  let medias = parent.nodes.filter(
82
- (node) => node.type === 'atrule' && node.name === 'media'
71
+ (node) => node.type === "atrule" && node.name === "media",
83
72
  );
84
73
 
85
74
  if (!medias) {
@@ -108,16 +97,18 @@ function plugin(options = {}) {
108
97
 
109
98
  // Sort query keys and append merged at-rules back to the parent
110
99
  if (atRules) {
111
- sortAtRules(Object.keys(atRules), options, sortCSSmq).forEach((query) => {
112
- parent.append(atRules[query]);
113
- });
100
+ sortAtRules(Object.keys(atRules), options, sortCSSmq).forEach(
101
+ (query) => {
102
+ parent.append(atRules[query]);
103
+ },
104
+ );
114
105
  }
115
106
  });
116
107
 
117
- root.walkAtRules('media', (parent) => {
108
+ root.walkAtRules("media", (parent) => {
118
109
  // Filter only @media nodes from the parent's children
119
110
  let medias = parent.nodes.filter(
120
- (node) => node.type === 'atrule' && node.name === 'media'
111
+ (node) => node.type === "atrule" && node.name === "media",
121
112
  );
122
113
 
123
114
  if (!medias) {
@@ -128,7 +119,7 @@ function plugin(options = {}) {
128
119
  parent.append(atRule);
129
120
  });
130
121
  });
131
- }
122
+ },
132
123
  };
133
124
  }
134
125