├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── leading-trim.ui.js ├── package.json ├── pnpm-lock.yaml ├── src ├── commands │ ├── showPanel │ │ ├── showPanel-main.ts │ │ └── showPanel-ui.tsx │ └── trimSelection.ts ├── core.ts ├── metrics │ ├── fontMetricsByFamilyName.ts │ ├── googleFonts.json │ └── systemFonts.json └── types.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | *.css.d.ts 4 | build/ 5 | node_modules/ 6 | manifest.json 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Development guide 2 | 3 | This project requires: 4 | 5 | - [Node.js](https://nodejs.org) 6 | - [pnpm](https://pnpm.io/) 7 | - [Figma desktop app](https://figma.com/downloads/) 8 | 9 | ## Build the plugin 10 | 11 | To watch for code changes and rebuild the plugin automatically during development: 12 | 13 | ```bash 14 | $ pnpm watch 15 | ``` 16 | 17 | To build the plugin for publishing: 18 | 19 | ```bash 20 | $ pnpm build 21 | ``` 22 | 23 | This will generate a [`manifest.json`](https://figma.com/plugin-docs/manifest/) file and a `build` directory containing the JavaScript bundles for the plugin. 24 | 25 | ## Install the plugin locally 26 | 27 | 1. In the Figma desktop app, open a Figma document. 28 | 2. Open Quick Actions (`Cmd + P`) and run `Import plugin from manifest…` 29 | 3. Select the generated `manifest.json` file. 30 | 31 | ## Debugging 32 | 33 | To open the developer console, search for and run `Open Console` via the Quick Actions search bar. Just like in a browser, you can use `console.log` statements to inspect values in your code. 34 | 35 | ## See also 36 | 37 | - [Create Figma Plugin docs](https://yuanqing.github.io/create-figma-plugin/) 38 | - [`yuanqing/figma-plugins`](https://github.com/yuanqing/figma-plugins#readme) 39 | 40 | Official docs and code samples from Figma: 41 | 42 | - [Plugin API docs](https://figma.com/plugin-docs/) 43 | - [`figma/plugin-samples`](https://github.com/figma/plugin-samples#readme) 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mark Dalgleish 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # figma-leading-trim 2 | 3 | Figma plugin for trimming your text elements, removing space above capital letters and below the baseline. Make text behave the same as every other element in your layout. 4 | 5 | This plugin works by nesting and offsetting text elements within frames. 6 | 7 | To achieve the same behaviour in a browser, check out [Capsize](https://seek-oss.github.io/capsize) which this plugin uses internally. 8 | 9 | ### Install 10 | 11 | To use this plugin, you can [install Leading Trim from Figma Community.](https://www.figma.com/community/plugin/1143761729202073143/Leading-Trim) 12 | 13 | --- 14 | 15 | ### Credit 16 | 17 | - [Yuan Qing Lim](https://twitter.com/yuanqinglim) for [create-figma-plugin](https://github.com/yuanqing/create-figma-plugin) 18 | - [Michael Taranto](https://twitter.com/michaeltaranto) for [Capsize](https://seek-oss.github.io/capsize) 19 | 20 | ### Development guide 21 | 22 | Read [CONTRIBUTING.md.](/CONTRIBUTING.md) 23 | 24 | ### License 25 | 26 | [MIT License](/LICENSE) 27 | -------------------------------------------------------------------------------- /leading-trim.ui.js: -------------------------------------------------------------------------------- 1 | module.exports = function (buildOptions) { 2 | return { 3 | ...buildOptions, 4 | define: { 5 | global: "window", 6 | }, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.0.0", 3 | "dependencies": { 4 | "@capsizecss/core": "^3.0.0", 5 | "@create-figma-plugin/ui": "^2.1.2", 6 | "@create-figma-plugin/utilities": "^2.1.2", 7 | "preact": "^10" 8 | }, 9 | "devDependencies": { 10 | "@create-figma-plugin/build": "^2.1.2", 11 | "@create-figma-plugin/tsconfig": "^2.1.2", 12 | "@figma/plugin-typings": "1.50.0", 13 | "@types/react": "^16", 14 | "react": "^16", 15 | "typescript": "^4" 16 | }, 17 | "scripts": { 18 | "start": "pnpm dev", 19 | "dev": "pnpm watch", 20 | "build": "build-figma-plugin --typecheck --minify", 21 | "watch": "build-figma-plugin --typecheck --watch" 22 | }, 23 | "figma-plugin": { 24 | "editorType": [ 25 | "figma" 26 | ], 27 | "id": "1143761729202073143", 28 | "name": "Leading Trim", 29 | "menu": [ 30 | { 31 | "name": "Show panel", 32 | "main": "src/commands/showPanel/showPanel-main.ts", 33 | "ui": "src/commands/showPanel/showPanel-ui.tsx" 34 | }, 35 | { 36 | "name": "Trim selection", 37 | "main": "src/commands/trimSelection.ts" 38 | } 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | '@capsizecss/core': ^3.0.0 5 | '@create-figma-plugin/build': ^2.1.2 6 | '@create-figma-plugin/tsconfig': ^2.1.2 7 | '@create-figma-plugin/ui': ^2.1.2 8 | '@create-figma-plugin/utilities': ^2.1.2 9 | '@figma/plugin-typings': 1.50.0 10 | '@types/react': ^16 11 | preact: ^10 12 | react: ^16 13 | typescript: ^4 14 | 15 | dependencies: 16 | '@capsizecss/core': 3.0.0 17 | '@create-figma-plugin/ui': 2.1.2_preact@10.10.3 18 | '@create-figma-plugin/utilities': 2.1.2 19 | preact: 10.10.3 20 | 21 | devDependencies: 22 | '@create-figma-plugin/build': 2.1.2_oglhe7pylu3m2v3h3nltktlase 23 | '@create-figma-plugin/tsconfig': 2.1.2 24 | '@figma/plugin-typings': 1.50.0 25 | '@types/react': 16.14.30 26 | react: 16.14.0 27 | typescript: 4.6.4 28 | 29 | packages: 30 | 31 | /@capsizecss/core/3.0.0: 32 | resolution: {integrity: sha512-tJNEWMmhHcU5z6ITAiVNN9z+PCTylybVIJqgX7Ts4zN66fe/W2Fe5UWJCCZIP/5uutsl5fYOaVVHZIjsuTVhBQ==} 33 | dev: false 34 | 35 | /@create-figma-plugin/build/2.1.2_oglhe7pylu3m2v3h3nltktlase: 36 | resolution: {integrity: sha512-/b2mwOv+KgirngIizwCBNGqs6EHWWke/wZ2nZ9PWZl7pL0yzbjveq1DZBRlH89pcoJlmgMZ8RlqdhOMxyjx3vw==} 37 | engines: {node: '>=16'} 38 | hasBin: true 39 | peerDependencies: 40 | '@figma/plugin-typings': ^1 41 | typescript: ^4 42 | dependencies: 43 | '@create-figma-plugin/common': 2.1.2 44 | '@figma/plugin-typings': 1.50.0 45 | chokidar: 3.5.3 46 | cssnano: 5.1.13_postcss@8.4.16 47 | esbuild: 0.14.54 48 | find-up: 6.3.0 49 | fs-extra: 10.1.0 50 | globby: 13.1.2 51 | indent-string: 5.0.0 52 | kleur: 4.1.4 53 | postcss: 8.4.16 54 | postcss-modules: 4.3.1_postcss@8.4.16 55 | rev-hash: 4.0.0 56 | sade: 1.8.1 57 | temp-write: 5.0.0 58 | tempy: 3.0.0 59 | typed-css-modules: 0.7.2 60 | typescript: 4.6.4 61 | dev: true 62 | 63 | /@create-figma-plugin/common/2.1.2: 64 | resolution: {integrity: sha512-E0i5VcfknhXv03nQYdswTFvS1lKgZbD9tbGMpjTRZ/FaUgSAu1SBvKH0/PdMHtZa94phADWdbsWuSXbf7rgOiA==} 65 | engines: {node: '>=16'} 66 | dependencies: 67 | '@sindresorhus/slugify': 2.1.0 68 | fs-extra: 10.1.0 69 | kleur: 4.1.4 70 | dev: true 71 | 72 | /@create-figma-plugin/tsconfig/2.1.2: 73 | resolution: {integrity: sha512-/zO3iafnkykyDyuj2uoBPHOznjxT/BWByr3OO639HQzaelB70Exbm0HOQayOcxeOzn/55JpDwz+fPsT5EqyfRw==} 74 | dev: true 75 | 76 | /@create-figma-plugin/ui/2.1.2_preact@10.10.3: 77 | resolution: {integrity: sha512-6w5taIN4dvknXNeZDGbRSHDqV9o0dshlzPeZkPnhsmWS2fsdyi1iVECYE74nEvalogHka50P/xY+5gG09m4Tyg==} 78 | engines: {node: '>=16'} 79 | peerDependencies: 80 | preact: ^10 81 | dependencies: 82 | '@create-figma-plugin/utilities': 2.1.2 83 | preact: 10.10.3 84 | dev: false 85 | 86 | /@create-figma-plugin/utilities/2.1.2: 87 | resolution: {integrity: sha512-Id1pP8TMD8zECQs/3acz9UsI+hu40T6Vx3dIATvvf+oAz5hSEerNoIwiYbkrHitT2NTVZin1nrlXN+M1mwxLsQ==} 88 | engines: {node: '>=16'} 89 | dependencies: 90 | hex-rgb: 5.0.0 91 | natural-compare-lite: 1.4.0 92 | rgb-hex: 4.0.0 93 | dev: false 94 | 95 | /@esbuild/linux-loong64/0.14.54: 96 | resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} 97 | engines: {node: '>=12'} 98 | cpu: [loong64] 99 | os: [linux] 100 | requiresBuild: true 101 | dev: true 102 | optional: true 103 | 104 | /@figma/plugin-typings/1.50.0: 105 | resolution: {integrity: sha512-ue1He4XimFEjY7eS7x6tBY6pyMp7zfVOjgStFioqKUxPPIz0gCFLmFUjR5g6fMrYJCqAMP5/Mjwq4Ks0vpe2sA==} 106 | dev: true 107 | 108 | /@nodelib/fs.scandir/2.1.5: 109 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 110 | engines: {node: '>= 8'} 111 | dependencies: 112 | '@nodelib/fs.stat': 2.0.5 113 | run-parallel: 1.2.0 114 | dev: true 115 | 116 | /@nodelib/fs.stat/2.0.5: 117 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 118 | engines: {node: '>= 8'} 119 | dev: true 120 | 121 | /@nodelib/fs.walk/1.2.8: 122 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 123 | engines: {node: '>= 8'} 124 | dependencies: 125 | '@nodelib/fs.scandir': 2.1.5 126 | fastq: 1.13.0 127 | dev: true 128 | 129 | /@sindresorhus/slugify/2.1.0: 130 | resolution: {integrity: sha512-gU3Gdm/V167BmUwIn8APHZ3SeeRVRUSOdXxnt7Q/JkUHLXaaTA/prYmoRumwsSitJZWUDYMzDWdWgrOdvE8IRQ==} 131 | engines: {node: '>=12'} 132 | dependencies: 133 | '@sindresorhus/transliterate': 1.5.0 134 | escape-string-regexp: 5.0.0 135 | dev: true 136 | 137 | /@sindresorhus/transliterate/1.5.0: 138 | resolution: {integrity: sha512-/sfSkoNelLq5riqNRp5uBjHIKBi1MWZk9ubRT1WiBQuTfmDf7BeQkph2DJzRB83QagMPHk2VDjuvpy0VuwyzdA==} 139 | engines: {node: '>=12'} 140 | dependencies: 141 | escape-string-regexp: 5.0.0 142 | lodash.deburr: 4.1.0 143 | dev: true 144 | 145 | /@trysound/sax/0.2.0: 146 | resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} 147 | engines: {node: '>=10.13.0'} 148 | dev: true 149 | 150 | /@types/css-modules-loader-core/1.1.0: 151 | resolution: {integrity: sha512-LMbyf7THPqLCPHIXAj79v9Pa193MeOHgp1fBFRR6s6VvEVHUFIcM5bc/WttslOf+lao4TURNN1X1zfW5wr2CHQ==} 152 | dependencies: 153 | postcss: 7.0.39 154 | dev: true 155 | 156 | /@types/prop-types/15.7.5: 157 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 158 | dev: true 159 | 160 | /@types/react/16.14.30: 161 | resolution: {integrity: sha512-tG+xGtDDSuIl1l63mN0LnaROAc99knkYyN4YTheE80iPzYvSy0U8LVie+OBZkrgjVrpkQV6bMCkSphPBnVNk6g==} 162 | dependencies: 163 | '@types/prop-types': 15.7.5 164 | '@types/scheduler': 0.16.2 165 | csstype: 3.1.0 166 | dev: true 167 | 168 | /@types/scheduler/0.16.2: 169 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} 170 | dev: true 171 | 172 | /ansi-regex/2.1.1: 173 | resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} 174 | engines: {node: '>=0.10.0'} 175 | dev: true 176 | 177 | /ansi-regex/5.0.1: 178 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 179 | engines: {node: '>=8'} 180 | dev: true 181 | 182 | /ansi-styles/2.2.1: 183 | resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} 184 | engines: {node: '>=0.10.0'} 185 | dev: true 186 | 187 | /ansi-styles/4.3.0: 188 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 189 | engines: {node: '>=8'} 190 | dependencies: 191 | color-convert: 2.0.1 192 | dev: true 193 | 194 | /anymatch/3.1.2: 195 | resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} 196 | engines: {node: '>= 8'} 197 | dependencies: 198 | normalize-path: 3.0.0 199 | picomatch: 2.3.1 200 | dev: true 201 | 202 | /balanced-match/1.0.2: 203 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 204 | dev: true 205 | 206 | /binary-extensions/2.2.0: 207 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 208 | engines: {node: '>=8'} 209 | dev: true 210 | 211 | /boolbase/1.0.0: 212 | resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} 213 | dev: true 214 | 215 | /brace-expansion/1.1.11: 216 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 217 | dependencies: 218 | balanced-match: 1.0.2 219 | concat-map: 0.0.1 220 | dev: true 221 | 222 | /braces/3.0.2: 223 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 224 | engines: {node: '>=8'} 225 | dependencies: 226 | fill-range: 7.0.1 227 | dev: true 228 | 229 | /browserslist/4.20.3: 230 | resolution: {integrity: sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==} 231 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 232 | hasBin: true 233 | dependencies: 234 | caniuse-lite: 1.0.30001339 235 | electron-to-chromium: 1.4.137 236 | escalade: 3.1.1 237 | node-releases: 2.0.4 238 | picocolors: 1.0.0 239 | dev: true 240 | 241 | /camelcase/5.3.1: 242 | resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} 243 | engines: {node: '>=6'} 244 | dev: true 245 | 246 | /camelcase/6.3.0: 247 | resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} 248 | engines: {node: '>=10'} 249 | dev: true 250 | 251 | /caniuse-api/3.0.0: 252 | resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} 253 | dependencies: 254 | browserslist: 4.20.3 255 | caniuse-lite: 1.0.30001339 256 | lodash.memoize: 4.1.2 257 | lodash.uniq: 4.5.0 258 | dev: true 259 | 260 | /caniuse-lite/1.0.30001339: 261 | resolution: {integrity: sha512-Es8PiVqCe+uXdms0Gu5xP5PF2bxLR7OBp3wUzUnuO7OHzhOfCyg3hdiGWVPVxhiuniOzng+hTc1u3fEQ0TlkSQ==} 262 | dev: true 263 | 264 | /chalk/1.1.3: 265 | resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} 266 | engines: {node: '>=0.10.0'} 267 | dependencies: 268 | ansi-styles: 2.2.1 269 | escape-string-regexp: 1.0.5 270 | has-ansi: 2.0.0 271 | strip-ansi: 3.0.1 272 | supports-color: 2.0.0 273 | dev: true 274 | 275 | /chalk/4.1.2: 276 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 277 | engines: {node: '>=10'} 278 | dependencies: 279 | ansi-styles: 4.3.0 280 | supports-color: 7.2.0 281 | dev: true 282 | 283 | /chokidar/3.5.3: 284 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 285 | engines: {node: '>= 8.10.0'} 286 | dependencies: 287 | anymatch: 3.1.2 288 | braces: 3.0.2 289 | glob-parent: 5.1.2 290 | is-binary-path: 2.1.0 291 | is-glob: 4.0.3 292 | normalize-path: 3.0.0 293 | readdirp: 3.6.0 294 | optionalDependencies: 295 | fsevents: 2.3.2 296 | dev: true 297 | 298 | /cliui/6.0.0: 299 | resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} 300 | dependencies: 301 | string-width: 4.2.3 302 | strip-ansi: 6.0.1 303 | wrap-ansi: 6.2.0 304 | dev: true 305 | 306 | /color-convert/2.0.1: 307 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 308 | engines: {node: '>=7.0.0'} 309 | dependencies: 310 | color-name: 1.1.4 311 | dev: true 312 | 313 | /color-name/1.1.4: 314 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 315 | dev: true 316 | 317 | /colord/2.9.2: 318 | resolution: {integrity: sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==} 319 | dev: true 320 | 321 | /commander/7.2.0: 322 | resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} 323 | engines: {node: '>= 10'} 324 | dev: true 325 | 326 | /concat-map/0.0.1: 327 | resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} 328 | dev: true 329 | 330 | /crypto-random-string/4.0.0: 331 | resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} 332 | engines: {node: '>=12'} 333 | dependencies: 334 | type-fest: 1.4.0 335 | dev: true 336 | 337 | /css-declaration-sorter/6.3.0_postcss@8.4.16: 338 | resolution: {integrity: sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og==} 339 | engines: {node: ^10 || ^12 || >=14} 340 | peerDependencies: 341 | postcss: ^8.0.9 342 | dependencies: 343 | postcss: 8.4.16 344 | dev: true 345 | 346 | /css-modules-loader-core/1.1.0: 347 | resolution: {integrity: sha512-XWOBwgy5nwBn76aA+6ybUGL/3JBnCtBX9Ay9/OWIpzKYWlVHMazvJ+WtHumfi+xxdPF440cWK7JCYtt8xDifew==} 348 | dependencies: 349 | icss-replace-symbols: 1.1.0 350 | postcss: 6.0.1 351 | postcss-modules-extract-imports: 1.1.0 352 | postcss-modules-local-by-default: 1.2.0 353 | postcss-modules-scope: 1.1.0 354 | postcss-modules-values: 1.3.0 355 | dev: true 356 | 357 | /css-select/4.3.0: 358 | resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} 359 | dependencies: 360 | boolbase: 1.0.0 361 | css-what: 6.1.0 362 | domhandler: 4.3.1 363 | domutils: 2.8.0 364 | nth-check: 2.0.1 365 | dev: true 366 | 367 | /css-selector-tokenizer/0.7.3: 368 | resolution: {integrity: sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==} 369 | dependencies: 370 | cssesc: 3.0.0 371 | fastparse: 1.1.2 372 | dev: true 373 | 374 | /css-tree/1.1.3: 375 | resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} 376 | engines: {node: '>=8.0.0'} 377 | dependencies: 378 | mdn-data: 2.0.14 379 | source-map: 0.6.1 380 | dev: true 381 | 382 | /css-what/6.1.0: 383 | resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} 384 | engines: {node: '>= 6'} 385 | dev: true 386 | 387 | /cssesc/3.0.0: 388 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 389 | engines: {node: '>=4'} 390 | hasBin: true 391 | dev: true 392 | 393 | /cssnano-preset-default/5.2.12_postcss@8.4.16: 394 | resolution: {integrity: sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==} 395 | engines: {node: ^10 || ^12 || >=14.0} 396 | peerDependencies: 397 | postcss: ^8.2.15 398 | dependencies: 399 | css-declaration-sorter: 6.3.0_postcss@8.4.16 400 | cssnano-utils: 3.1.0_postcss@8.4.16 401 | postcss: 8.4.16 402 | postcss-calc: 8.2.4_postcss@8.4.16 403 | postcss-colormin: 5.3.0_postcss@8.4.16 404 | postcss-convert-values: 5.1.2_postcss@8.4.16 405 | postcss-discard-comments: 5.1.2_postcss@8.4.16 406 | postcss-discard-duplicates: 5.1.0_postcss@8.4.16 407 | postcss-discard-empty: 5.1.1_postcss@8.4.16 408 | postcss-discard-overridden: 5.1.0_postcss@8.4.16 409 | postcss-merge-longhand: 5.1.6_postcss@8.4.16 410 | postcss-merge-rules: 5.1.2_postcss@8.4.16 411 | postcss-minify-font-values: 5.1.0_postcss@8.4.16 412 | postcss-minify-gradients: 5.1.1_postcss@8.4.16 413 | postcss-minify-params: 5.1.3_postcss@8.4.16 414 | postcss-minify-selectors: 5.2.1_postcss@8.4.16 415 | postcss-normalize-charset: 5.1.0_postcss@8.4.16 416 | postcss-normalize-display-values: 5.1.0_postcss@8.4.16 417 | postcss-normalize-positions: 5.1.1_postcss@8.4.16 418 | postcss-normalize-repeat-style: 5.1.1_postcss@8.4.16 419 | postcss-normalize-string: 5.1.0_postcss@8.4.16 420 | postcss-normalize-timing-functions: 5.1.0_postcss@8.4.16 421 | postcss-normalize-unicode: 5.1.0_postcss@8.4.16 422 | postcss-normalize-url: 5.1.0_postcss@8.4.16 423 | postcss-normalize-whitespace: 5.1.1_postcss@8.4.16 424 | postcss-ordered-values: 5.1.3_postcss@8.4.16 425 | postcss-reduce-initial: 5.1.0_postcss@8.4.16 426 | postcss-reduce-transforms: 5.1.0_postcss@8.4.16 427 | postcss-svgo: 5.1.0_postcss@8.4.16 428 | postcss-unique-selectors: 5.1.1_postcss@8.4.16 429 | dev: true 430 | 431 | /cssnano-utils/3.1.0_postcss@8.4.16: 432 | resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} 433 | engines: {node: ^10 || ^12 || >=14.0} 434 | peerDependencies: 435 | postcss: ^8.2.15 436 | dependencies: 437 | postcss: 8.4.16 438 | dev: true 439 | 440 | /cssnano/5.1.13_postcss@8.4.16: 441 | resolution: {integrity: sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==} 442 | engines: {node: ^10 || ^12 || >=14.0} 443 | peerDependencies: 444 | postcss: ^8.2.15 445 | dependencies: 446 | cssnano-preset-default: 5.2.12_postcss@8.4.16 447 | lilconfig: 2.0.5 448 | postcss: 8.4.16 449 | yaml: 1.10.2 450 | dev: true 451 | 452 | /csso/4.2.0: 453 | resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} 454 | engines: {node: '>=8.0.0'} 455 | dependencies: 456 | css-tree: 1.1.3 457 | dev: true 458 | 459 | /csstype/3.1.0: 460 | resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==} 461 | dev: true 462 | 463 | /decamelize/1.2.0: 464 | resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} 465 | engines: {node: '>=0.10.0'} 466 | dev: true 467 | 468 | /dir-glob/3.0.1: 469 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 470 | engines: {node: '>=8'} 471 | dependencies: 472 | path-type: 4.0.0 473 | dev: true 474 | 475 | /dom-serializer/1.4.1: 476 | resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} 477 | dependencies: 478 | domelementtype: 2.3.0 479 | domhandler: 4.3.1 480 | entities: 2.2.0 481 | dev: true 482 | 483 | /domelementtype/2.3.0: 484 | resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} 485 | dev: true 486 | 487 | /domhandler/4.3.1: 488 | resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} 489 | engines: {node: '>= 4'} 490 | dependencies: 491 | domelementtype: 2.3.0 492 | dev: true 493 | 494 | /domutils/2.8.0: 495 | resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} 496 | dependencies: 497 | dom-serializer: 1.4.1 498 | domelementtype: 2.3.0 499 | domhandler: 4.3.1 500 | dev: true 501 | 502 | /electron-to-chromium/1.4.137: 503 | resolution: {integrity: sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==} 504 | dev: true 505 | 506 | /emoji-regex/8.0.0: 507 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 508 | dev: true 509 | 510 | /entities/2.2.0: 511 | resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} 512 | dev: true 513 | 514 | /esbuild-android-64/0.14.54: 515 | resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} 516 | engines: {node: '>=12'} 517 | cpu: [x64] 518 | os: [android] 519 | requiresBuild: true 520 | dev: true 521 | optional: true 522 | 523 | /esbuild-android-arm64/0.14.54: 524 | resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} 525 | engines: {node: '>=12'} 526 | cpu: [arm64] 527 | os: [android] 528 | requiresBuild: true 529 | dev: true 530 | optional: true 531 | 532 | /esbuild-darwin-64/0.14.54: 533 | resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} 534 | engines: {node: '>=12'} 535 | cpu: [x64] 536 | os: [darwin] 537 | requiresBuild: true 538 | dev: true 539 | optional: true 540 | 541 | /esbuild-darwin-arm64/0.14.54: 542 | resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} 543 | engines: {node: '>=12'} 544 | cpu: [arm64] 545 | os: [darwin] 546 | requiresBuild: true 547 | dev: true 548 | optional: true 549 | 550 | /esbuild-freebsd-64/0.14.54: 551 | resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} 552 | engines: {node: '>=12'} 553 | cpu: [x64] 554 | os: [freebsd] 555 | requiresBuild: true 556 | dev: true 557 | optional: true 558 | 559 | /esbuild-freebsd-arm64/0.14.54: 560 | resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} 561 | engines: {node: '>=12'} 562 | cpu: [arm64] 563 | os: [freebsd] 564 | requiresBuild: true 565 | dev: true 566 | optional: true 567 | 568 | /esbuild-linux-32/0.14.54: 569 | resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} 570 | engines: {node: '>=12'} 571 | cpu: [ia32] 572 | os: [linux] 573 | requiresBuild: true 574 | dev: true 575 | optional: true 576 | 577 | /esbuild-linux-64/0.14.54: 578 | resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} 579 | engines: {node: '>=12'} 580 | cpu: [x64] 581 | os: [linux] 582 | requiresBuild: true 583 | dev: true 584 | optional: true 585 | 586 | /esbuild-linux-arm/0.14.54: 587 | resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} 588 | engines: {node: '>=12'} 589 | cpu: [arm] 590 | os: [linux] 591 | requiresBuild: true 592 | dev: true 593 | optional: true 594 | 595 | /esbuild-linux-arm64/0.14.54: 596 | resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} 597 | engines: {node: '>=12'} 598 | cpu: [arm64] 599 | os: [linux] 600 | requiresBuild: true 601 | dev: true 602 | optional: true 603 | 604 | /esbuild-linux-mips64le/0.14.54: 605 | resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} 606 | engines: {node: '>=12'} 607 | cpu: [mips64el] 608 | os: [linux] 609 | requiresBuild: true 610 | dev: true 611 | optional: true 612 | 613 | /esbuild-linux-ppc64le/0.14.54: 614 | resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} 615 | engines: {node: '>=12'} 616 | cpu: [ppc64] 617 | os: [linux] 618 | requiresBuild: true 619 | dev: true 620 | optional: true 621 | 622 | /esbuild-linux-riscv64/0.14.54: 623 | resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} 624 | engines: {node: '>=12'} 625 | cpu: [riscv64] 626 | os: [linux] 627 | requiresBuild: true 628 | dev: true 629 | optional: true 630 | 631 | /esbuild-linux-s390x/0.14.54: 632 | resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} 633 | engines: {node: '>=12'} 634 | cpu: [s390x] 635 | os: [linux] 636 | requiresBuild: true 637 | dev: true 638 | optional: true 639 | 640 | /esbuild-netbsd-64/0.14.54: 641 | resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} 642 | engines: {node: '>=12'} 643 | cpu: [x64] 644 | os: [netbsd] 645 | requiresBuild: true 646 | dev: true 647 | optional: true 648 | 649 | /esbuild-openbsd-64/0.14.54: 650 | resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} 651 | engines: {node: '>=12'} 652 | cpu: [x64] 653 | os: [openbsd] 654 | requiresBuild: true 655 | dev: true 656 | optional: true 657 | 658 | /esbuild-sunos-64/0.14.54: 659 | resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} 660 | engines: {node: '>=12'} 661 | cpu: [x64] 662 | os: [sunos] 663 | requiresBuild: true 664 | dev: true 665 | optional: true 666 | 667 | /esbuild-windows-32/0.14.54: 668 | resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} 669 | engines: {node: '>=12'} 670 | cpu: [ia32] 671 | os: [win32] 672 | requiresBuild: true 673 | dev: true 674 | optional: true 675 | 676 | /esbuild-windows-64/0.14.54: 677 | resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} 678 | engines: {node: '>=12'} 679 | cpu: [x64] 680 | os: [win32] 681 | requiresBuild: true 682 | dev: true 683 | optional: true 684 | 685 | /esbuild-windows-arm64/0.14.54: 686 | resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} 687 | engines: {node: '>=12'} 688 | cpu: [arm64] 689 | os: [win32] 690 | requiresBuild: true 691 | dev: true 692 | optional: true 693 | 694 | /esbuild/0.14.54: 695 | resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} 696 | engines: {node: '>=12'} 697 | hasBin: true 698 | requiresBuild: true 699 | optionalDependencies: 700 | '@esbuild/linux-loong64': 0.14.54 701 | esbuild-android-64: 0.14.54 702 | esbuild-android-arm64: 0.14.54 703 | esbuild-darwin-64: 0.14.54 704 | esbuild-darwin-arm64: 0.14.54 705 | esbuild-freebsd-64: 0.14.54 706 | esbuild-freebsd-arm64: 0.14.54 707 | esbuild-linux-32: 0.14.54 708 | esbuild-linux-64: 0.14.54 709 | esbuild-linux-arm: 0.14.54 710 | esbuild-linux-arm64: 0.14.54 711 | esbuild-linux-mips64le: 0.14.54 712 | esbuild-linux-ppc64le: 0.14.54 713 | esbuild-linux-riscv64: 0.14.54 714 | esbuild-linux-s390x: 0.14.54 715 | esbuild-netbsd-64: 0.14.54 716 | esbuild-openbsd-64: 0.14.54 717 | esbuild-sunos-64: 0.14.54 718 | esbuild-windows-32: 0.14.54 719 | esbuild-windows-64: 0.14.54 720 | esbuild-windows-arm64: 0.14.54 721 | dev: true 722 | 723 | /escalade/3.1.1: 724 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 725 | engines: {node: '>=6'} 726 | dev: true 727 | 728 | /escape-string-regexp/1.0.5: 729 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 730 | engines: {node: '>=0.8.0'} 731 | dev: true 732 | 733 | /escape-string-regexp/5.0.0: 734 | resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} 735 | engines: {node: '>=12'} 736 | dev: true 737 | 738 | /fast-glob/3.2.11: 739 | resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} 740 | engines: {node: '>=8.6.0'} 741 | dependencies: 742 | '@nodelib/fs.stat': 2.0.5 743 | '@nodelib/fs.walk': 1.2.8 744 | glob-parent: 5.1.2 745 | merge2: 1.4.1 746 | micromatch: 4.0.5 747 | dev: true 748 | 749 | /fastparse/1.1.2: 750 | resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==} 751 | dev: true 752 | 753 | /fastq/1.13.0: 754 | resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} 755 | dependencies: 756 | reusify: 1.0.4 757 | dev: true 758 | 759 | /fill-range/7.0.1: 760 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 761 | engines: {node: '>=8'} 762 | dependencies: 763 | to-regex-range: 5.0.1 764 | dev: true 765 | 766 | /find-up/4.1.0: 767 | resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} 768 | engines: {node: '>=8'} 769 | dependencies: 770 | locate-path: 5.0.0 771 | path-exists: 4.0.0 772 | dev: true 773 | 774 | /find-up/6.3.0: 775 | resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} 776 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 777 | dependencies: 778 | locate-path: 7.1.0 779 | path-exists: 5.0.0 780 | dev: true 781 | 782 | /fs-extra/10.1.0: 783 | resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} 784 | engines: {node: '>=12'} 785 | dependencies: 786 | graceful-fs: 4.2.10 787 | jsonfile: 6.1.0 788 | universalify: 2.0.0 789 | dev: true 790 | 791 | /fs.realpath/1.0.0: 792 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 793 | dev: true 794 | 795 | /fsevents/2.3.2: 796 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 797 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 798 | os: [darwin] 799 | requiresBuild: true 800 | dev: true 801 | optional: true 802 | 803 | /generic-names/4.0.0: 804 | resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} 805 | dependencies: 806 | loader-utils: 3.2.0 807 | dev: true 808 | 809 | /get-caller-file/2.0.5: 810 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 811 | engines: {node: 6.* || 8.* || >= 10.*} 812 | dev: true 813 | 814 | /glob-parent/5.1.2: 815 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 816 | engines: {node: '>= 6'} 817 | dependencies: 818 | is-glob: 4.0.3 819 | dev: true 820 | 821 | /glob/7.2.0: 822 | resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} 823 | dependencies: 824 | fs.realpath: 1.0.0 825 | inflight: 1.0.6 826 | inherits: 2.0.4 827 | minimatch: 3.1.2 828 | once: 1.4.0 829 | path-is-absolute: 1.0.1 830 | dev: true 831 | 832 | /globby/13.1.2: 833 | resolution: {integrity: sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==} 834 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 835 | dependencies: 836 | dir-glob: 3.0.1 837 | fast-glob: 3.2.11 838 | ignore: 5.2.0 839 | merge2: 1.4.1 840 | slash: 4.0.0 841 | dev: true 842 | 843 | /graceful-fs/4.2.10: 844 | resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} 845 | dev: true 846 | 847 | /has-ansi/2.0.0: 848 | resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} 849 | engines: {node: '>=0.10.0'} 850 | dependencies: 851 | ansi-regex: 2.1.1 852 | dev: true 853 | 854 | /has-flag/1.0.0: 855 | resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} 856 | engines: {node: '>=0.10.0'} 857 | dev: true 858 | 859 | /has-flag/4.0.0: 860 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 861 | engines: {node: '>=8'} 862 | dev: true 863 | 864 | /hex-rgb/5.0.0: 865 | resolution: {integrity: sha512-NQO+lgVUCtHxZ792FodgW0zflK+ozS9X9dwGp9XvvmPlH7pyxd588cn24TD3rmPm/N0AIRXF10Otah8yKqGw4w==} 866 | engines: {node: '>=12'} 867 | dev: false 868 | 869 | /icss-replace-symbols/1.1.0: 870 | resolution: {integrity: sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=} 871 | dev: true 872 | 873 | /icss-utils/5.1.0_postcss@8.4.16: 874 | resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} 875 | engines: {node: ^10 || ^12 || >= 14} 876 | peerDependencies: 877 | postcss: ^8.1.0 878 | dependencies: 879 | postcss: 8.4.16 880 | dev: true 881 | 882 | /ignore/5.2.0: 883 | resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} 884 | engines: {node: '>= 4'} 885 | dev: true 886 | 887 | /indent-string/5.0.0: 888 | resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} 889 | engines: {node: '>=12'} 890 | dev: true 891 | 892 | /inflight/1.0.6: 893 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 894 | dependencies: 895 | once: 1.4.0 896 | wrappy: 1.0.2 897 | dev: true 898 | 899 | /inherits/2.0.4: 900 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 901 | dev: true 902 | 903 | /is-binary-path/2.1.0: 904 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 905 | engines: {node: '>=8'} 906 | dependencies: 907 | binary-extensions: 2.2.0 908 | dev: true 909 | 910 | /is-extglob/2.1.1: 911 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 912 | engines: {node: '>=0.10.0'} 913 | dev: true 914 | 915 | /is-fullwidth-code-point/3.0.0: 916 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 917 | engines: {node: '>=8'} 918 | dev: true 919 | 920 | /is-glob/4.0.3: 921 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 922 | engines: {node: '>=0.10.0'} 923 | dependencies: 924 | is-extglob: 2.1.1 925 | dev: true 926 | 927 | /is-number/7.0.0: 928 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 929 | engines: {node: '>=0.12.0'} 930 | dev: true 931 | 932 | /is-stream/2.0.1: 933 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} 934 | engines: {node: '>=8'} 935 | dev: true 936 | 937 | /is-stream/3.0.0: 938 | resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 939 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 940 | dev: true 941 | 942 | /is-there/4.5.1: 943 | resolution: {integrity: sha512-vIZ7HTXAoRoIwYSsTnxb0sg9L6rth+JOulNcavsbskQkCIWoSM2cjFOWZs4wGziGZER+Xgs/HXiCQZgiL8ppxQ==} 944 | dev: true 945 | 946 | /js-tokens/4.0.0: 947 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 948 | dev: true 949 | 950 | /jsonfile/6.1.0: 951 | resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} 952 | dependencies: 953 | universalify: 2.0.0 954 | optionalDependencies: 955 | graceful-fs: 4.2.10 956 | dev: true 957 | 958 | /kleur/4.1.4: 959 | resolution: {integrity: sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==} 960 | engines: {node: '>=6'} 961 | dev: true 962 | 963 | /lilconfig/2.0.5: 964 | resolution: {integrity: sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==} 965 | engines: {node: '>=10'} 966 | dev: true 967 | 968 | /loader-utils/3.2.0: 969 | resolution: {integrity: sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==} 970 | engines: {node: '>= 12.13.0'} 971 | dev: true 972 | 973 | /locate-path/5.0.0: 974 | resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} 975 | engines: {node: '>=8'} 976 | dependencies: 977 | p-locate: 4.1.0 978 | dev: true 979 | 980 | /locate-path/7.1.0: 981 | resolution: {integrity: sha512-HNx5uOnYeK4SxEoid5qnhRfprlJeGMzFRKPLCf/15N3/B4AiofNwC/yq7VBKdVk9dx7m+PiYCJOGg55JYTAqoQ==} 982 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 983 | dependencies: 984 | p-locate: 6.0.0 985 | dev: true 986 | 987 | /lodash.camelcase/4.3.0: 988 | resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} 989 | dev: true 990 | 991 | /lodash.deburr/4.1.0: 992 | resolution: {integrity: sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==} 993 | dev: true 994 | 995 | /lodash.memoize/4.1.2: 996 | resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} 997 | dev: true 998 | 999 | /lodash.uniq/4.5.0: 1000 | resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} 1001 | dev: true 1002 | 1003 | /loose-envify/1.4.0: 1004 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 1005 | hasBin: true 1006 | dependencies: 1007 | js-tokens: 4.0.0 1008 | dev: true 1009 | 1010 | /mdn-data/2.0.14: 1011 | resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} 1012 | dev: true 1013 | 1014 | /merge2/1.4.1: 1015 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1016 | engines: {node: '>= 8'} 1017 | dev: true 1018 | 1019 | /micromatch/4.0.5: 1020 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 1021 | engines: {node: '>=8.6'} 1022 | dependencies: 1023 | braces: 3.0.2 1024 | picomatch: 2.3.1 1025 | dev: true 1026 | 1027 | /minimatch/3.1.2: 1028 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1029 | dependencies: 1030 | brace-expansion: 1.1.11 1031 | dev: true 1032 | 1033 | /mkdirp/1.0.4: 1034 | resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} 1035 | engines: {node: '>=10'} 1036 | hasBin: true 1037 | dev: true 1038 | 1039 | /mri/1.2.0: 1040 | resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 1041 | engines: {node: '>=4'} 1042 | dev: true 1043 | 1044 | /nanoid/3.3.4: 1045 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 1046 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1047 | hasBin: true 1048 | dev: true 1049 | 1050 | /natural-compare-lite/1.4.0: 1051 | resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} 1052 | dev: false 1053 | 1054 | /node-releases/2.0.4: 1055 | resolution: {integrity: sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==} 1056 | dev: true 1057 | 1058 | /normalize-path/3.0.0: 1059 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 1060 | engines: {node: '>=0.10.0'} 1061 | dev: true 1062 | 1063 | /normalize-url/6.1.0: 1064 | resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} 1065 | engines: {node: '>=10'} 1066 | dev: true 1067 | 1068 | /nth-check/2.0.1: 1069 | resolution: {integrity: sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==} 1070 | dependencies: 1071 | boolbase: 1.0.0 1072 | dev: true 1073 | 1074 | /object-assign/4.1.1: 1075 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 1076 | engines: {node: '>=0.10.0'} 1077 | dev: true 1078 | 1079 | /once/1.4.0: 1080 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 1081 | dependencies: 1082 | wrappy: 1.0.2 1083 | dev: true 1084 | 1085 | /p-limit/2.3.0: 1086 | resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} 1087 | engines: {node: '>=6'} 1088 | dependencies: 1089 | p-try: 2.2.0 1090 | dev: true 1091 | 1092 | /p-limit/4.0.0: 1093 | resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} 1094 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1095 | dependencies: 1096 | yocto-queue: 1.0.0 1097 | dev: true 1098 | 1099 | /p-locate/4.1.0: 1100 | resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} 1101 | engines: {node: '>=8'} 1102 | dependencies: 1103 | p-limit: 2.3.0 1104 | dev: true 1105 | 1106 | /p-locate/6.0.0: 1107 | resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} 1108 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1109 | dependencies: 1110 | p-limit: 4.0.0 1111 | dev: true 1112 | 1113 | /p-try/2.2.0: 1114 | resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} 1115 | engines: {node: '>=6'} 1116 | dev: true 1117 | 1118 | /path-exists/4.0.0: 1119 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1120 | engines: {node: '>=8'} 1121 | dev: true 1122 | 1123 | /path-exists/5.0.0: 1124 | resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} 1125 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1126 | dev: true 1127 | 1128 | /path-is-absolute/1.0.1: 1129 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 1130 | engines: {node: '>=0.10.0'} 1131 | dev: true 1132 | 1133 | /path-type/4.0.0: 1134 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1135 | engines: {node: '>=8'} 1136 | dev: true 1137 | 1138 | /picocolors/0.2.1: 1139 | resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} 1140 | dev: true 1141 | 1142 | /picocolors/1.0.0: 1143 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 1144 | dev: true 1145 | 1146 | /picomatch/2.3.1: 1147 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1148 | engines: {node: '>=8.6'} 1149 | dev: true 1150 | 1151 | /postcss-calc/8.2.4_postcss@8.4.16: 1152 | resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} 1153 | peerDependencies: 1154 | postcss: ^8.2.2 1155 | dependencies: 1156 | postcss: 8.4.16 1157 | postcss-selector-parser: 6.0.10 1158 | postcss-value-parser: 4.2.0 1159 | dev: true 1160 | 1161 | /postcss-colormin/5.3.0_postcss@8.4.16: 1162 | resolution: {integrity: sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==} 1163 | engines: {node: ^10 || ^12 || >=14.0} 1164 | peerDependencies: 1165 | postcss: ^8.2.15 1166 | dependencies: 1167 | browserslist: 4.20.3 1168 | caniuse-api: 3.0.0 1169 | colord: 2.9.2 1170 | postcss: 8.4.16 1171 | postcss-value-parser: 4.2.0 1172 | dev: true 1173 | 1174 | /postcss-convert-values/5.1.2_postcss@8.4.16: 1175 | resolution: {integrity: sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==} 1176 | engines: {node: ^10 || ^12 || >=14.0} 1177 | peerDependencies: 1178 | postcss: ^8.2.15 1179 | dependencies: 1180 | browserslist: 4.20.3 1181 | postcss: 8.4.16 1182 | postcss-value-parser: 4.2.0 1183 | dev: true 1184 | 1185 | /postcss-discard-comments/5.1.2_postcss@8.4.16: 1186 | resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} 1187 | engines: {node: ^10 || ^12 || >=14.0} 1188 | peerDependencies: 1189 | postcss: ^8.2.15 1190 | dependencies: 1191 | postcss: 8.4.16 1192 | dev: true 1193 | 1194 | /postcss-discard-duplicates/5.1.0_postcss@8.4.16: 1195 | resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} 1196 | engines: {node: ^10 || ^12 || >=14.0} 1197 | peerDependencies: 1198 | postcss: ^8.2.15 1199 | dependencies: 1200 | postcss: 8.4.16 1201 | dev: true 1202 | 1203 | /postcss-discard-empty/5.1.1_postcss@8.4.16: 1204 | resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} 1205 | engines: {node: ^10 || ^12 || >=14.0} 1206 | peerDependencies: 1207 | postcss: ^8.2.15 1208 | dependencies: 1209 | postcss: 8.4.16 1210 | dev: true 1211 | 1212 | /postcss-discard-overridden/5.1.0_postcss@8.4.16: 1213 | resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} 1214 | engines: {node: ^10 || ^12 || >=14.0} 1215 | peerDependencies: 1216 | postcss: ^8.2.15 1217 | dependencies: 1218 | postcss: 8.4.16 1219 | dev: true 1220 | 1221 | /postcss-merge-longhand/5.1.6_postcss@8.4.16: 1222 | resolution: {integrity: sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==} 1223 | engines: {node: ^10 || ^12 || >=14.0} 1224 | peerDependencies: 1225 | postcss: ^8.2.15 1226 | dependencies: 1227 | postcss: 8.4.16 1228 | postcss-value-parser: 4.2.0 1229 | stylehacks: 5.1.0_postcss@8.4.16 1230 | dev: true 1231 | 1232 | /postcss-merge-rules/5.1.2_postcss@8.4.16: 1233 | resolution: {integrity: sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==} 1234 | engines: {node: ^10 || ^12 || >=14.0} 1235 | peerDependencies: 1236 | postcss: ^8.2.15 1237 | dependencies: 1238 | browserslist: 4.20.3 1239 | caniuse-api: 3.0.0 1240 | cssnano-utils: 3.1.0_postcss@8.4.16 1241 | postcss: 8.4.16 1242 | postcss-selector-parser: 6.0.10 1243 | dev: true 1244 | 1245 | /postcss-minify-font-values/5.1.0_postcss@8.4.16: 1246 | resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} 1247 | engines: {node: ^10 || ^12 || >=14.0} 1248 | peerDependencies: 1249 | postcss: ^8.2.15 1250 | dependencies: 1251 | postcss: 8.4.16 1252 | postcss-value-parser: 4.2.0 1253 | dev: true 1254 | 1255 | /postcss-minify-gradients/5.1.1_postcss@8.4.16: 1256 | resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} 1257 | engines: {node: ^10 || ^12 || >=14.0} 1258 | peerDependencies: 1259 | postcss: ^8.2.15 1260 | dependencies: 1261 | colord: 2.9.2 1262 | cssnano-utils: 3.1.0_postcss@8.4.16 1263 | postcss: 8.4.16 1264 | postcss-value-parser: 4.2.0 1265 | dev: true 1266 | 1267 | /postcss-minify-params/5.1.3_postcss@8.4.16: 1268 | resolution: {integrity: sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==} 1269 | engines: {node: ^10 || ^12 || >=14.0} 1270 | peerDependencies: 1271 | postcss: ^8.2.15 1272 | dependencies: 1273 | browserslist: 4.20.3 1274 | cssnano-utils: 3.1.0_postcss@8.4.16 1275 | postcss: 8.4.16 1276 | postcss-value-parser: 4.2.0 1277 | dev: true 1278 | 1279 | /postcss-minify-selectors/5.2.1_postcss@8.4.16: 1280 | resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} 1281 | engines: {node: ^10 || ^12 || >=14.0} 1282 | peerDependencies: 1283 | postcss: ^8.2.15 1284 | dependencies: 1285 | postcss: 8.4.16 1286 | postcss-selector-parser: 6.0.10 1287 | dev: true 1288 | 1289 | /postcss-modules-extract-imports/1.1.0: 1290 | resolution: {integrity: sha512-zF9+UIEvtpeqMGxhpeT9XaIevQSrBBCz9fi7SwfkmjVacsSj8DY5eFVgn+wY8I9vvdDDwK5xC8Myq4UkoLFIkA==} 1291 | dependencies: 1292 | postcss: 6.0.1 1293 | dev: true 1294 | 1295 | /postcss-modules-extract-imports/3.0.0_postcss@8.4.16: 1296 | resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} 1297 | engines: {node: ^10 || ^12 || >= 14} 1298 | peerDependencies: 1299 | postcss: ^8.1.0 1300 | dependencies: 1301 | postcss: 8.4.16 1302 | dev: true 1303 | 1304 | /postcss-modules-local-by-default/1.2.0: 1305 | resolution: {integrity: sha512-X4cquUPIaAd86raVrBwO8fwRfkIdbwFu7CTfEOjiZQHVQwlHRSkTgH5NLDmMm5+1hQO8u6dZ+TOOJDbay1hYpA==} 1306 | dependencies: 1307 | css-selector-tokenizer: 0.7.3 1308 | postcss: 6.0.1 1309 | dev: true 1310 | 1311 | /postcss-modules-local-by-default/4.0.0_postcss@8.4.16: 1312 | resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} 1313 | engines: {node: ^10 || ^12 || >= 14} 1314 | peerDependencies: 1315 | postcss: ^8.1.0 1316 | dependencies: 1317 | icss-utils: 5.1.0_postcss@8.4.16 1318 | postcss: 8.4.16 1319 | postcss-selector-parser: 6.0.10 1320 | postcss-value-parser: 4.2.0 1321 | dev: true 1322 | 1323 | /postcss-modules-scope/1.1.0: 1324 | resolution: {integrity: sha512-LTYwnA4C1He1BKZXIx1CYiHixdSe9LWYVKadq9lK5aCCMkoOkFyZ7aigt+srfjlRplJY3gIol6KUNefdMQJdlw==} 1325 | dependencies: 1326 | css-selector-tokenizer: 0.7.3 1327 | postcss: 6.0.1 1328 | dev: true 1329 | 1330 | /postcss-modules-scope/3.0.0_postcss@8.4.16: 1331 | resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} 1332 | engines: {node: ^10 || ^12 || >= 14} 1333 | peerDependencies: 1334 | postcss: ^8.1.0 1335 | dependencies: 1336 | postcss: 8.4.16 1337 | postcss-selector-parser: 6.0.10 1338 | dev: true 1339 | 1340 | /postcss-modules-values/1.3.0: 1341 | resolution: {integrity: sha512-i7IFaR9hlQ6/0UgFuqM6YWaCfA1Ej8WMg8A5DggnH1UGKJvTV/ugqq/KaULixzzOi3T/tF6ClBXcHGCzdd5unA==} 1342 | dependencies: 1343 | icss-replace-symbols: 1.1.0 1344 | postcss: 6.0.1 1345 | dev: true 1346 | 1347 | /postcss-modules-values/4.0.0_postcss@8.4.16: 1348 | resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} 1349 | engines: {node: ^10 || ^12 || >= 14} 1350 | peerDependencies: 1351 | postcss: ^8.1.0 1352 | dependencies: 1353 | icss-utils: 5.1.0_postcss@8.4.16 1354 | postcss: 8.4.16 1355 | dev: true 1356 | 1357 | /postcss-modules/4.3.1_postcss@8.4.16: 1358 | resolution: {integrity: sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==} 1359 | peerDependencies: 1360 | postcss: ^8.0.0 1361 | dependencies: 1362 | generic-names: 4.0.0 1363 | icss-replace-symbols: 1.1.0 1364 | lodash.camelcase: 4.3.0 1365 | postcss: 8.4.16 1366 | postcss-modules-extract-imports: 3.0.0_postcss@8.4.16 1367 | postcss-modules-local-by-default: 4.0.0_postcss@8.4.16 1368 | postcss-modules-scope: 3.0.0_postcss@8.4.16 1369 | postcss-modules-values: 4.0.0_postcss@8.4.16 1370 | string-hash: 1.1.3 1371 | dev: true 1372 | 1373 | /postcss-normalize-charset/5.1.0_postcss@8.4.16: 1374 | resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} 1375 | engines: {node: ^10 || ^12 || >=14.0} 1376 | peerDependencies: 1377 | postcss: ^8.2.15 1378 | dependencies: 1379 | postcss: 8.4.16 1380 | dev: true 1381 | 1382 | /postcss-normalize-display-values/5.1.0_postcss@8.4.16: 1383 | resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} 1384 | engines: {node: ^10 || ^12 || >=14.0} 1385 | peerDependencies: 1386 | postcss: ^8.2.15 1387 | dependencies: 1388 | postcss: 8.4.16 1389 | postcss-value-parser: 4.2.0 1390 | dev: true 1391 | 1392 | /postcss-normalize-positions/5.1.1_postcss@8.4.16: 1393 | resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} 1394 | engines: {node: ^10 || ^12 || >=14.0} 1395 | peerDependencies: 1396 | postcss: ^8.2.15 1397 | dependencies: 1398 | postcss: 8.4.16 1399 | postcss-value-parser: 4.2.0 1400 | dev: true 1401 | 1402 | /postcss-normalize-repeat-style/5.1.1_postcss@8.4.16: 1403 | resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} 1404 | engines: {node: ^10 || ^12 || >=14.0} 1405 | peerDependencies: 1406 | postcss: ^8.2.15 1407 | dependencies: 1408 | postcss: 8.4.16 1409 | postcss-value-parser: 4.2.0 1410 | dev: true 1411 | 1412 | /postcss-normalize-string/5.1.0_postcss@8.4.16: 1413 | resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} 1414 | engines: {node: ^10 || ^12 || >=14.0} 1415 | peerDependencies: 1416 | postcss: ^8.2.15 1417 | dependencies: 1418 | postcss: 8.4.16 1419 | postcss-value-parser: 4.2.0 1420 | dev: true 1421 | 1422 | /postcss-normalize-timing-functions/5.1.0_postcss@8.4.16: 1423 | resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} 1424 | engines: {node: ^10 || ^12 || >=14.0} 1425 | peerDependencies: 1426 | postcss: ^8.2.15 1427 | dependencies: 1428 | postcss: 8.4.16 1429 | postcss-value-parser: 4.2.0 1430 | dev: true 1431 | 1432 | /postcss-normalize-unicode/5.1.0_postcss@8.4.16: 1433 | resolution: {integrity: sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==} 1434 | engines: {node: ^10 || ^12 || >=14.0} 1435 | peerDependencies: 1436 | postcss: ^8.2.15 1437 | dependencies: 1438 | browserslist: 4.20.3 1439 | postcss: 8.4.16 1440 | postcss-value-parser: 4.2.0 1441 | dev: true 1442 | 1443 | /postcss-normalize-url/5.1.0_postcss@8.4.16: 1444 | resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} 1445 | engines: {node: ^10 || ^12 || >=14.0} 1446 | peerDependencies: 1447 | postcss: ^8.2.15 1448 | dependencies: 1449 | normalize-url: 6.1.0 1450 | postcss: 8.4.16 1451 | postcss-value-parser: 4.2.0 1452 | dev: true 1453 | 1454 | /postcss-normalize-whitespace/5.1.1_postcss@8.4.16: 1455 | resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} 1456 | engines: {node: ^10 || ^12 || >=14.0} 1457 | peerDependencies: 1458 | postcss: ^8.2.15 1459 | dependencies: 1460 | postcss: 8.4.16 1461 | postcss-value-parser: 4.2.0 1462 | dev: true 1463 | 1464 | /postcss-ordered-values/5.1.3_postcss@8.4.16: 1465 | resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} 1466 | engines: {node: ^10 || ^12 || >=14.0} 1467 | peerDependencies: 1468 | postcss: ^8.2.15 1469 | dependencies: 1470 | cssnano-utils: 3.1.0_postcss@8.4.16 1471 | postcss: 8.4.16 1472 | postcss-value-parser: 4.2.0 1473 | dev: true 1474 | 1475 | /postcss-reduce-initial/5.1.0_postcss@8.4.16: 1476 | resolution: {integrity: sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==} 1477 | engines: {node: ^10 || ^12 || >=14.0} 1478 | peerDependencies: 1479 | postcss: ^8.2.15 1480 | dependencies: 1481 | browserslist: 4.20.3 1482 | caniuse-api: 3.0.0 1483 | postcss: 8.4.16 1484 | dev: true 1485 | 1486 | /postcss-reduce-transforms/5.1.0_postcss@8.4.16: 1487 | resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} 1488 | engines: {node: ^10 || ^12 || >=14.0} 1489 | peerDependencies: 1490 | postcss: ^8.2.15 1491 | dependencies: 1492 | postcss: 8.4.16 1493 | postcss-value-parser: 4.2.0 1494 | dev: true 1495 | 1496 | /postcss-selector-parser/6.0.10: 1497 | resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} 1498 | engines: {node: '>=4'} 1499 | dependencies: 1500 | cssesc: 3.0.0 1501 | util-deprecate: 1.0.2 1502 | dev: true 1503 | 1504 | /postcss-svgo/5.1.0_postcss@8.4.16: 1505 | resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} 1506 | engines: {node: ^10 || ^12 || >=14.0} 1507 | peerDependencies: 1508 | postcss: ^8.2.15 1509 | dependencies: 1510 | postcss: 8.4.16 1511 | postcss-value-parser: 4.2.0 1512 | svgo: 2.8.0 1513 | dev: true 1514 | 1515 | /postcss-unique-selectors/5.1.1_postcss@8.4.16: 1516 | resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} 1517 | engines: {node: ^10 || ^12 || >=14.0} 1518 | peerDependencies: 1519 | postcss: ^8.2.15 1520 | dependencies: 1521 | postcss: 8.4.16 1522 | postcss-selector-parser: 6.0.10 1523 | dev: true 1524 | 1525 | /postcss-value-parser/4.2.0: 1526 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 1527 | dev: true 1528 | 1529 | /postcss/6.0.1: 1530 | resolution: {integrity: sha512-VbGX1LQgQbf9l3cZ3qbUuC3hGqIEOGQFHAEHQ/Diaeo0yLgpgK5Rb8J+OcamIfQ9PbAU/fzBjVtQX3AhJHUvZw==} 1531 | engines: {node: '>=4.0.0'} 1532 | dependencies: 1533 | chalk: 1.1.3 1534 | source-map: 0.5.7 1535 | supports-color: 3.2.3 1536 | dev: true 1537 | 1538 | /postcss/7.0.39: 1539 | resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} 1540 | engines: {node: '>=6.0.0'} 1541 | dependencies: 1542 | picocolors: 0.2.1 1543 | source-map: 0.6.1 1544 | dev: true 1545 | 1546 | /postcss/8.4.16: 1547 | resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} 1548 | engines: {node: ^10 || ^12 || >=14} 1549 | dependencies: 1550 | nanoid: 3.3.4 1551 | picocolors: 1.0.0 1552 | source-map-js: 1.0.2 1553 | dev: true 1554 | 1555 | /preact/10.10.3: 1556 | resolution: {integrity: sha512-Gwwh0o531izatQQZu0yEX4mtfxVYsZJ4TT/o2VK3UZ/UuAWAWFnzsEfpZvad32vY3TKoRnSY2WqiDz2rH/viWQ==} 1557 | dev: false 1558 | 1559 | /prop-types/15.8.1: 1560 | resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} 1561 | dependencies: 1562 | loose-envify: 1.4.0 1563 | object-assign: 4.1.1 1564 | react-is: 16.13.1 1565 | dev: true 1566 | 1567 | /queue-microtask/1.2.3: 1568 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1569 | dev: true 1570 | 1571 | /react-is/16.13.1: 1572 | resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} 1573 | dev: true 1574 | 1575 | /react/16.14.0: 1576 | resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==} 1577 | engines: {node: '>=0.10.0'} 1578 | dependencies: 1579 | loose-envify: 1.4.0 1580 | object-assign: 4.1.1 1581 | prop-types: 15.8.1 1582 | dev: true 1583 | 1584 | /readdirp/3.6.0: 1585 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1586 | engines: {node: '>=8.10.0'} 1587 | dependencies: 1588 | picomatch: 2.3.1 1589 | dev: true 1590 | 1591 | /require-directory/2.1.1: 1592 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 1593 | engines: {node: '>=0.10.0'} 1594 | dev: true 1595 | 1596 | /require-main-filename/2.0.0: 1597 | resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} 1598 | dev: true 1599 | 1600 | /reusify/1.0.4: 1601 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1602 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1603 | dev: true 1604 | 1605 | /rev-hash/4.0.0: 1606 | resolution: {integrity: sha512-5w/auZRs65pf1AkZIbfICeorQfOCb6XVWaHmDEbkMyjmyRMxck+W0Erdj9zffuBRXxn5cbKfgmWQ9GpgR8dFZQ==} 1607 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1608 | dev: true 1609 | 1610 | /rgb-hex/4.0.0: 1611 | resolution: {integrity: sha512-Eg2ev5CiMBnQ9Gpflmqbwbso0CCdISqtVIow7OpYSLN1ULUv2jTB9YieS1DSSn/17AD7KkPWDPzSFzI4GSuu/Q==} 1612 | engines: {node: '>=12'} 1613 | dev: false 1614 | 1615 | /run-parallel/1.2.0: 1616 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1617 | dependencies: 1618 | queue-microtask: 1.2.3 1619 | dev: true 1620 | 1621 | /sade/1.8.1: 1622 | resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} 1623 | engines: {node: '>=6'} 1624 | dependencies: 1625 | mri: 1.2.0 1626 | dev: true 1627 | 1628 | /set-blocking/2.0.0: 1629 | resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} 1630 | dev: true 1631 | 1632 | /slash/4.0.0: 1633 | resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} 1634 | engines: {node: '>=12'} 1635 | dev: true 1636 | 1637 | /source-map-js/1.0.2: 1638 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 1639 | engines: {node: '>=0.10.0'} 1640 | dev: true 1641 | 1642 | /source-map/0.5.7: 1643 | resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} 1644 | engines: {node: '>=0.10.0'} 1645 | dev: true 1646 | 1647 | /source-map/0.6.1: 1648 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 1649 | engines: {node: '>=0.10.0'} 1650 | dev: true 1651 | 1652 | /stable/0.1.8: 1653 | resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} 1654 | deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' 1655 | dev: true 1656 | 1657 | /string-hash/1.1.3: 1658 | resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} 1659 | dev: true 1660 | 1661 | /string-width/4.2.3: 1662 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1663 | engines: {node: '>=8'} 1664 | dependencies: 1665 | emoji-regex: 8.0.0 1666 | is-fullwidth-code-point: 3.0.0 1667 | strip-ansi: 6.0.1 1668 | dev: true 1669 | 1670 | /strip-ansi/3.0.1: 1671 | resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} 1672 | engines: {node: '>=0.10.0'} 1673 | dependencies: 1674 | ansi-regex: 2.1.1 1675 | dev: true 1676 | 1677 | /strip-ansi/6.0.1: 1678 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1679 | engines: {node: '>=8'} 1680 | dependencies: 1681 | ansi-regex: 5.0.1 1682 | dev: true 1683 | 1684 | /stylehacks/5.1.0_postcss@8.4.16: 1685 | resolution: {integrity: sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==} 1686 | engines: {node: ^10 || ^12 || >=14.0} 1687 | peerDependencies: 1688 | postcss: ^8.2.15 1689 | dependencies: 1690 | browserslist: 4.20.3 1691 | postcss: 8.4.16 1692 | postcss-selector-parser: 6.0.10 1693 | dev: true 1694 | 1695 | /supports-color/2.0.0: 1696 | resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} 1697 | engines: {node: '>=0.8.0'} 1698 | dev: true 1699 | 1700 | /supports-color/3.2.3: 1701 | resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} 1702 | engines: {node: '>=0.8.0'} 1703 | dependencies: 1704 | has-flag: 1.0.0 1705 | dev: true 1706 | 1707 | /supports-color/7.2.0: 1708 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1709 | engines: {node: '>=8'} 1710 | dependencies: 1711 | has-flag: 4.0.0 1712 | dev: true 1713 | 1714 | /svgo/2.8.0: 1715 | resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} 1716 | engines: {node: '>=10.13.0'} 1717 | hasBin: true 1718 | dependencies: 1719 | '@trysound/sax': 0.2.0 1720 | commander: 7.2.0 1721 | css-select: 4.3.0 1722 | css-tree: 1.1.3 1723 | csso: 4.2.0 1724 | picocolors: 1.0.0 1725 | stable: 0.1.8 1726 | dev: true 1727 | 1728 | /temp-dir/2.0.0: 1729 | resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} 1730 | engines: {node: '>=8'} 1731 | dev: true 1732 | 1733 | /temp-write/5.0.0: 1734 | resolution: {integrity: sha512-cJhnzBW7DjNox7VcZDXeNlQSkIh3mX/h+M0n0Fh+zgT7YAHwI9c+OngKx4MCiQCVx9iXxV104xYlJgDBCCtawA==} 1735 | engines: {node: '>=12'} 1736 | dependencies: 1737 | graceful-fs: 4.2.10 1738 | is-stream: 2.0.1 1739 | temp-dir: 2.0.0 1740 | uuid: 8.3.2 1741 | dev: true 1742 | 1743 | /tempy/3.0.0: 1744 | resolution: {integrity: sha512-B2I9X7+o2wOaW4r/CWMkpOO9mdiTRCxXNgob6iGvPmfPWgH/KyUD6Uy5crtWBxIBe3YrNZKR2lSzv1JJKWD4vA==} 1745 | engines: {node: '>=14.16'} 1746 | dependencies: 1747 | is-stream: 3.0.0 1748 | temp-dir: 2.0.0 1749 | type-fest: 2.12.2 1750 | unique-string: 3.0.0 1751 | dev: true 1752 | 1753 | /to-regex-range/5.0.1: 1754 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1755 | engines: {node: '>=8.0'} 1756 | dependencies: 1757 | is-number: 7.0.0 1758 | dev: true 1759 | 1760 | /type-fest/1.4.0: 1761 | resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} 1762 | engines: {node: '>=10'} 1763 | dev: true 1764 | 1765 | /type-fest/2.12.2: 1766 | resolution: {integrity: sha512-qt6ylCGpLjZ7AaODxbpyBZSs9fCI9SkL3Z9q2oxMBQhs/uyY+VD8jHA8ULCGmWQJlBgqvO3EJeAngOHD8zQCrQ==} 1767 | engines: {node: '>=12.20'} 1768 | dev: true 1769 | 1770 | /typed-css-modules/0.7.2: 1771 | resolution: {integrity: sha512-R3guXrQ8ry/yhlfvNmkVY4J3+FtKaEdwqrvgSvFpVY0ieYQHqhhBW0RwfE4hnG4m29Ef/4IE0tBsk/UKplmJkA==} 1772 | engines: {node: '>=12.0.0'} 1773 | hasBin: true 1774 | dependencies: 1775 | '@types/css-modules-loader-core': 1.1.0 1776 | camelcase: 6.3.0 1777 | chalk: 4.1.2 1778 | chokidar: 3.5.3 1779 | css-modules-loader-core: 1.1.0 1780 | glob: 7.2.0 1781 | is-there: 4.5.1 1782 | mkdirp: 1.0.4 1783 | yargs: 15.4.1 1784 | dev: true 1785 | 1786 | /typescript/4.6.4: 1787 | resolution: {integrity: sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==} 1788 | engines: {node: '>=4.2.0'} 1789 | hasBin: true 1790 | dev: true 1791 | 1792 | /unique-string/3.0.0: 1793 | resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} 1794 | engines: {node: '>=12'} 1795 | dependencies: 1796 | crypto-random-string: 4.0.0 1797 | dev: true 1798 | 1799 | /universalify/2.0.0: 1800 | resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} 1801 | engines: {node: '>= 10.0.0'} 1802 | dev: true 1803 | 1804 | /util-deprecate/1.0.2: 1805 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 1806 | dev: true 1807 | 1808 | /uuid/8.3.2: 1809 | resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} 1810 | hasBin: true 1811 | dev: true 1812 | 1813 | /which-module/2.0.0: 1814 | resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} 1815 | dev: true 1816 | 1817 | /wrap-ansi/6.2.0: 1818 | resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} 1819 | engines: {node: '>=8'} 1820 | dependencies: 1821 | ansi-styles: 4.3.0 1822 | string-width: 4.2.3 1823 | strip-ansi: 6.0.1 1824 | dev: true 1825 | 1826 | /wrappy/1.0.2: 1827 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1828 | dev: true 1829 | 1830 | /y18n/4.0.3: 1831 | resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} 1832 | dev: true 1833 | 1834 | /yaml/1.10.2: 1835 | resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} 1836 | engines: {node: '>= 6'} 1837 | dev: true 1838 | 1839 | /yargs-parser/18.1.3: 1840 | resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} 1841 | engines: {node: '>=6'} 1842 | dependencies: 1843 | camelcase: 5.3.1 1844 | decamelize: 1.2.0 1845 | dev: true 1846 | 1847 | /yargs/15.4.1: 1848 | resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} 1849 | engines: {node: '>=8'} 1850 | dependencies: 1851 | cliui: 6.0.0 1852 | decamelize: 1.2.0 1853 | find-up: 4.1.0 1854 | get-caller-file: 2.0.5 1855 | require-directory: 2.1.1 1856 | require-main-filename: 2.0.0 1857 | set-blocking: 2.0.0 1858 | string-width: 4.2.3 1859 | which-module: 2.0.0 1860 | y18n: 4.0.3 1861 | yargs-parser: 18.1.3 1862 | dev: true 1863 | 1864 | /yocto-queue/1.0.0: 1865 | resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} 1866 | engines: {node: '>=12.20'} 1867 | dev: true 1868 | -------------------------------------------------------------------------------- /src/commands/showPanel/showPanel-main.ts: -------------------------------------------------------------------------------- 1 | import { on, emit, showUI } from "@create-figma-plugin/utilities"; 2 | import { 3 | trimSelectedNodes, 4 | resolveTextNodeFromSelectedNode, 5 | getFontMetricsForTextNode, 6 | } from "../../core"; 7 | import { 8 | TrimSelectionHandler, 9 | UpdateFontSizeHandler, 10 | UpdateLineHeightHandler, 11 | SelectionChangedHandler, 12 | SelectionData, 13 | } from "../../types"; 14 | 15 | const lineHeightDelimiter = "|"; 16 | 17 | function stringifyLineHeight(lineHeight: LineHeight): string { 18 | return [ 19 | lineHeight.unit, 20 | "value" in lineHeight ? String(lineHeight.value) : null, 21 | ] 22 | .filter((value) => value !== null) 23 | .join(lineHeightDelimiter); 24 | } 25 | 26 | function parseLineHeight(lineHeight: string): LineHeight { 27 | const [unit, value] = lineHeight.split(lineHeightDelimiter); 28 | 29 | if (unit === "AUTO") { 30 | return { unit: "AUTO" }; 31 | } 32 | 33 | if (unit === "PERCENT" || unit === "PIXELS") { 34 | return { unit, value: parseInt(value) }; 35 | } 36 | 37 | throw new Error("Invalid line height string"); 38 | } 39 | 40 | function getSelectionData(): SelectionData { 41 | const fontSizes = new Set(); 42 | const stringifiedLineHeights = new Set(); 43 | const autoLineHeights = new Set(); 44 | let hasTextSelected = false; 45 | let hasSupportedFontSelected = false; 46 | 47 | figma.currentPage.selection.forEach((selectedNode) => { 48 | const textNode = resolveTextNodeFromSelectedNode(selectedNode); 49 | 50 | if (textNode) { 51 | hasTextSelected = true; 52 | 53 | const fontMetrics = getFontMetricsForTextNode(textNode); 54 | 55 | if (!fontMetrics) { 56 | return; 57 | } 58 | 59 | hasSupportedFontSelected = true; 60 | 61 | if (textNode.fontSize !== figma.mixed) { 62 | fontSizes.add(textNode.fontSize); 63 | } 64 | 65 | if (textNode.lineHeight !== figma.mixed) { 66 | stringifiedLineHeights.add(stringifyLineHeight(textNode.lineHeight)); 67 | } 68 | 69 | if ( 70 | textNode.fontSize !== figma.mixed && 71 | textNode.lineHeight !== figma.mixed 72 | ) { 73 | const { descent, ascent, lineGap, unitsPerEm } = fontMetrics; 74 | const absoluteDescent = Math.abs(descent); 75 | const contentArea = ascent + lineGap + absoluteDescent; 76 | const lineHeightScale = contentArea / unitsPerEm; 77 | autoLineHeights.add(Math.round(lineHeightScale * textNode.fontSize)); 78 | } 79 | } 80 | }); 81 | 82 | return { 83 | fontSize: fontSizes.size === 1 ? Array.from(fontSizes)[0] : undefined, 84 | lineHeight: 85 | stringifiedLineHeights.size === 1 86 | ? parseLineHeight(Array.from(stringifiedLineHeights)[0]) 87 | : undefined, 88 | autoLineHeight: 89 | autoLineHeights.size === 1 ? Array.from(autoLineHeights)[0] : undefined, 90 | hasTextSelected, 91 | hasSupportedFontSelected, 92 | }; 93 | } 94 | 95 | export default function () { 96 | on("TRIM_SELECTION", () => trimSelectedNodes()); 97 | 98 | on( 99 | "UPDATE_LINE_HEIGHT_FOR_SELECTION", 100 | (lineHeight) => { 101 | trimSelectedNodes({ lineHeight }); 102 | } 103 | ); 104 | 105 | on("UPDATE_FONT_SIZE_FOR_SELECTION", (fontSize) => { 106 | trimSelectedNodes({ fontSize }); 107 | }); 108 | 109 | figma.on("selectionchange", () => { 110 | const { 111 | fontSize, 112 | lineHeight, 113 | autoLineHeight, 114 | hasTextSelected, 115 | hasSupportedFontSelected, 116 | } = getSelectionData(); 117 | emit("SELECTION_CHANGED", { 118 | fontSize, 119 | lineHeight, 120 | autoLineHeight, 121 | hasTextSelected, 122 | hasSupportedFontSelected, 123 | }); 124 | }); 125 | 126 | showUI( 127 | { width: 240, height: 108, title: "Leading Trim" }, 128 | getSelectionData() 129 | ); 130 | } 131 | -------------------------------------------------------------------------------- /src/commands/showPanel/showPanel-ui.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Button, 3 | Columns, 4 | Container, 5 | IconLineHeight32, 6 | render, 7 | Textbox, 8 | VerticalSpace, 9 | } from "@create-figma-plugin/ui"; 10 | import { emit, on } from "@create-figma-plugin/utilities"; 11 | import { h } from "preact"; 12 | import { useCallback, useEffect, useState } from "preact/hooks"; 13 | import { 14 | SelectionChangedHandler, 15 | SelectionData, 16 | TrimSelectionHandler, 17 | UpdateFontSizeHandler, 18 | UpdateLineHeightHandler, 19 | } from "../../types"; 20 | 21 | function stringifyLineHeight(lineHeight: LineHeight) { 22 | if (lineHeight.unit === "AUTO") { 23 | return "Auto"; 24 | } 25 | 26 | return `${lineHeight.value}${lineHeight.unit === "PERCENT" ? "%" : ""}`; 27 | } 28 | 29 | function parseLineHeight(lineHeightString: string): LineHeight | null { 30 | if (lineHeightString === "Auto") { 31 | return { unit: "AUTO" } as const; 32 | } 33 | 34 | if (/^[1-9?][0-9]*$/.test(lineHeightString)) { 35 | return { unit: "PIXELS", value: parseInt(lineHeightString) } as const; 36 | } 37 | 38 | if (/^[1-9?][0-9]*%$/.test(lineHeightString)) { 39 | return { unit: "PERCENT", value: parseInt(lineHeightString) } as const; 40 | } 41 | 42 | return null; 43 | } 44 | 45 | export default render(function Plugin({ 46 | fontSize: initialFontSize, 47 | lineHeight: initialLineHeight, 48 | autoLineHeight: initialAutoLineHeight, 49 | hasTextSelected: initialHasTextSelected, 50 | hasSupportedFontSelected: initialHasSupportedFontSelected, 51 | }: SelectionData) { 52 | const [fontSizeFieldValue, setFontSizeFieldValue] = useState( 53 | initialFontSize ? String(initialFontSize) : "" 54 | ); 55 | const [lineHeightFieldValue, setLineHeightFieldValue] = useState(() => 56 | initialLineHeight ? stringifyLineHeight(initialLineHeight) : "" 57 | ); 58 | const [isLineHeightFieldFocused, setIsLineHeightFieldFocused] = 59 | useState(false); 60 | const [autoLineHeightPlaceholder, setAutoLineHeightPlaceholder] = useState( 61 | initialAutoLineHeight ? String(initialAutoLineHeight) : "" 62 | ); 63 | const [hasTextSelected, setHasTextSelected] = useState( 64 | initialHasTextSelected 65 | ); 66 | const [hasSupportedFontSelected, setHasSupportedFontSelected] = useState( 67 | initialHasSupportedFontSelected 68 | ); 69 | 70 | const handleTrimButtonClick = useCallback(function () { 71 | emit("TRIM_SELECTION"); 72 | }, []); 73 | 74 | useEffect(() => { 75 | on( 76 | "SELECTION_CHANGED", 77 | ({ 78 | fontSize, 79 | lineHeight, 80 | autoLineHeight, 81 | hasTextSelected, 82 | hasSupportedFontSelected, 83 | }) => { 84 | setFontSizeFieldValue(fontSize ? String(fontSize) : ""); 85 | setLineHeightFieldValue( 86 | lineHeight ? stringifyLineHeight(lineHeight) : "" 87 | ); 88 | setHasTextSelected(hasTextSelected); 89 | setHasSupportedFontSelected(hasSupportedFontSelected); 90 | setAutoLineHeightPlaceholder( 91 | autoLineHeight ? String(autoLineHeight) : "" 92 | ); 93 | } 94 | ); 95 | }, []); 96 | 97 | return ( 98 | 99 | 100 | 101 |
{ 103 | // We need this onKeyDown handler attached to a parent div 104 | // because Textbox doesn't support the onKeyDown event. 105 | if (event.key === "ArrowUp" || event.key === "ArrowDown") { 106 | event.preventDefault(); 107 | 108 | if ( 109 | event.target instanceof HTMLInputElement && 110 | /^[1-9][0-9]*$/.test(event.target.value) 111 | ) { 112 | const newFontSize = Math.max( 113 | 1, 114 | parseInt(event.target.value) + 115 | (event.shiftKey ? 10 : 1) * 116 | (event.key === "ArrowDown" ? -1 : 1) 117 | ); 118 | setFontSizeFieldValue(String(newFontSize)); 119 | emit( 120 | "UPDATE_FONT_SIZE_FOR_SELECTION", 121 | newFontSize 122 | ); 123 | } 124 | } 125 | }} 126 | > 127 | { 130 | setFontSizeFieldValue(event.currentTarget.value); 131 | }} 132 | validateOnBlur={(value) => { 133 | if (!/^[1-9][0-9]*$/.test(value)) { 134 | return false; 135 | } 136 | 137 | setFontSizeFieldValue(value); 138 | emit( 139 | "UPDATE_FONT_SIZE_FOR_SELECTION", 140 | parseInt(value) 141 | ); 142 | 143 | return true; 144 | }} 145 | value={fontSizeFieldValue} 146 | /> 147 |
148 |
{ 150 | // We need this onFocusCapture handler attached to a parent div 151 | // because Textbox doesn't support the onFocus event. 152 | if (event.target instanceof HTMLInputElement) { 153 | if (event.target.value === "Auto") { 154 | setIsLineHeightFieldFocused(true); 155 | setLineHeightFieldValue(""); 156 | } 157 | } 158 | }} 159 | onKeyDown={(event) => { 160 | // We need this event handler attached to a parent div 161 | // because Textbox doesn't support the onKeyDown event. 162 | if (event.key === "ArrowUp" || event.key === "ArrowDown") { 163 | event.preventDefault(); 164 | 165 | if (event.target instanceof HTMLInputElement) { 166 | const parsedLineHeight = parseLineHeight( 167 | event.target.value === "" && autoLineHeightPlaceholder 168 | ? autoLineHeightPlaceholder 169 | : event.target.value 170 | ); 171 | if (parsedLineHeight && parsedLineHeight.unit !== "AUTO") { 172 | const newLineHeight = { 173 | ...parsedLineHeight, 174 | value: Math.max( 175 | 1, 176 | parsedLineHeight.value + 177 | (event.shiftKey ? 10 : 1) * 178 | (event.key === "ArrowDown" ? -1 : 1) 179 | ), 180 | }; 181 | setLineHeightFieldValue(stringifyLineHeight(newLineHeight)); 182 | emit( 183 | "UPDATE_LINE_HEIGHT_FOR_SELECTION", 184 | newLineHeight 185 | ); 186 | } 187 | } 188 | } 189 | }} 190 | > 191 | } 193 | disabled={!hasSupportedFontSelected} 194 | onInput={(event) => { 195 | setLineHeightFieldValue(event.currentTarget.value); 196 | }} 197 | validateOnBlur={(value) => { 198 | setIsLineHeightFieldFocused(false); 199 | 200 | const lowerCaseValue = value.toLocaleLowerCase().trim(); 201 | 202 | if ( 203 | lowerCaseValue === "" || 204 | lowerCaseValue === "a" || 205 | lowerCaseValue === "au" || 206 | lowerCaseValue === "aut" || 207 | lowerCaseValue === "auto" 208 | ) { 209 | emit( 210 | "UPDATE_LINE_HEIGHT_FOR_SELECTION", 211 | { unit: "AUTO" } 212 | ); 213 | return "Auto"; 214 | } 215 | 216 | const parsedLineHeight = parseLineHeight(value); 217 | 218 | if (parsedLineHeight === null) { 219 | return false; 220 | } 221 | 222 | emit( 223 | "UPDATE_LINE_HEIGHT_FOR_SELECTION", 224 | parsedLineHeight 225 | ); 226 | 227 | return true; 228 | }} 229 | placeholder={ 230 | isLineHeightFieldFocused && lineHeightFieldValue === "" 231 | ? autoLineHeightPlaceholder 232 | : undefined 233 | } 234 | value={lineHeightFieldValue} 235 | /> 236 |
237 |
238 | 239 | 247 | 248 |
249 | ); 250 | }); 251 | -------------------------------------------------------------------------------- /src/commands/trimSelection.ts: -------------------------------------------------------------------------------- 1 | import { trimSelectedNodes } from "../core"; 2 | 3 | export default async function () { 4 | await trimSelectedNodes(); 5 | figma.closePlugin(); 6 | } 7 | -------------------------------------------------------------------------------- /src/core.ts: -------------------------------------------------------------------------------- 1 | import { FontMetrics, precomputeValues } from "@capsizecss/core"; 2 | import { loadFontsAsync } from "@create-figma-plugin/utilities"; 3 | import { fontMetricsByFamilyName } from "./metrics/fontMetricsByFamilyName"; 4 | 5 | function isNodeOwned(node: SceneNode) { 6 | return node.getPluginData("owned") === "true"; 7 | } 8 | 9 | function markNodeAsOwned(node: SceneNode) { 10 | node.setPluginData("owned", "true"); 11 | } 12 | 13 | export function getFontMetricsForTextNode( 14 | textNode: TextNode 15 | ): FontMetrics | null { 16 | if ( 17 | textNode.fontName !== figma.mixed && 18 | textNode.fontName.family in fontMetricsByFamilyName 19 | ) { 20 | return fontMetricsByFamilyName[textNode.fontName.family]; 21 | } 22 | 23 | return null; 24 | } 25 | 26 | export function resolveTextNodeFromSelectedNode( 27 | sceneNode: SceneNode 28 | ): TextNode | undefined { 29 | const textNode = 30 | sceneNode.type === "TEXT" 31 | ? sceneNode 32 | : sceneNode.type === "FRAME" && 33 | isNodeOwned(sceneNode) && 34 | sceneNode.children.length === 1 && 35 | sceneNode.children[0].type === "TEXT" 36 | ? sceneNode.children[0] 37 | : undefined; 38 | 39 | return textNode; 40 | } 41 | 42 | function resolveLineHeightFromTextNode(textNode: TextNode): number | undefined { 43 | if ( 44 | textNode.lineHeight === figma.mixed || 45 | textNode.fontSize === figma.mixed 46 | ) { 47 | return undefined; 48 | } 49 | 50 | return textNode.lineHeight.unit !== "AUTO" 51 | ? textNode.lineHeight.unit === "PERCENT" 52 | ? textNode.fontSize * (textNode.lineHeight.value / 100) 53 | : textNode.lineHeight.value 54 | : undefined; 55 | } 56 | 57 | function isNodeWithinFrame(node: BaseNode): boolean { 58 | let parentNode: BaseNode | null = node.parent; 59 | 60 | while (parentNode) { 61 | if (parentNode.type === "FRAME") { 62 | return true; 63 | } 64 | 65 | parentNode = parentNode.parent; 66 | } 67 | 68 | return false; 69 | } 70 | 71 | export async function trimSelectedNodes({ 72 | fontSize, 73 | lineHeight, 74 | }: { 75 | fontSize?: number; 76 | lineHeight?: LineHeight; 77 | } = {}) { 78 | await loadFontsAsync( 79 | figma.currentPage.selection.reduce( 80 | (acc, selection) => [ 81 | ...acc, 82 | selection, 83 | ...("children" in selection ? [...selection.children] : []), 84 | ], 85 | [] as SceneNode[] 86 | ) 87 | ); 88 | 89 | figma.currentPage.selection = figma.currentPage.selection.map( 90 | (selectedNode): SceneNode => { 91 | const textNode = resolveTextNodeFromSelectedNode(selectedNode); 92 | 93 | if (!textNode) { 94 | return selectedNode; 95 | } 96 | 97 | const fontFamilies: Set = 98 | textNode.fontName === figma.mixed 99 | ? new Set( 100 | textNode 101 | .getRangeAllFontNames(0, textNode.characters.length) 102 | .map((fontName) => fontName.family) 103 | ) 104 | : new Set([textNode.fontName.family]); 105 | 106 | function notify(message: string) { 107 | figma.notify(message, { timeout: 5000 }); 108 | } 109 | 110 | if (fontFamilies.size > 1) { 111 | notify("Leading cannot be trimmed from text with mixed fonts."); 112 | return selectedNode; 113 | } 114 | 115 | const fontFamily = Array.from(fontFamilies)[0]; 116 | if (!(fontFamily in fontMetricsByFamilyName)) { 117 | notify( 118 | `Leading cannot be trimmed from font "${fontFamily}" as it is not currently supported.` 119 | ); 120 | return selectedNode; 121 | } 122 | 123 | if (textNode.fontSize === figma.mixed) { 124 | notify("Leading cannot be trimmed from text with mixed sizes."); 125 | return selectedNode; 126 | } 127 | 128 | if (textNode.lineHeight === figma.mixed) { 129 | notify("Leading cannot be trimmed from text with mixed line heights."); 130 | return selectedNode; 131 | } 132 | 133 | if (textNode.textAutoResize === "NONE") { 134 | textNode.textAutoResize = "HEIGHT"; 135 | } 136 | 137 | let frameYBeforeUpdate: number | null = null; 138 | const isUpdatingLineHeight = lineHeight; 139 | 140 | if (fontSize || isUpdatingLineHeight) { 141 | frameYBeforeUpdate = 142 | textNode.parent?.type === "FRAME" && isNodeOwned(textNode.parent) 143 | ? textNode.parent.y 144 | : null; 145 | } 146 | 147 | if (fontSize) { 148 | textNode.fontSize = fontSize; 149 | } 150 | 151 | if (isUpdatingLineHeight) { 152 | textNode.lineHeight = lineHeight; 153 | } 154 | 155 | const options = { 156 | fontSize: textNode.fontSize, 157 | leading: resolveLineHeightFromTextNode(textNode), 158 | fontMetrics: fontMetricsByFamilyName[fontFamily], 159 | }; 160 | 161 | const capsizeValues = precomputeValues(options); 162 | const marginTop = Math.round( 163 | parseFloat(capsizeValues.capHeightTrim) * textNode.fontSize 164 | ); 165 | 166 | const marginBottom = Math.round( 167 | parseFloat(capsizeValues.baselineTrim) * textNode.fontSize 168 | ); 169 | 170 | // Add new margins 171 | const parent = textNode.parent ?? figma.currentPage; 172 | const index = parent.children.indexOf(textNode); 173 | 174 | const isFirstRun = parent.type !== "FRAME" || !isNodeOwned(parent); 175 | const frame = isFirstRun ? figma.createFrame() : (parent as FrameNode); 176 | markNodeAsOwned(frame); 177 | 178 | frame.name = isNodeWithinFrame(textNode) ? "Leading Trim" : " "; // This ensures a frame name is not visible in the UI 179 | frame.fills = []; 180 | frame.clipsContent = false; // Allows ascenders/descenders to be visible 181 | frame.resize(textNode.width, textNode.height + marginTop + marginBottom); 182 | 183 | if (isFirstRun) { 184 | frame.appendChild(textNode); 185 | frame.x = textNode.x; 186 | frame.y = textNode.y - marginTop; 187 | parent.insertChild(index, frame); 188 | } else { 189 | frame.x = frame.x + textNode.x; 190 | frame.y = frameYBeforeUpdate ?? frame.y + textNode.y - marginTop; 191 | } 192 | 193 | textNode.x = 0; 194 | textNode.y = marginTop; 195 | 196 | return frame; 197 | } 198 | ); 199 | } 200 | -------------------------------------------------------------------------------- /src/metrics/fontMetricsByFamilyName.ts: -------------------------------------------------------------------------------- 1 | import { FontMetrics } from "@capsizecss/core"; 2 | import googleFontMetrics from "./googleFonts.json"; 3 | import systemFontMetrics from "./systemFonts.json"; 4 | 5 | export const fontMetricsByFamilyName: Record = { 6 | ...googleFontMetrics, 7 | ...systemFontMetrics, 8 | }; 9 | -------------------------------------------------------------------------------- /src/metrics/systemFonts.json: -------------------------------------------------------------------------------- 1 | { 2 | "Arial": { 3 | "capHeight": 1467, 4 | "ascent": 1854, 5 | "descent": -434, 6 | "lineGap": 67, 7 | "unitsPerEm": 2048 8 | }, 9 | "SF Mono": { 10 | "capHeight": 1443, 11 | "ascent": 1950, 12 | "descent": -494, 13 | "lineGap": 0, 14 | "unitsPerEm": 2048 15 | }, 16 | "SF Pro": { 17 | "capHeight": 1443, 18 | "ascent": 1950, 19 | "descent": -494, 20 | "lineGap": 0, 21 | "unitsPerEm": 2048 22 | }, 23 | "SF Pro Display": { 24 | "capHeight": 1443, 25 | "ascent": 1950, 26 | "descent": -494, 27 | "lineGap": 0, 28 | "unitsPerEm": 2048 29 | }, 30 | "SF Pro Rounded": { 31 | "capHeight": 1443, 32 | "ascent": 1950, 33 | "descent": -494, 34 | "lineGap": 0, 35 | "unitsPerEm": 2048 36 | }, 37 | "SF Pro Text": { 38 | "capHeight": 1443, 39 | "ascent": 1950, 40 | "descent": -494, 41 | "lineGap": 0, 42 | "unitsPerEm": 2048 43 | }, 44 | "Roboto": { 45 | "capHeight": 1456, 46 | "ascent": 1900, 47 | "descent": -500, 48 | "lineGap": 0, 49 | "unitsPerEm": 2048 50 | }, 51 | "Segoe UI": { 52 | "capHeight": 1434, 53 | "ascent": 2210, 54 | "descent": -514, 55 | "lineGap": 0, 56 | "unitsPerEm": 2048 57 | }, 58 | "Oxygen": { 59 | "capHeight": 1468, 60 | "ascent": 2103, 61 | "descent": -483, 62 | "lineGap": 0, 63 | "unitsPerEm": 2048 64 | }, 65 | "Helvetica": { 66 | "capHeight": 1469, 67 | "ascent": 1577, 68 | "descent": -471, 69 | "lineGap": 0, 70 | "unitsPerEm": 2048 71 | }, 72 | "Helvetica Neue": { 73 | "capHeight": 714, 74 | "ascent": 952, 75 | "descent": -213, 76 | "lineGap": 28, 77 | "unitsPerEm": 1000 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { EventHandler } from "@create-figma-plugin/utilities"; 2 | 3 | export type SelectionData = { 4 | fontSize?: number; 5 | lineHeight?: LineHeight; 6 | autoLineHeight?: number; 7 | hasTextSelected: boolean; 8 | hasSupportedFontSelected: boolean; 9 | }; 10 | 11 | export interface TrimSelectionHandler extends EventHandler { 12 | name: "TRIM_SELECTION"; 13 | handler: () => void; 14 | } 15 | 16 | export interface UpdateFontSizeHandler extends EventHandler { 17 | name: "UPDATE_FONT_SIZE_FOR_SELECTION"; 18 | handler: (fontSize: number) => void; 19 | } 20 | 21 | export interface UpdateLineHeightHandler extends EventHandler { 22 | name: "UPDATE_LINE_HEIGHT_FOR_SELECTION"; 23 | handler: (lineHeight: LineHeight) => void; 24 | } 25 | 26 | export interface SelectionChangedHandler extends EventHandler { 27 | name: "SELECTION_CHANGED"; 28 | handler: (selectionData: SelectionData) => void; 29 | } 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@create-figma-plugin/tsconfig", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@figma", "node_modules/@types"], 5 | "resolveJsonModule": true 6 | }, 7 | "include": ["src/**/*.ts", "src/**/*.tsx"] 8 | } 9 | --------------------------------------------------------------------------------