├── .gitignore ├── README.md ├── __tests__ ├── babel.spec.ts ├── config.spec.ts ├── rule.spec.ts ├── run.spec.ts ├── svgxml.spec.ts ├── transfomer.spec.ts └── uno.config.ts ├── doc └── image-20230322211848407.png ├── package.json ├── pnpm-lock.yaml ├── src ├── babel.ts ├── hoc │ ├── hub.ts │ ├── icon.tsx │ ├── index.tsx │ └── uno-styled.tsx ├── index.ts ├── preset-react-native │ ├── _theme │ │ ├── colors.ts │ │ ├── default.ts │ │ ├── filters.ts │ │ ├── font.ts │ │ ├── index.ts │ │ ├── misc.ts │ │ ├── preflight.ts │ │ ├── size.ts │ │ └── types.ts │ ├── _utils │ │ ├── colors.ts │ │ ├── handlers │ │ │ ├── handlers.ts │ │ │ ├── index.ts │ │ │ └── regex.ts │ │ ├── index.ts │ │ ├── mappings.ts │ │ ├── utilities.ts │ │ └── variants.ts │ ├── index.ts │ ├── rules │ │ ├── align.ts │ │ ├── border.ts │ │ ├── color.ts │ │ ├── decoration.ts │ │ ├── default.ts │ │ ├── flex.ts │ │ ├── gap.ts │ │ ├── index.ts │ │ ├── layout.ts │ │ ├── position.ts │ │ ├── size.ts │ │ ├── spacing.ts │ │ ├── static.ts │ │ ├── transform.ts │ │ ├── transition.ts │ │ ├── typography.ts │ │ └── variables.ts │ ├── theme.ts │ └── utils.ts ├── preset.ts ├── transformer │ ├── index.ts │ ├── style-processor.ts │ ├── style-transformer.ts │ └── svg-transformer.ts ├── transformerEntry.ts └── type.d.ts ├── tsconfig.json ├── tsup.config.ts ├── type.d.ts └── vitest.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | /dist 25 | /.vscode 26 | /.idea 27 | 28 | .npmrc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Uno With React Native 2 | Using UnoCSS in a React Native project [Demo](https://github.com/eagermko/unonative-demo) 3 | 4 | ![image-20230322211848407](doc/image-20230322211848407.png) 5 | 6 | ## Setup 7 | 8 | ```bash 9 | yarn add unonative 10 | ``` 11 | 12 | ### Basic setup 13 | 14 | 15 | 1. Uno Config for vscode plugin auto completion 16 | 17 | ```ts 18 | // uno.config.ts 19 | import { defineConfig } from 'unocss'; 20 | import { preset } from 'unonative/preset'; 21 | 22 | export default defineConfig({ 23 | presets: [...preset], 24 | }); 25 | ``` 26 | 27 | 2. Transform JsxElement with className to Wrapper 28 | ```js 29 | // babel.config.js 30 | // npm i babel-plugin-jsx-classlist 31 | const unocssBabel = require('unonative/babel'); 32 | 33 | module.exports = function(api) { 34 | api.cache(true); 35 | return { 36 | presets: ['babel-preset-expo'], 37 | plugins: [unocssBabel.default], 38 | }; 39 | }; 40 | 41 | ``` 42 | 43 | 3. Due to Babel Visitor **not supporting** asynchronous processing of source code, we have moved the processing of style collection/Icon to Metro transformer. 44 | ```js 45 | // metro.config.js 46 | // Learn more https://docs.expo.io/guides/customizing-metro 47 | const { getDefaultConfig } = require('expo/metro-config'); 48 | 49 | const config = getDefaultConfig(__dirname); 50 | 51 | 52 | const babelTransformerPath = require.resolve('unonative/transformer'); 53 | config.transformer.babelTransformerPath = babelTransformerPath; 54 | module.exports = config; 55 | 56 | ``` 57 | 58 | ### Enable SVG icon support (**optional**) 59 | ```bash 60 | expo install react-native-svg 61 | yarn add @iconify/json 62 | ``` 63 | After importing the dependencies, you can use them in your project. 64 | ```tsx 65 | import { Icon } from 'unonative'; 66 | 67 | export function App() { 68 | return 69 | 70 | 71 | } 72 | ``` 73 | Icons can be sourced from [icones](https://icones.js.org/) using the format "**collection**-(icon)". 74 | 75 | ### Use with Typescript 76 | ```diff 77 | // project .d.ts 78 | +/// 79 | ``` 80 | 81 | ## How it works 82 | 83 | **Source Code** 84 | 85 | ```tsx 86 | import { Icon } from 'unonative'; 87 | function App() { 88 | return ( 89 | 90 | Hello 91 | Word 92 | 93 | 94 | ); 95 | } 96 | ``` 97 | 98 | In the Metro Transform phase, the source code will be processed into 99 | 100 | ```tsx 101 | import __unonative__ from 'unonative'; 102 | import { Icon } from 'unonative'; 103 | function App() { 104 | return ( 105 | 106 | Hello 107 | Word 108 | 112 | 113 | ); 114 | } 115 | __unonative__.register({ 116 | 'bg-red-100': { backgroundColor: 'rgba(254,226,226,1)' }, 117 | 'text-lg': { fontSize: 18 }, 118 | 'h-8': { height: 32 }, 119 | 'w-8': { width: 32 }, 120 | }); 121 | ``` 122 | 123 | In the Babel transpile phase, any jsxElement containing className will be transpiled into a **higher-order component** 124 | 125 | ```tsx 126 | import { UnoStyled as _UnoStyled } from "unonative"; 127 | import __unonative__ from "unonative"; 128 | import { Icon } from 'unonative'; 129 | function App() { 130 | return <_UnoStyled className='bg-red-100' component={View}> 131 | <_UnoStyled className='text-lg' component={Text}>Hello 132 | <_UnoStyled className='text-lg' component={Text}>Word 133 | <_UnoStyled icon='' className='h-8 w-8' component={Icon} /> 134 | ; 135 | } 136 | __unonative__.register({ 137 | "bg-red-100": { 138 | "backgroundColor": "rgba(254,226,226,1)" 139 | }, 140 | "text-lg": { 141 | "fontSize": 18 142 | }, 143 | "h-8": { 144 | "height": 32 145 | }, 146 | "w-8": { 147 | "width": 32 148 | } 149 | }); 150 | ``` 151 | 152 | ## Demo 153 | 154 | [unonative-demo](https://github.com/eagermko/unonative-demo) 155 | 156 | ## Roadmap 157 | 158 | - [x] Exporting type definitions 159 | - [ ] Adding a VW preset to convert PX units to VW units 160 | - [x] Generating CSS using uno.config.ts at the project root path 161 | -------------------------------------------------------------------------------- /__tests__/babel.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, it } from 'vitest'; 2 | import dedent from 'dedent'; 3 | import { transform } from '@babel/core'; 4 | import plugin from '../src/babel'; 5 | 6 | function doTransform(input: string) { 7 | const result = transform(input, { 8 | plugins: ['syntax-jsx', plugin], 9 | }); 10 | 11 | if (!result) { 12 | throw new Error('transform failed'); 13 | } 14 | 15 | return result.code!; 16 | } 17 | 18 | it('transform and add import', () => { 19 | const result = doTransform(dedent` 20 | Hello 21 | `); 22 | 23 | expect(result).toMatchInlineSnapshot(` 24 | "import { UnoStyled as _UnoStyled } from \\"unonative\\"; 25 | <_UnoStyled className=\\"123\\" component={View}>Hello;" 26 | `); 27 | }); 28 | 29 | it('transform and add import once', () => { 30 | const result = doTransform(dedent` 31 | function App() { 32 | return Hello; 33 | } 34 | `); 35 | 36 | expect(result).toMatchInlineSnapshot(` 37 | "import { UnoStyled as _UnoStyled } from \\"unonative\\"; 38 | function App() { 39 | return <_UnoStyled className=\\"123\\" component={View}>Hello; 40 | }" 41 | `); 42 | }); 43 | 44 | it('transform and add import once', () => { 45 | const result = doTransform(dedent` 46 | function App() { 47 | return 48 | Hello 49 | 50 | 51 | } 52 | `); 53 | 54 | expect(result).toMatchInlineSnapshot(` 55 | "import { UnoStyled as _UnoStyled } from \\"unonative\\"; 56 | function App() { 57 | return 58 | <_UnoStyled className=\\"123\\" component={View}>Hello 59 | <_UnoStyled className=\\"234\\" component={Image}> 60 | ; 61 | }" 62 | `); 63 | }); 64 | -------------------------------------------------------------------------------- /__tests__/config.spec.ts: -------------------------------------------------------------------------------- 1 | import dedent from 'dedent'; 2 | import { expect, it } from 'vitest'; 3 | import { loadUnoConfig } from '../src/transformer/style-processor'; 4 | 5 | it('should resolve config', async () => { 6 | const result = await loadUnoConfig(__dirname); 7 | expect(result).toHaveProperty('theme.colors.primary'); 8 | expect(result.presets).toHaveLength(2); 9 | }); 10 | -------------------------------------------------------------------------------- /__tests__/rule.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, it } from 'vitest'; 2 | import transform from '../src/transformer'; 3 | 4 | it('rule transform', async () => { 5 | const source = `Hello`; 6 | const result = await transform(source, { projectRoot: __dirname }); 7 | 8 | expect(result).toMatchInlineSnapshot(` 9 | "import __unonative__ from \\"unonative\\" 10 | Hello 11 | __unonative__.register({\\"transform-[rotateX(45deg)_rotateZ(0.785398rad)]\\":{\\"transform\\":[{\\"rotateZ\\":\\"0.785398rad\\"},{\\"rotateX\\":\\"45deg\\"}]}})" 12 | `); 13 | }); 14 | -------------------------------------------------------------------------------- /__tests__/run.spec.ts: -------------------------------------------------------------------------------- 1 | import { transform as babelTransform } from '@babel/core'; 2 | import dedent from 'dedent'; 3 | import { expect, it } from 'vitest'; 4 | import plugin from '../src/babel'; 5 | import transform from '../src/transformer'; 6 | 7 | function doBabelTransform(input: string) { 8 | const result = babelTransform(input, { 9 | plugins: ['syntax-jsx', plugin], 10 | }); 11 | 12 | if (!result) { 13 | throw new Error('transform failed'); 14 | } 15 | 16 | return result.code!; 17 | } 18 | 19 | const source = dedent` 20 | import { Icon } from 'unonative'; 21 | function App() { 22 | return ( 23 | 24 | Hello 25 | Word 26 | 27 | 28 | ); 29 | } 30 | `; 31 | 32 | it('transform code correctly', async () => { 33 | const result = await transform(source, { projectRoot: '' }); 34 | const babelResult = await doBabelTransform(result); 35 | 36 | expect(babelResult).toMatchInlineSnapshot(` 37 | "import { UnoStyled as _UnoStyled } from \\"unonative\\"; 38 | import __unonative__ from \\"unonative\\"; 39 | import { Icon } from 'unonative'; 40 | function App() { 41 | return <_UnoStyled className='bg-red-100' component={View}> 42 | <_UnoStyled className='text-lg' component={Text}>Hello 43 | <_UnoStyled className='text-lg' component={Text}>Word 44 | <_UnoStyled icon='' className='h-8 w-8' component={Icon} /> 45 | ; 46 | } 47 | __unonative__.register({ 48 | \\"bg-red-100\\": { 49 | \\"backgroundColor\\": \\"rgba(254,226,226,1)\\" 50 | }, 51 | \\"text-lg\\": { 52 | \\"fontSize\\": 18 53 | }, 54 | \\"h-8\\": { 55 | \\"height\\": 32 56 | }, 57 | \\"w-8\\": { 58 | \\"width\\": 32 59 | } 60 | });" 61 | `); 62 | }); 63 | -------------------------------------------------------------------------------- /__tests__/svgxml.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, it } from 'vitest'; 2 | import dedent from 'dedent'; 3 | import svgTransformer from '../src/transformer/svg-transformer'; 4 | 5 | it('replace icon with svgxml', async () => { 6 | const input = dedent` 7 | 8 | 9 | `; 10 | 11 | const result = await svgTransformer(input); 12 | expect(result).toMatchInlineSnapshot(` 13 | " 14 | " 15 | `); 16 | }); 17 | -------------------------------------------------------------------------------- /__tests__/transfomer.spec.ts: -------------------------------------------------------------------------------- 1 | import dedent from 'dedent'; 2 | import { expect, it } from 'vitest'; 3 | import transform from '../src/transformer'; 4 | 5 | const source = dedent` 6 | import { Icon } from 'unonative'; 7 | function App() { 8 | return ( 9 | 10 | Hello 11 | Word 12 | 13 | 14 | ); 15 | } 16 | `; 17 | 18 | it('translating source code', async () => { 19 | const result = await transform(source, { projectRoot: '' }); 20 | expect(result).toMatchInlineSnapshot(` 21 | "import __unonative__ from \\"unonative\\" 22 | import { Icon } from 'unonative'; 23 | function App() { 24 | return ( 25 | 26 | Hello 27 | Word 28 | 29 | 30 | ); 31 | } 32 | __unonative__.register({\\"bg-red-100\\":{\\"backgroundColor\\":\\"rgba(254,226,226,1)\\"},\\"text-lg\\":{\\"fontSize\\":18},\\"h-8\\":{\\"height\\":32},\\"w-8\\":{\\"width\\":32}})" 33 | `); 34 | }); 35 | 36 | it('translating with config file', async () => { 37 | const source = `Hello`; 38 | const result = await transform(source, { projectRoot: __dirname }); 39 | 40 | expect(result).toMatchInlineSnapshot(` 41 | "import __unonative__ from \\"unonative\\" 42 | Hello 43 | __unonative__.register({\\"bg-primary\\":{\\"backgroundColor\\":\\"red\\"}})" 44 | `); 45 | }) -------------------------------------------------------------------------------- /__tests__/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'unocss'; 2 | 3 | export default defineConfig({ 4 | presets: [], 5 | theme: { 6 | colors: { 7 | primary: 'red', 8 | }, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /doc/image-20230322211848407.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eagermko/react-native-unocss/b9bdb74d571168d59e7c57c36868618a89e26d29/doc/image-20230322211848407.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unonative", 3 | "version": "0.0.12", 4 | "description": "", 5 | "main": "dist/index.js", 6 | "type": "commonjs", 7 | "scripts": { 8 | "test": "vitest", 9 | "build": "tsup" 10 | }, 11 | "exports": { 12 | ".": { 13 | "types": "./dist/index.d.ts", 14 | "require": "./dist/index.js", 15 | "import": "./dist/index.mjs" 16 | }, 17 | "./transformer": { 18 | "types": "./dist/transformerEntry.d.ts", 19 | "require": "./dist/transformerEntry.js", 20 | "import": "./dist/transformerEntry.mjs" 21 | }, 22 | "./preset": { 23 | "types": "./dist/preset.d.ts", 24 | "require": "./dist/preset.js", 25 | "import": "./dist/preset.mjs" 26 | }, 27 | "./babel": { 28 | "types": "./dist/babel.d.ts", 29 | "require": "./dist/babel.js", 30 | "import": "./dist/babel.mjs" 31 | } 32 | }, 33 | "author": "eagermko", 34 | "repository": { 35 | "type": "git", 36 | "url": "https://github.com/eagermko/unonative" 37 | }, 38 | "license": "MIT", 39 | "devDependencies": { 40 | "@babel/core": "^7.20.12", 41 | "@babel/types": "^7.20.7", 42 | "@iconify/json": "^2.2.37", 43 | "@types/babel__core": "^7.20.0", 44 | "@types/dedent": "^0.7.0", 45 | "@types/node": "^18.0.0", 46 | "@types/react": "^18.0.28", 47 | "@types/react-native": "^0.71.5", 48 | "babel-plugin-syntax-jsx": "^6.18.0", 49 | "dedent": "^0.7.0", 50 | "tsup": "^6.5.0", 51 | "tsx": "^3.5.0", 52 | "typescript": "^4.9.5", 53 | "vite": "^4.2.0", 54 | "@unocss/core": "^0.50.6", 55 | "vitest": "^0.29.3" 56 | }, 57 | "dependencies": { 58 | "@babel/helper-module-imports": "^7.18.6", 59 | "@iconify/utils": "^2.1.5", 60 | "@unocss/config": "^0.50.6", 61 | "css-to-react-native": "^3.2.0", 62 | "cssom": "^0.5.0", 63 | "unocss": "^0.50.4" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | '@babel/core': ^7.20.12 5 | '@babel/helper-module-imports': ^7.18.6 6 | '@babel/types': ^7.20.7 7 | '@iconify/json': ^2.2.37 8 | '@iconify/utils': ^2.1.5 9 | '@types/babel__core': ^7.20.0 10 | '@types/dedent': ^0.7.0 11 | '@types/node': ^18.0.0 12 | '@types/react': ^18.0.28 13 | '@types/react-native': ^0.71.5 14 | '@unocss/config': ^0.50.6 15 | '@unocss/core': ^0.50.6 16 | babel-plugin-syntax-jsx: ^6.18.0 17 | css-to-react-native: ^3.2.0 18 | cssom: ^0.5.0 19 | dedent: ^0.7.0 20 | tsup: ^6.5.0 21 | tsx: ^3.5.0 22 | typescript: ^4.9.5 23 | unocss: ^0.50.4 24 | vite: ^4.2.0 25 | vitest: ^0.29.3 26 | 27 | dependencies: 28 | '@babel/helper-module-imports': 7.18.6 29 | '@iconify/utils': 2.1.5 30 | '@unocss/config': 0.50.6 31 | '@unocss/core': 0.50.6 32 | css-to-react-native: 3.2.0 33 | cssom: 0.5.0 34 | unocss: 0.50.4_vite@4.2.0 35 | 36 | devDependencies: 37 | '@babel/core': 7.20.12 38 | '@babel/types': 7.20.7 39 | '@iconify/json': 2.2.37 40 | '@types/babel__core': 7.20.0 41 | '@types/dedent': 0.7.0 42 | '@types/node': 18.11.18 43 | '@types/react': 18.0.28 44 | '@types/react-native': 0.71.5 45 | babel-plugin-syntax-jsx: 6.18.0 46 | dedent: 0.7.0 47 | tsup: 6.5.0_typescript@4.9.5 48 | tsx: 3.12.2 49 | typescript: 4.9.5 50 | vite: 4.2.0_@types+node@18.11.18 51 | vitest: 0.29.3 52 | 53 | packages: 54 | 55 | /@ampproject/remapping/2.2.0: 56 | resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} 57 | engines: {node: '>=6.0.0'} 58 | dependencies: 59 | '@jridgewell/gen-mapping': 0.1.1 60 | '@jridgewell/trace-mapping': 0.3.17 61 | 62 | /@antfu/install-pkg/0.1.1: 63 | resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} 64 | dependencies: 65 | execa: 5.1.1 66 | find-up: 5.0.0 67 | dev: false 68 | 69 | /@antfu/utils/0.5.2: 70 | resolution: {integrity: sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA==} 71 | dev: false 72 | 73 | /@antfu/utils/0.7.2: 74 | resolution: {integrity: sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g==} 75 | dev: false 76 | 77 | /@babel/code-frame/7.18.6: 78 | resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} 79 | engines: {node: '>=6.9.0'} 80 | dependencies: 81 | '@babel/highlight': 7.18.6 82 | dev: true 83 | 84 | /@babel/compat-data/7.20.14: 85 | resolution: {integrity: sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==} 86 | engines: {node: '>=6.9.0'} 87 | dev: true 88 | 89 | /@babel/core/7.20.12: 90 | resolution: {integrity: sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==} 91 | engines: {node: '>=6.9.0'} 92 | dependencies: 93 | '@ampproject/remapping': 2.2.0 94 | '@babel/code-frame': 7.18.6 95 | '@babel/generator': 7.20.14 96 | '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 97 | '@babel/helper-module-transforms': 7.20.11 98 | '@babel/helpers': 7.20.13 99 | '@babel/parser': 7.20.13 100 | '@babel/template': 7.20.7 101 | '@babel/traverse': 7.20.13 102 | '@babel/types': 7.20.7 103 | convert-source-map: 1.9.0 104 | debug: 4.3.4 105 | gensync: 1.0.0-beta.2 106 | json5: 2.2.3 107 | semver: 6.3.0 108 | transitivePeerDependencies: 109 | - supports-color 110 | dev: true 111 | 112 | /@babel/generator/7.20.14: 113 | resolution: {integrity: sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==} 114 | engines: {node: '>=6.9.0'} 115 | dependencies: 116 | '@babel/types': 7.20.7 117 | '@jridgewell/gen-mapping': 0.3.2 118 | jsesc: 2.5.2 119 | dev: true 120 | 121 | /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12: 122 | resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} 123 | engines: {node: '>=6.9.0'} 124 | peerDependencies: 125 | '@babel/core': ^7.0.0 126 | dependencies: 127 | '@babel/compat-data': 7.20.14 128 | '@babel/core': 7.20.12 129 | '@babel/helper-validator-option': 7.18.6 130 | browserslist: 4.21.5 131 | lru-cache: 5.1.1 132 | semver: 6.3.0 133 | dev: true 134 | 135 | /@babel/helper-environment-visitor/7.18.9: 136 | resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} 137 | engines: {node: '>=6.9.0'} 138 | dev: true 139 | 140 | /@babel/helper-function-name/7.19.0: 141 | resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} 142 | engines: {node: '>=6.9.0'} 143 | dependencies: 144 | '@babel/template': 7.20.7 145 | '@babel/types': 7.20.7 146 | dev: true 147 | 148 | /@babel/helper-hoist-variables/7.18.6: 149 | resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} 150 | engines: {node: '>=6.9.0'} 151 | dependencies: 152 | '@babel/types': 7.20.7 153 | dev: true 154 | 155 | /@babel/helper-module-imports/7.18.6: 156 | resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} 157 | engines: {node: '>=6.9.0'} 158 | dependencies: 159 | '@babel/types': 7.20.7 160 | 161 | /@babel/helper-module-transforms/7.20.11: 162 | resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} 163 | engines: {node: '>=6.9.0'} 164 | dependencies: 165 | '@babel/helper-environment-visitor': 7.18.9 166 | '@babel/helper-module-imports': 7.18.6 167 | '@babel/helper-simple-access': 7.20.2 168 | '@babel/helper-split-export-declaration': 7.18.6 169 | '@babel/helper-validator-identifier': 7.19.1 170 | '@babel/template': 7.20.7 171 | '@babel/traverse': 7.20.13 172 | '@babel/types': 7.20.7 173 | transitivePeerDependencies: 174 | - supports-color 175 | dev: true 176 | 177 | /@babel/helper-simple-access/7.20.2: 178 | resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} 179 | engines: {node: '>=6.9.0'} 180 | dependencies: 181 | '@babel/types': 7.20.7 182 | dev: true 183 | 184 | /@babel/helper-split-export-declaration/7.18.6: 185 | resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} 186 | engines: {node: '>=6.9.0'} 187 | dependencies: 188 | '@babel/types': 7.20.7 189 | dev: true 190 | 191 | /@babel/helper-string-parser/7.19.4: 192 | resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} 193 | engines: {node: '>=6.9.0'} 194 | 195 | /@babel/helper-validator-identifier/7.19.1: 196 | resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} 197 | engines: {node: '>=6.9.0'} 198 | 199 | /@babel/helper-validator-option/7.18.6: 200 | resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} 201 | engines: {node: '>=6.9.0'} 202 | dev: true 203 | 204 | /@babel/helpers/7.20.13: 205 | resolution: {integrity: sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==} 206 | engines: {node: '>=6.9.0'} 207 | dependencies: 208 | '@babel/template': 7.20.7 209 | '@babel/traverse': 7.20.13 210 | '@babel/types': 7.20.7 211 | transitivePeerDependencies: 212 | - supports-color 213 | dev: true 214 | 215 | /@babel/highlight/7.18.6: 216 | resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} 217 | engines: {node: '>=6.9.0'} 218 | dependencies: 219 | '@babel/helper-validator-identifier': 7.19.1 220 | chalk: 2.4.2 221 | js-tokens: 4.0.0 222 | dev: true 223 | 224 | /@babel/parser/7.20.13: 225 | resolution: {integrity: sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==} 226 | engines: {node: '>=6.0.0'} 227 | hasBin: true 228 | dependencies: 229 | '@babel/types': 7.20.7 230 | dev: true 231 | 232 | /@babel/template/7.20.7: 233 | resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} 234 | engines: {node: '>=6.9.0'} 235 | dependencies: 236 | '@babel/code-frame': 7.18.6 237 | '@babel/parser': 7.20.13 238 | '@babel/types': 7.20.7 239 | dev: true 240 | 241 | /@babel/traverse/7.20.13: 242 | resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==} 243 | engines: {node: '>=6.9.0'} 244 | dependencies: 245 | '@babel/code-frame': 7.18.6 246 | '@babel/generator': 7.20.14 247 | '@babel/helper-environment-visitor': 7.18.9 248 | '@babel/helper-function-name': 7.19.0 249 | '@babel/helper-hoist-variables': 7.18.6 250 | '@babel/helper-split-export-declaration': 7.18.6 251 | '@babel/parser': 7.20.13 252 | '@babel/types': 7.20.7 253 | debug: 4.3.4 254 | globals: 11.12.0 255 | transitivePeerDependencies: 256 | - supports-color 257 | dev: true 258 | 259 | /@babel/types/7.20.7: 260 | resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} 261 | engines: {node: '>=6.9.0'} 262 | dependencies: 263 | '@babel/helper-string-parser': 7.19.4 264 | '@babel/helper-validator-identifier': 7.19.1 265 | to-fast-properties: 2.0.0 266 | 267 | /@esbuild-kit/cjs-loader/2.4.1: 268 | resolution: {integrity: sha512-lhc/XLith28QdW0HpHZvZKkorWgmCNT7sVelMHDj3HFdTfdqkwEKvT+aXVQtNAmCC39VJhunDkWhONWB7335mg==} 269 | dependencies: 270 | '@esbuild-kit/core-utils': 3.0.0 271 | get-tsconfig: 4.3.0 272 | dev: true 273 | 274 | /@esbuild-kit/core-utils/3.0.0: 275 | resolution: {integrity: sha512-TXmwH9EFS3DC2sI2YJWJBgHGhlteK0Xyu1VabwetMULfm3oYhbrsWV5yaSr2NTWZIgDGVLHbRf0inxbjXqAcmQ==} 276 | dependencies: 277 | esbuild: 0.15.18 278 | source-map-support: 0.5.21 279 | dev: true 280 | 281 | /@esbuild-kit/esm-loader/2.5.4: 282 | resolution: {integrity: sha512-afmtLf6uqxD5IgwCzomtqCYIgz/sjHzCWZFvfS5+FzeYxOURPUo4QcHtqJxbxWOMOogKriZanN/1bJQE/ZL93A==} 283 | dependencies: 284 | '@esbuild-kit/core-utils': 3.0.0 285 | get-tsconfig: 4.3.0 286 | dev: true 287 | 288 | /@esbuild/android-arm/0.15.18: 289 | resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} 290 | engines: {node: '>=12'} 291 | cpu: [arm] 292 | os: [android] 293 | requiresBuild: true 294 | dev: true 295 | optional: true 296 | 297 | /@esbuild/android-arm/0.17.11: 298 | resolution: {integrity: sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw==} 299 | engines: {node: '>=12'} 300 | cpu: [arm] 301 | os: [android] 302 | requiresBuild: true 303 | optional: true 304 | 305 | /@esbuild/android-arm64/0.17.11: 306 | resolution: {integrity: sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg==} 307 | engines: {node: '>=12'} 308 | cpu: [arm64] 309 | os: [android] 310 | requiresBuild: true 311 | optional: true 312 | 313 | /@esbuild/android-x64/0.17.11: 314 | resolution: {integrity: sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ==} 315 | engines: {node: '>=12'} 316 | cpu: [x64] 317 | os: [android] 318 | requiresBuild: true 319 | optional: true 320 | 321 | /@esbuild/darwin-arm64/0.17.11: 322 | resolution: {integrity: sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw==} 323 | engines: {node: '>=12'} 324 | cpu: [arm64] 325 | os: [darwin] 326 | requiresBuild: true 327 | optional: true 328 | 329 | /@esbuild/darwin-x64/0.17.11: 330 | resolution: {integrity: sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw==} 331 | engines: {node: '>=12'} 332 | cpu: [x64] 333 | os: [darwin] 334 | requiresBuild: true 335 | optional: true 336 | 337 | /@esbuild/freebsd-arm64/0.17.11: 338 | resolution: {integrity: sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q==} 339 | engines: {node: '>=12'} 340 | cpu: [arm64] 341 | os: [freebsd] 342 | requiresBuild: true 343 | optional: true 344 | 345 | /@esbuild/freebsd-x64/0.17.11: 346 | resolution: {integrity: sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g==} 347 | engines: {node: '>=12'} 348 | cpu: [x64] 349 | os: [freebsd] 350 | requiresBuild: true 351 | optional: true 352 | 353 | /@esbuild/linux-arm/0.17.11: 354 | resolution: {integrity: sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg==} 355 | engines: {node: '>=12'} 356 | cpu: [arm] 357 | os: [linux] 358 | requiresBuild: true 359 | optional: true 360 | 361 | /@esbuild/linux-arm64/0.17.11: 362 | resolution: {integrity: sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg==} 363 | engines: {node: '>=12'} 364 | cpu: [arm64] 365 | os: [linux] 366 | requiresBuild: true 367 | optional: true 368 | 369 | /@esbuild/linux-ia32/0.17.11: 370 | resolution: {integrity: sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA==} 371 | engines: {node: '>=12'} 372 | cpu: [ia32] 373 | os: [linux] 374 | requiresBuild: true 375 | optional: true 376 | 377 | /@esbuild/linux-loong64/0.15.18: 378 | resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} 379 | engines: {node: '>=12'} 380 | cpu: [loong64] 381 | os: [linux] 382 | requiresBuild: true 383 | dev: true 384 | optional: true 385 | 386 | /@esbuild/linux-loong64/0.17.11: 387 | resolution: {integrity: sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g==} 388 | engines: {node: '>=12'} 389 | cpu: [loong64] 390 | os: [linux] 391 | requiresBuild: true 392 | optional: true 393 | 394 | /@esbuild/linux-mips64el/0.17.11: 395 | resolution: {integrity: sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw==} 396 | engines: {node: '>=12'} 397 | cpu: [mips64el] 398 | os: [linux] 399 | requiresBuild: true 400 | optional: true 401 | 402 | /@esbuild/linux-ppc64/0.17.11: 403 | resolution: {integrity: sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA==} 404 | engines: {node: '>=12'} 405 | cpu: [ppc64] 406 | os: [linux] 407 | requiresBuild: true 408 | optional: true 409 | 410 | /@esbuild/linux-riscv64/0.17.11: 411 | resolution: {integrity: sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA==} 412 | engines: {node: '>=12'} 413 | cpu: [riscv64] 414 | os: [linux] 415 | requiresBuild: true 416 | optional: true 417 | 418 | /@esbuild/linux-s390x/0.17.11: 419 | resolution: {integrity: sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ==} 420 | engines: {node: '>=12'} 421 | cpu: [s390x] 422 | os: [linux] 423 | requiresBuild: true 424 | optional: true 425 | 426 | /@esbuild/linux-x64/0.17.11: 427 | resolution: {integrity: sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw==} 428 | engines: {node: '>=12'} 429 | cpu: [x64] 430 | os: [linux] 431 | requiresBuild: true 432 | optional: true 433 | 434 | /@esbuild/netbsd-x64/0.17.11: 435 | resolution: {integrity: sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag==} 436 | engines: {node: '>=12'} 437 | cpu: [x64] 438 | os: [netbsd] 439 | requiresBuild: true 440 | optional: true 441 | 442 | /@esbuild/openbsd-x64/0.17.11: 443 | resolution: {integrity: sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w==} 444 | engines: {node: '>=12'} 445 | cpu: [x64] 446 | os: [openbsd] 447 | requiresBuild: true 448 | optional: true 449 | 450 | /@esbuild/sunos-x64/0.17.11: 451 | resolution: {integrity: sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg==} 452 | engines: {node: '>=12'} 453 | cpu: [x64] 454 | os: [sunos] 455 | requiresBuild: true 456 | optional: true 457 | 458 | /@esbuild/win32-arm64/0.17.11: 459 | resolution: {integrity: sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ==} 460 | engines: {node: '>=12'} 461 | cpu: [arm64] 462 | os: [win32] 463 | requiresBuild: true 464 | optional: true 465 | 466 | /@esbuild/win32-ia32/0.17.11: 467 | resolution: {integrity: sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw==} 468 | engines: {node: '>=12'} 469 | cpu: [ia32] 470 | os: [win32] 471 | requiresBuild: true 472 | optional: true 473 | 474 | /@esbuild/win32-x64/0.17.11: 475 | resolution: {integrity: sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ==} 476 | engines: {node: '>=12'} 477 | cpu: [x64] 478 | os: [win32] 479 | requiresBuild: true 480 | optional: true 481 | 482 | /@iconify/json/2.2.37: 483 | resolution: {integrity: sha512-3PHw+H9hMUYZ+wUij6DmdWxBnBIYOMtsKGRrJUHsKhMloy4kcOu+Yi2XKfD8JvXgJ6ybzoNAXOkKDgEqY0JKQw==} 484 | dependencies: 485 | '@iconify/types': 2.0.0 486 | pathe: 1.1.0 487 | dev: true 488 | 489 | /@iconify/types/2.0.0: 490 | resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} 491 | 492 | /@iconify/utils/2.1.5: 493 | resolution: {integrity: sha512-6MvDI+I6QMvXn5rK9KQGdpEE4mmLTcuQdLZEiX5N+uZB+vc4Yw9K1OtnOgkl8mp4d9X0UrILREyZgF1NUwUt+Q==} 494 | dependencies: 495 | '@antfu/install-pkg': 0.1.1 496 | '@antfu/utils': 0.7.2 497 | '@iconify/types': 2.0.0 498 | debug: 4.3.4 499 | kolorist: 1.7.0 500 | local-pkg: 0.4.3 501 | transitivePeerDependencies: 502 | - supports-color 503 | dev: false 504 | 505 | /@jridgewell/gen-mapping/0.1.1: 506 | resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} 507 | engines: {node: '>=6.0.0'} 508 | dependencies: 509 | '@jridgewell/set-array': 1.1.2 510 | '@jridgewell/sourcemap-codec': 1.4.14 511 | 512 | /@jridgewell/gen-mapping/0.3.2: 513 | resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} 514 | engines: {node: '>=6.0.0'} 515 | dependencies: 516 | '@jridgewell/set-array': 1.1.2 517 | '@jridgewell/sourcemap-codec': 1.4.14 518 | '@jridgewell/trace-mapping': 0.3.17 519 | dev: true 520 | 521 | /@jridgewell/resolve-uri/3.1.0: 522 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 523 | engines: {node: '>=6.0.0'} 524 | 525 | /@jridgewell/set-array/1.1.2: 526 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} 527 | engines: {node: '>=6.0.0'} 528 | 529 | /@jridgewell/sourcemap-codec/1.4.14: 530 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 531 | 532 | /@jridgewell/trace-mapping/0.3.17: 533 | resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} 534 | dependencies: 535 | '@jridgewell/resolve-uri': 3.1.0 536 | '@jridgewell/sourcemap-codec': 1.4.14 537 | 538 | /@nodelib/fs.scandir/2.1.5: 539 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 540 | engines: {node: '>= 8'} 541 | dependencies: 542 | '@nodelib/fs.stat': 2.0.5 543 | run-parallel: 1.2.0 544 | 545 | /@nodelib/fs.stat/2.0.5: 546 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 547 | engines: {node: '>= 8'} 548 | 549 | /@nodelib/fs.walk/1.2.8: 550 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 551 | engines: {node: '>= 8'} 552 | dependencies: 553 | '@nodelib/fs.scandir': 2.1.5 554 | fastq: 1.15.0 555 | 556 | /@polka/url/1.0.0-next.21: 557 | resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} 558 | dev: false 559 | 560 | /@rollup/pluginutils/5.0.2: 561 | resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} 562 | engines: {node: '>=14.0.0'} 563 | peerDependencies: 564 | rollup: ^1.20.0||^2.0.0||^3.0.0 565 | peerDependenciesMeta: 566 | rollup: 567 | optional: true 568 | dependencies: 569 | '@types/estree': 1.0.0 570 | estree-walker: 2.0.2 571 | picomatch: 2.3.1 572 | dev: false 573 | 574 | /@types/babel__core/7.20.0: 575 | resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} 576 | dependencies: 577 | '@babel/parser': 7.20.13 578 | '@babel/types': 7.20.7 579 | '@types/babel__generator': 7.6.4 580 | '@types/babel__template': 7.4.1 581 | '@types/babel__traverse': 7.18.3 582 | dev: true 583 | 584 | /@types/babel__generator/7.6.4: 585 | resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} 586 | dependencies: 587 | '@babel/types': 7.20.7 588 | dev: true 589 | 590 | /@types/babel__template/7.4.1: 591 | resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} 592 | dependencies: 593 | '@babel/parser': 7.20.13 594 | '@babel/types': 7.20.7 595 | dev: true 596 | 597 | /@types/babel__traverse/7.18.3: 598 | resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==} 599 | dependencies: 600 | '@babel/types': 7.20.7 601 | dev: true 602 | 603 | /@types/chai-subset/1.3.3: 604 | resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} 605 | dependencies: 606 | '@types/chai': 4.3.4 607 | dev: true 608 | 609 | /@types/chai/4.3.4: 610 | resolution: {integrity: sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==} 611 | dev: true 612 | 613 | /@types/dedent/0.7.0: 614 | resolution: {integrity: sha512-EGlKlgMhnLt/cM4DbUSafFdrkeJoC9Mvnj0PUCU7tFmTjMjNRT957kXCx0wYm3JuEq4o4ZsS5vG+NlkM2DMd2A==} 615 | dev: true 616 | 617 | /@types/estree/1.0.0: 618 | resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} 619 | dev: false 620 | 621 | /@types/node/18.11.18: 622 | resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} 623 | 624 | /@types/node/18.15.3: 625 | resolution: {integrity: sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==} 626 | dev: true 627 | 628 | /@types/prop-types/15.7.5: 629 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 630 | dev: true 631 | 632 | /@types/react-native/0.71.5: 633 | resolution: {integrity: sha512-Tp5druh7DGwNDvWYH09PCE++hbH4zYz0OOvGFb3/QFIFKXgfezaT/txJeKlBkbiqs45QJzllp9S0qo0WpWyijA==} 634 | dependencies: 635 | '@types/react': 18.0.28 636 | dev: true 637 | 638 | /@types/react/18.0.28: 639 | resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==} 640 | dependencies: 641 | '@types/prop-types': 15.7.5 642 | '@types/scheduler': 0.16.2 643 | csstype: 3.1.1 644 | dev: true 645 | 646 | /@types/scheduler/0.16.2: 647 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} 648 | dev: true 649 | 650 | /@unocss/astro/0.50.4_vite@4.2.0: 651 | resolution: {integrity: sha512-NlfkyMM/xv0ozzP/ByqFAQmtzpDALWqWssXmtSQVV3CCZCxTQYzeenXgv92VELISxNUHJ46elKPHhWNpRBxCjg==} 652 | dependencies: 653 | '@unocss/core': 0.50.4 654 | '@unocss/reset': 0.50.4 655 | '@unocss/vite': 0.50.4_vite@4.2.0 656 | transitivePeerDependencies: 657 | - rollup 658 | - vite 659 | dev: false 660 | 661 | /@unocss/cli/0.50.4: 662 | resolution: {integrity: sha512-rAdMSfDio5dGbHCnhmvh+72D7JmIksDIpGYf0rjrMU+rxSC3/l4+Dr9Rr5qqNg1I51AcB9/UM6ena0TF2RyK8A==} 663 | engines: {node: '>=14'} 664 | hasBin: true 665 | dependencies: 666 | '@ampproject/remapping': 2.2.0 667 | '@rollup/pluginutils': 5.0.2 668 | '@unocss/config': 0.50.4 669 | '@unocss/core': 0.50.4 670 | '@unocss/preset-uno': 0.50.4 671 | cac: 6.7.14 672 | chokidar: 3.5.3 673 | colorette: 2.0.19 674 | consola: 2.15.3 675 | fast-glob: 3.2.12 676 | magic-string: 0.30.0 677 | pathe: 1.1.0 678 | perfect-debounce: 0.1.3 679 | transitivePeerDependencies: 680 | - rollup 681 | dev: false 682 | 683 | /@unocss/config/0.50.4: 684 | resolution: {integrity: sha512-5Nvlvu3RHoZFqaxJwaN/pr9bWHg2PZ4omD90y/xe0CXWHjX9n3BJHcXqQQm0Iai6uF1IZDPOC5nj2UU2oKFxMg==} 685 | engines: {node: '>=14'} 686 | dependencies: 687 | '@unocss/core': 0.50.4 688 | unconfig: 0.3.7 689 | dev: false 690 | 691 | /@unocss/config/0.50.6: 692 | resolution: {integrity: sha512-/IdnXyU4NOQCXBryZsEv9GYAnTvCZ/wmm5mv5ZIPXrS1ZClVbCbnwUxIW08t4EHIX/E9gSFClzXJ52pLBFkZ7g==} 693 | engines: {node: '>=14'} 694 | dependencies: 695 | '@unocss/core': 0.50.6 696 | unconfig: 0.3.7 697 | dev: false 698 | 699 | /@unocss/core/0.50.4: 700 | resolution: {integrity: sha512-k/8CdnO4w7f+QdvCpS3U5y6xApC4odiErkBKCCaGgBqOWkuTSL92TiBnffSEA2WepGm1+Mv4urIk20ocKYxbUQ==} 701 | dev: false 702 | 703 | /@unocss/core/0.50.6: 704 | resolution: {integrity: sha512-WMIp8xr7YSlID2whqfRGLwagp59e6u4ckPACEpoDOW8sTeSPRZm54hxPhuWXD1SQuqcwHPMtM9nzGD8UOnqQxA==} 705 | dev: false 706 | 707 | /@unocss/inspector/0.50.4: 708 | resolution: {integrity: sha512-3xYOhjNmM7qpdU4CSbL7acCb4YuTdeSoYCIMtWkbg9mHh/6GQZWV2eDTxwSxVE7WwDymw9Jg44Ewq3oboZWl1Q==} 709 | dependencies: 710 | gzip-size: 6.0.0 711 | sirv: 2.0.2 712 | dev: false 713 | 714 | /@unocss/postcss/0.50.4: 715 | resolution: {integrity: sha512-Gri+EqIOs/yKk0YHel5XLHQCRD1BzKdQHF82zizJUyqaRStR2qvR8ECInYsirXL/eUEvx2zT8iQKCXkiApTuQw==} 716 | engines: {node: '>=14'} 717 | dependencies: 718 | '@unocss/config': 0.50.4 719 | '@unocss/core': 0.50.4 720 | css-tree: 2.3.1 721 | fast-glob: 3.2.12 722 | magic-string: 0.30.0 723 | postcss: 8.4.21 724 | dev: false 725 | 726 | /@unocss/preset-attributify/0.50.4: 727 | resolution: {integrity: sha512-lSEyfpIGSzZB4DHFxrxhaa7rDF5PpM1EbReKogTVG7wsYTCmdCh8YirrgAlrcFCN1NgcbW1DaHdQs891A7glow==} 728 | dependencies: 729 | '@unocss/core': 0.50.4 730 | dev: false 731 | 732 | /@unocss/preset-icons/0.50.4: 733 | resolution: {integrity: sha512-0Bnito2u/t479oI9syXG8ynK1q2YUBt+dV6S6UugiTtys0KahjmuOTuk10GDgF50r4FvI38QfHBv+kF95qmwZg==} 734 | dependencies: 735 | '@iconify/utils': 2.1.5 736 | '@unocss/core': 0.50.4 737 | ofetch: 1.0.1 738 | transitivePeerDependencies: 739 | - supports-color 740 | dev: false 741 | 742 | /@unocss/preset-mini/0.50.4: 743 | resolution: {integrity: sha512-M+4by82hlpZq/sE0axrepQ6sgTl65nXrbNIHhXmfIsqulH7nENELJIr/TFi7VcSJdPMGVwo9l9dHnFMhSQM5hg==} 744 | dependencies: 745 | '@unocss/core': 0.50.4 746 | dev: false 747 | 748 | /@unocss/preset-tagify/0.50.4: 749 | resolution: {integrity: sha512-SJchttBpnePOKBD9onjprqOcgyWFAaOzT3O6M/sWzHEszVcfsFi2uPcwZW5CLwbOMiV0tbozBQFkcQ1c1swilw==} 750 | dependencies: 751 | '@unocss/core': 0.50.4 752 | dev: false 753 | 754 | /@unocss/preset-typography/0.50.4: 755 | resolution: {integrity: sha512-iEVdwd591RKAzirvftAHcLWdTam3ea/M7ElC1geMlY8rsFNtiDjVLtY87v8piHVXXFBwy71YAGhJkPCrxE8yHw==} 756 | dependencies: 757 | '@unocss/core': 0.50.4 758 | '@unocss/preset-mini': 0.50.4 759 | dev: false 760 | 761 | /@unocss/preset-uno/0.50.4: 762 | resolution: {integrity: sha512-otmCHbzJH1EISZ2Hvu35CEYaH3T6giwTreaP8CEo+BEjhGv2hgWmJko8GPDerUgO4FSP/YCwSGyBvcvSsRXV8A==} 763 | dependencies: 764 | '@unocss/core': 0.50.4 765 | '@unocss/preset-mini': 0.50.4 766 | '@unocss/preset-wind': 0.50.4 767 | dev: false 768 | 769 | /@unocss/preset-web-fonts/0.50.4: 770 | resolution: {integrity: sha512-4l8ILVzL6pAtMjwB5NRg1HowCS6dz4tLRVxH5W4uPyU5ADt3nhk5oQvzD9hDiB5sNJcXFVpMhI09UsRjUHQaTw==} 771 | dependencies: 772 | '@unocss/core': 0.50.4 773 | ofetch: 1.0.1 774 | dev: false 775 | 776 | /@unocss/preset-wind/0.50.4: 777 | resolution: {integrity: sha512-kOdX5DYrspbVOkNY7cEH0jJrtmtxlEcsZb9ieToYb3l76oWicgZX5G46c74+UzMW2ru9dxdOBgJWgnWbH7AFDQ==} 778 | dependencies: 779 | '@unocss/core': 0.50.4 780 | '@unocss/preset-mini': 0.50.4 781 | dev: false 782 | 783 | /@unocss/reset/0.50.4: 784 | resolution: {integrity: sha512-UHNDhClJMx3sG3oi68XkOcTeJ2hkI20O0eHowSoua10NClbnS9tiKxeo4ZLInouzvac3tb1TsjKEgTosHfkR/w==} 785 | dev: false 786 | 787 | /@unocss/scope/0.50.4: 788 | resolution: {integrity: sha512-USJ5hr1dVE8JOb0PJYqpfAWxGLB69b+z30ZGzdmDgblmVheYsyzWZ3KMclz/2x8HtXRsB2VuJT5KqUPW7lT3gw==} 789 | dev: false 790 | 791 | /@unocss/transformer-attributify-jsx/0.50.4: 792 | resolution: {integrity: sha512-DETbAiN/i393/OLuyEMBCXr2wDGyqEbkDMl/ZPN5RKO6m7312yt0KebnfIJnKaL0wGs90ohtV4ZHWMOeucX2jQ==} 793 | dependencies: 794 | '@unocss/core': 0.50.4 795 | dev: false 796 | 797 | /@unocss/transformer-compile-class/0.50.4: 798 | resolution: {integrity: sha512-pjXamTunv8CAX8r6heEw/UJdhkYNIbMEr6GGQfe33K6lL4fdU85NbvZD7c3pXbQJahKrGsgL7TSPvFoRw+5MZA==} 799 | dependencies: 800 | '@unocss/core': 0.50.4 801 | dev: false 802 | 803 | /@unocss/transformer-directives/0.50.4: 804 | resolution: {integrity: sha512-sk7AlL6wGnfKbCBDP4bKg008sJQuIbT408bkq98yA7h0/bIlLTqF6U0nzqUoIer5YxAAvIVm1Sm30CQV06s9rA==} 805 | dependencies: 806 | '@unocss/core': 0.50.4 807 | css-tree: 2.3.1 808 | dev: false 809 | 810 | /@unocss/transformer-variant-group/0.50.4: 811 | resolution: {integrity: sha512-caSByOVhD36yeE0j11gkhsxGPX7wphexVZLlzJa/6w2RAHwab1SCBCtAQeTRdl/C53DI8q4gsNt73IFoqQ1eng==} 812 | dependencies: 813 | '@unocss/core': 0.50.4 814 | dev: false 815 | 816 | /@unocss/vite/0.50.4_vite@4.2.0: 817 | resolution: {integrity: sha512-NW0B6hY3ho6G+PRFjNDvs0+nokCzHGbMtK4E9GIU5NyjJh0b4FfuWe9C9o1GxHGiFskGfYnirKPV40IHWOzOFw==} 818 | peerDependencies: 819 | vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 820 | dependencies: 821 | '@ampproject/remapping': 2.2.0 822 | '@rollup/pluginutils': 5.0.2 823 | '@unocss/config': 0.50.4 824 | '@unocss/core': 0.50.4 825 | '@unocss/inspector': 0.50.4 826 | '@unocss/scope': 0.50.4 827 | '@unocss/transformer-directives': 0.50.4 828 | chokidar: 3.5.3 829 | fast-glob: 3.2.12 830 | magic-string: 0.30.0 831 | vite: 4.2.0_@types+node@18.11.18 832 | transitivePeerDependencies: 833 | - rollup 834 | dev: false 835 | 836 | /@vitest/expect/0.29.3: 837 | resolution: {integrity: sha512-z/0JqBqqrdtrT/wzxNrWC76EpkOHdl+SvuNGxWulLaoluygntYyG5wJul5u/rQs5875zfFz/F+JaDf90SkLUIg==} 838 | dependencies: 839 | '@vitest/spy': 0.29.3 840 | '@vitest/utils': 0.29.3 841 | chai: 4.3.7 842 | dev: true 843 | 844 | /@vitest/runner/0.29.3: 845 | resolution: {integrity: sha512-XLi8ctbvOWhUWmuvBUSIBf8POEDH4zCh6bOuVxm/KGfARpgmVF1ku+vVNvyq85va+7qXxtl+MFmzyXQ2xzhAvw==} 846 | dependencies: 847 | '@vitest/utils': 0.29.3 848 | p-limit: 4.0.0 849 | pathe: 1.1.0 850 | dev: true 851 | 852 | /@vitest/spy/0.29.3: 853 | resolution: {integrity: sha512-LLpCb1oOCOZcBm0/Oxbr1DQTuKLRBsSIHyLYof7z4QVE8/v8NcZKdORjMUq645fcfX55+nLXwU/1AQ+c2rND+w==} 854 | dependencies: 855 | tinyspy: 1.1.1 856 | dev: true 857 | 858 | /@vitest/utils/0.29.3: 859 | resolution: {integrity: sha512-hg4Ff8AM1GtUnLpUJlNMxrf9f4lZr/xRJjh3uJ0QFP+vjaW82HAxKrmeBmLnhc8Os2eRf+f+VBu4ts7TafPPkA==} 860 | dependencies: 861 | cli-truncate: 3.1.0 862 | diff: 5.1.0 863 | loupe: 2.3.6 864 | pretty-format: 27.5.1 865 | dev: true 866 | 867 | /acorn-walk/8.2.0: 868 | resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} 869 | engines: {node: '>=0.4.0'} 870 | dev: true 871 | 872 | /acorn/8.8.2: 873 | resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} 874 | engines: {node: '>=0.4.0'} 875 | hasBin: true 876 | dev: true 877 | 878 | /ansi-regex/5.0.1: 879 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 880 | engines: {node: '>=8'} 881 | dev: true 882 | 883 | /ansi-regex/6.0.1: 884 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 885 | engines: {node: '>=12'} 886 | dev: true 887 | 888 | /ansi-styles/3.2.1: 889 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 890 | engines: {node: '>=4'} 891 | dependencies: 892 | color-convert: 1.9.3 893 | dev: true 894 | 895 | /ansi-styles/5.2.0: 896 | resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} 897 | engines: {node: '>=10'} 898 | dev: true 899 | 900 | /ansi-styles/6.2.1: 901 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 902 | engines: {node: '>=12'} 903 | dev: true 904 | 905 | /any-promise/1.3.0: 906 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 907 | dev: true 908 | 909 | /anymatch/3.1.3: 910 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 911 | engines: {node: '>= 8'} 912 | dependencies: 913 | normalize-path: 3.0.0 914 | picomatch: 2.3.1 915 | 916 | /array-union/2.1.0: 917 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 918 | engines: {node: '>=8'} 919 | dev: true 920 | 921 | /assertion-error/1.1.0: 922 | resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} 923 | dev: true 924 | 925 | /babel-plugin-syntax-jsx/6.18.0: 926 | resolution: {integrity: sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==} 927 | dev: true 928 | 929 | /balanced-match/1.0.2: 930 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 931 | dev: true 932 | 933 | /binary-extensions/2.2.0: 934 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 935 | engines: {node: '>=8'} 936 | 937 | /brace-expansion/1.1.11: 938 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 939 | dependencies: 940 | balanced-match: 1.0.2 941 | concat-map: 0.0.1 942 | dev: true 943 | 944 | /braces/3.0.2: 945 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 946 | engines: {node: '>=8'} 947 | dependencies: 948 | fill-range: 7.0.1 949 | 950 | /browserslist/4.21.5: 951 | resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} 952 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 953 | hasBin: true 954 | dependencies: 955 | caniuse-lite: 1.0.30001450 956 | electron-to-chromium: 1.4.284 957 | node-releases: 2.0.9 958 | update-browserslist-db: 1.0.10_browserslist@4.21.5 959 | dev: true 960 | 961 | /buffer-from/1.1.2: 962 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 963 | dev: true 964 | 965 | /bundle-require/3.1.2_esbuild@0.15.18: 966 | resolution: {integrity: sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==} 967 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 968 | peerDependencies: 969 | esbuild: '>=0.13' 970 | dependencies: 971 | esbuild: 0.15.18 972 | load-tsconfig: 0.2.3 973 | dev: true 974 | 975 | /cac/6.7.14: 976 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 977 | engines: {node: '>=8'} 978 | 979 | /camelize/1.0.1: 980 | resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} 981 | dev: false 982 | 983 | /caniuse-lite/1.0.30001450: 984 | resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==} 985 | dev: true 986 | 987 | /chai/4.3.7: 988 | resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} 989 | engines: {node: '>=4'} 990 | dependencies: 991 | assertion-error: 1.1.0 992 | check-error: 1.0.2 993 | deep-eql: 4.1.3 994 | get-func-name: 2.0.0 995 | loupe: 2.3.6 996 | pathval: 1.1.1 997 | type-detect: 4.0.8 998 | dev: true 999 | 1000 | /chalk/2.4.2: 1001 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 1002 | engines: {node: '>=4'} 1003 | dependencies: 1004 | ansi-styles: 3.2.1 1005 | escape-string-regexp: 1.0.5 1006 | supports-color: 5.5.0 1007 | dev: true 1008 | 1009 | /check-error/1.0.2: 1010 | resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} 1011 | dev: true 1012 | 1013 | /chokidar/3.5.3: 1014 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 1015 | engines: {node: '>= 8.10.0'} 1016 | dependencies: 1017 | anymatch: 3.1.3 1018 | braces: 3.0.2 1019 | glob-parent: 5.1.2 1020 | is-binary-path: 2.1.0 1021 | is-glob: 4.0.3 1022 | normalize-path: 3.0.0 1023 | readdirp: 3.6.0 1024 | optionalDependencies: 1025 | fsevents: 2.3.2 1026 | 1027 | /cli-truncate/3.1.0: 1028 | resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} 1029 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1030 | dependencies: 1031 | slice-ansi: 5.0.0 1032 | string-width: 5.1.2 1033 | dev: true 1034 | 1035 | /color-convert/1.9.3: 1036 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 1037 | dependencies: 1038 | color-name: 1.1.3 1039 | dev: true 1040 | 1041 | /color-name/1.1.3: 1042 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 1043 | dev: true 1044 | 1045 | /colorette/2.0.19: 1046 | resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} 1047 | dev: false 1048 | 1049 | /commander/4.1.1: 1050 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 1051 | engines: {node: '>= 6'} 1052 | dev: true 1053 | 1054 | /concat-map/0.0.1: 1055 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 1056 | dev: true 1057 | 1058 | /consola/2.15.3: 1059 | resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} 1060 | dev: false 1061 | 1062 | /convert-source-map/1.9.0: 1063 | resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} 1064 | dev: true 1065 | 1066 | /cross-spawn/7.0.3: 1067 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 1068 | engines: {node: '>= 8'} 1069 | dependencies: 1070 | path-key: 3.1.1 1071 | shebang-command: 2.0.0 1072 | which: 2.0.2 1073 | 1074 | /css-color-keywords/1.0.0: 1075 | resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} 1076 | engines: {node: '>=4'} 1077 | dev: false 1078 | 1079 | /css-to-react-native/3.2.0: 1080 | resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} 1081 | dependencies: 1082 | camelize: 1.0.1 1083 | css-color-keywords: 1.0.0 1084 | postcss-value-parser: 4.2.0 1085 | dev: false 1086 | 1087 | /css-tree/2.3.1: 1088 | resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} 1089 | engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} 1090 | dependencies: 1091 | mdn-data: 2.0.30 1092 | source-map-js: 1.0.2 1093 | dev: false 1094 | 1095 | /cssom/0.5.0: 1096 | resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} 1097 | dev: false 1098 | 1099 | /csstype/3.1.1: 1100 | resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} 1101 | dev: true 1102 | 1103 | /debug/4.3.4: 1104 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 1105 | engines: {node: '>=6.0'} 1106 | peerDependencies: 1107 | supports-color: '*' 1108 | peerDependenciesMeta: 1109 | supports-color: 1110 | optional: true 1111 | dependencies: 1112 | ms: 2.1.2 1113 | 1114 | /dedent/0.7.0: 1115 | resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} 1116 | dev: true 1117 | 1118 | /deep-eql/4.1.3: 1119 | resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} 1120 | engines: {node: '>=6'} 1121 | dependencies: 1122 | type-detect: 4.0.8 1123 | dev: true 1124 | 1125 | /defu/6.1.2: 1126 | resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} 1127 | dev: false 1128 | 1129 | /destr/1.2.2: 1130 | resolution: {integrity: sha512-lrbCJwD9saUQrqUfXvl6qoM+QN3W7tLV5pAOs+OqOmopCCz/JkE05MHedJR1xfk4IAnZuJXPVuN5+7jNA2ZCiA==} 1131 | dev: false 1132 | 1133 | /diff/5.1.0: 1134 | resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} 1135 | engines: {node: '>=0.3.1'} 1136 | dev: true 1137 | 1138 | /dir-glob/3.0.1: 1139 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 1140 | engines: {node: '>=8'} 1141 | dependencies: 1142 | path-type: 4.0.0 1143 | dev: true 1144 | 1145 | /duplexer/0.1.2: 1146 | resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} 1147 | dev: false 1148 | 1149 | /eastasianwidth/0.2.0: 1150 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 1151 | dev: true 1152 | 1153 | /electron-to-chromium/1.4.284: 1154 | resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} 1155 | dev: true 1156 | 1157 | /emoji-regex/9.2.2: 1158 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 1159 | dev: true 1160 | 1161 | /esbuild-android-64/0.15.18: 1162 | resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} 1163 | engines: {node: '>=12'} 1164 | cpu: [x64] 1165 | os: [android] 1166 | requiresBuild: true 1167 | dev: true 1168 | optional: true 1169 | 1170 | /esbuild-android-arm64/0.15.18: 1171 | resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} 1172 | engines: {node: '>=12'} 1173 | cpu: [arm64] 1174 | os: [android] 1175 | requiresBuild: true 1176 | dev: true 1177 | optional: true 1178 | 1179 | /esbuild-darwin-64/0.15.18: 1180 | resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} 1181 | engines: {node: '>=12'} 1182 | cpu: [x64] 1183 | os: [darwin] 1184 | requiresBuild: true 1185 | dev: true 1186 | optional: true 1187 | 1188 | /esbuild-darwin-arm64/0.15.18: 1189 | resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} 1190 | engines: {node: '>=12'} 1191 | cpu: [arm64] 1192 | os: [darwin] 1193 | requiresBuild: true 1194 | dev: true 1195 | optional: true 1196 | 1197 | /esbuild-freebsd-64/0.15.18: 1198 | resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} 1199 | engines: {node: '>=12'} 1200 | cpu: [x64] 1201 | os: [freebsd] 1202 | requiresBuild: true 1203 | dev: true 1204 | optional: true 1205 | 1206 | /esbuild-freebsd-arm64/0.15.18: 1207 | resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} 1208 | engines: {node: '>=12'} 1209 | cpu: [arm64] 1210 | os: [freebsd] 1211 | requiresBuild: true 1212 | dev: true 1213 | optional: true 1214 | 1215 | /esbuild-linux-32/0.15.18: 1216 | resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} 1217 | engines: {node: '>=12'} 1218 | cpu: [ia32] 1219 | os: [linux] 1220 | requiresBuild: true 1221 | dev: true 1222 | optional: true 1223 | 1224 | /esbuild-linux-64/0.15.18: 1225 | resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} 1226 | engines: {node: '>=12'} 1227 | cpu: [x64] 1228 | os: [linux] 1229 | requiresBuild: true 1230 | dev: true 1231 | optional: true 1232 | 1233 | /esbuild-linux-arm/0.15.18: 1234 | resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} 1235 | engines: {node: '>=12'} 1236 | cpu: [arm] 1237 | os: [linux] 1238 | requiresBuild: true 1239 | dev: true 1240 | optional: true 1241 | 1242 | /esbuild-linux-arm64/0.15.18: 1243 | resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} 1244 | engines: {node: '>=12'} 1245 | cpu: [arm64] 1246 | os: [linux] 1247 | requiresBuild: true 1248 | dev: true 1249 | optional: true 1250 | 1251 | /esbuild-linux-mips64le/0.15.18: 1252 | resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} 1253 | engines: {node: '>=12'} 1254 | cpu: [mips64el] 1255 | os: [linux] 1256 | requiresBuild: true 1257 | dev: true 1258 | optional: true 1259 | 1260 | /esbuild-linux-ppc64le/0.15.18: 1261 | resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} 1262 | engines: {node: '>=12'} 1263 | cpu: [ppc64] 1264 | os: [linux] 1265 | requiresBuild: true 1266 | dev: true 1267 | optional: true 1268 | 1269 | /esbuild-linux-riscv64/0.15.18: 1270 | resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} 1271 | engines: {node: '>=12'} 1272 | cpu: [riscv64] 1273 | os: [linux] 1274 | requiresBuild: true 1275 | dev: true 1276 | optional: true 1277 | 1278 | /esbuild-linux-s390x/0.15.18: 1279 | resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} 1280 | engines: {node: '>=12'} 1281 | cpu: [s390x] 1282 | os: [linux] 1283 | requiresBuild: true 1284 | dev: true 1285 | optional: true 1286 | 1287 | /esbuild-netbsd-64/0.15.18: 1288 | resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} 1289 | engines: {node: '>=12'} 1290 | cpu: [x64] 1291 | os: [netbsd] 1292 | requiresBuild: true 1293 | dev: true 1294 | optional: true 1295 | 1296 | /esbuild-openbsd-64/0.15.18: 1297 | resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} 1298 | engines: {node: '>=12'} 1299 | cpu: [x64] 1300 | os: [openbsd] 1301 | requiresBuild: true 1302 | dev: true 1303 | optional: true 1304 | 1305 | /esbuild-sunos-64/0.15.18: 1306 | resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} 1307 | engines: {node: '>=12'} 1308 | cpu: [x64] 1309 | os: [sunos] 1310 | requiresBuild: true 1311 | dev: true 1312 | optional: true 1313 | 1314 | /esbuild-windows-32/0.15.18: 1315 | resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} 1316 | engines: {node: '>=12'} 1317 | cpu: [ia32] 1318 | os: [win32] 1319 | requiresBuild: true 1320 | dev: true 1321 | optional: true 1322 | 1323 | /esbuild-windows-64/0.15.18: 1324 | resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} 1325 | engines: {node: '>=12'} 1326 | cpu: [x64] 1327 | os: [win32] 1328 | requiresBuild: true 1329 | dev: true 1330 | optional: true 1331 | 1332 | /esbuild-windows-arm64/0.15.18: 1333 | resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} 1334 | engines: {node: '>=12'} 1335 | cpu: [arm64] 1336 | os: [win32] 1337 | requiresBuild: true 1338 | dev: true 1339 | optional: true 1340 | 1341 | /esbuild/0.15.18: 1342 | resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} 1343 | engines: {node: '>=12'} 1344 | hasBin: true 1345 | requiresBuild: true 1346 | optionalDependencies: 1347 | '@esbuild/android-arm': 0.15.18 1348 | '@esbuild/linux-loong64': 0.15.18 1349 | esbuild-android-64: 0.15.18 1350 | esbuild-android-arm64: 0.15.18 1351 | esbuild-darwin-64: 0.15.18 1352 | esbuild-darwin-arm64: 0.15.18 1353 | esbuild-freebsd-64: 0.15.18 1354 | esbuild-freebsd-arm64: 0.15.18 1355 | esbuild-linux-32: 0.15.18 1356 | esbuild-linux-64: 0.15.18 1357 | esbuild-linux-arm: 0.15.18 1358 | esbuild-linux-arm64: 0.15.18 1359 | esbuild-linux-mips64le: 0.15.18 1360 | esbuild-linux-ppc64le: 0.15.18 1361 | esbuild-linux-riscv64: 0.15.18 1362 | esbuild-linux-s390x: 0.15.18 1363 | esbuild-netbsd-64: 0.15.18 1364 | esbuild-openbsd-64: 0.15.18 1365 | esbuild-sunos-64: 0.15.18 1366 | esbuild-windows-32: 0.15.18 1367 | esbuild-windows-64: 0.15.18 1368 | esbuild-windows-arm64: 0.15.18 1369 | dev: true 1370 | 1371 | /esbuild/0.17.11: 1372 | resolution: {integrity: sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg==} 1373 | engines: {node: '>=12'} 1374 | hasBin: true 1375 | requiresBuild: true 1376 | optionalDependencies: 1377 | '@esbuild/android-arm': 0.17.11 1378 | '@esbuild/android-arm64': 0.17.11 1379 | '@esbuild/android-x64': 0.17.11 1380 | '@esbuild/darwin-arm64': 0.17.11 1381 | '@esbuild/darwin-x64': 0.17.11 1382 | '@esbuild/freebsd-arm64': 0.17.11 1383 | '@esbuild/freebsd-x64': 0.17.11 1384 | '@esbuild/linux-arm': 0.17.11 1385 | '@esbuild/linux-arm64': 0.17.11 1386 | '@esbuild/linux-ia32': 0.17.11 1387 | '@esbuild/linux-loong64': 0.17.11 1388 | '@esbuild/linux-mips64el': 0.17.11 1389 | '@esbuild/linux-ppc64': 0.17.11 1390 | '@esbuild/linux-riscv64': 0.17.11 1391 | '@esbuild/linux-s390x': 0.17.11 1392 | '@esbuild/linux-x64': 0.17.11 1393 | '@esbuild/netbsd-x64': 0.17.11 1394 | '@esbuild/openbsd-x64': 0.17.11 1395 | '@esbuild/sunos-x64': 0.17.11 1396 | '@esbuild/win32-arm64': 0.17.11 1397 | '@esbuild/win32-ia32': 0.17.11 1398 | '@esbuild/win32-x64': 0.17.11 1399 | 1400 | /escalade/3.1.1: 1401 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 1402 | engines: {node: '>=6'} 1403 | dev: true 1404 | 1405 | /escape-string-regexp/1.0.5: 1406 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 1407 | engines: {node: '>=0.8.0'} 1408 | dev: true 1409 | 1410 | /estree-walker/2.0.2: 1411 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 1412 | dev: false 1413 | 1414 | /execa/5.1.1: 1415 | resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} 1416 | engines: {node: '>=10'} 1417 | dependencies: 1418 | cross-spawn: 7.0.3 1419 | get-stream: 6.0.1 1420 | human-signals: 2.1.0 1421 | is-stream: 2.0.1 1422 | merge-stream: 2.0.0 1423 | npm-run-path: 4.0.1 1424 | onetime: 5.1.2 1425 | signal-exit: 3.0.7 1426 | strip-final-newline: 2.0.0 1427 | 1428 | /fast-glob/3.2.12: 1429 | resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} 1430 | engines: {node: '>=8.6.0'} 1431 | dependencies: 1432 | '@nodelib/fs.stat': 2.0.5 1433 | '@nodelib/fs.walk': 1.2.8 1434 | glob-parent: 5.1.2 1435 | merge2: 1.4.1 1436 | micromatch: 4.0.5 1437 | 1438 | /fastq/1.15.0: 1439 | resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} 1440 | dependencies: 1441 | reusify: 1.0.4 1442 | 1443 | /fill-range/7.0.1: 1444 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 1445 | engines: {node: '>=8'} 1446 | dependencies: 1447 | to-regex-range: 5.0.1 1448 | 1449 | /find-up/5.0.0: 1450 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 1451 | engines: {node: '>=10'} 1452 | dependencies: 1453 | locate-path: 6.0.0 1454 | path-exists: 4.0.0 1455 | dev: false 1456 | 1457 | /fs.realpath/1.0.0: 1458 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 1459 | dev: true 1460 | 1461 | /fsevents/2.3.2: 1462 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 1463 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1464 | os: [darwin] 1465 | requiresBuild: true 1466 | optional: true 1467 | 1468 | /function-bind/1.1.1: 1469 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 1470 | 1471 | /gensync/1.0.0-beta.2: 1472 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 1473 | engines: {node: '>=6.9.0'} 1474 | dev: true 1475 | 1476 | /get-func-name/2.0.0: 1477 | resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} 1478 | dev: true 1479 | 1480 | /get-stream/6.0.1: 1481 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 1482 | engines: {node: '>=10'} 1483 | 1484 | /get-tsconfig/4.3.0: 1485 | resolution: {integrity: sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ==} 1486 | dev: true 1487 | 1488 | /glob-parent/5.1.2: 1489 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 1490 | engines: {node: '>= 6'} 1491 | dependencies: 1492 | is-glob: 4.0.3 1493 | 1494 | /glob/7.1.6: 1495 | resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} 1496 | dependencies: 1497 | fs.realpath: 1.0.0 1498 | inflight: 1.0.6 1499 | inherits: 2.0.4 1500 | minimatch: 3.1.2 1501 | once: 1.4.0 1502 | path-is-absolute: 1.0.1 1503 | dev: true 1504 | 1505 | /globals/11.12.0: 1506 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 1507 | engines: {node: '>=4'} 1508 | dev: true 1509 | 1510 | /globby/11.1.0: 1511 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 1512 | engines: {node: '>=10'} 1513 | dependencies: 1514 | array-union: 2.1.0 1515 | dir-glob: 3.0.1 1516 | fast-glob: 3.2.12 1517 | ignore: 5.2.4 1518 | merge2: 1.4.1 1519 | slash: 3.0.0 1520 | dev: true 1521 | 1522 | /gzip-size/6.0.0: 1523 | resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} 1524 | engines: {node: '>=10'} 1525 | dependencies: 1526 | duplexer: 0.1.2 1527 | dev: false 1528 | 1529 | /has-flag/3.0.0: 1530 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 1531 | engines: {node: '>=4'} 1532 | dev: true 1533 | 1534 | /has/1.0.3: 1535 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 1536 | engines: {node: '>= 0.4.0'} 1537 | dependencies: 1538 | function-bind: 1.1.1 1539 | 1540 | /human-signals/2.1.0: 1541 | resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} 1542 | engines: {node: '>=10.17.0'} 1543 | 1544 | /ignore/5.2.4: 1545 | resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} 1546 | engines: {node: '>= 4'} 1547 | dev: true 1548 | 1549 | /inflight/1.0.6: 1550 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 1551 | dependencies: 1552 | once: 1.4.0 1553 | wrappy: 1.0.2 1554 | dev: true 1555 | 1556 | /inherits/2.0.4: 1557 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 1558 | dev: true 1559 | 1560 | /is-binary-path/2.1.0: 1561 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 1562 | engines: {node: '>=8'} 1563 | dependencies: 1564 | binary-extensions: 2.2.0 1565 | 1566 | /is-core-module/2.11.0: 1567 | resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} 1568 | dependencies: 1569 | has: 1.0.3 1570 | 1571 | /is-extglob/2.1.1: 1572 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 1573 | engines: {node: '>=0.10.0'} 1574 | 1575 | /is-fullwidth-code-point/4.0.0: 1576 | resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} 1577 | engines: {node: '>=12'} 1578 | dev: true 1579 | 1580 | /is-glob/4.0.3: 1581 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 1582 | engines: {node: '>=0.10.0'} 1583 | dependencies: 1584 | is-extglob: 2.1.1 1585 | 1586 | /is-number/7.0.0: 1587 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 1588 | engines: {node: '>=0.12.0'} 1589 | 1590 | /is-stream/2.0.1: 1591 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} 1592 | engines: {node: '>=8'} 1593 | 1594 | /isexe/2.0.0: 1595 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 1596 | 1597 | /jiti/1.17.2: 1598 | resolution: {integrity: sha512-Xf0nU8+8wuiQpLcqdb2HRyHqYwGk2Pd+F7kstyp20ZuqTyCmB9dqpX2NxaxFc1kovraa2bG6c1RL3W7XfapiZg==} 1599 | hasBin: true 1600 | dev: false 1601 | 1602 | /joycon/3.1.1: 1603 | resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} 1604 | engines: {node: '>=10'} 1605 | dev: true 1606 | 1607 | /js-tokens/4.0.0: 1608 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1609 | dev: true 1610 | 1611 | /jsesc/2.5.2: 1612 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} 1613 | engines: {node: '>=4'} 1614 | hasBin: true 1615 | dev: true 1616 | 1617 | /json5/2.2.3: 1618 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 1619 | engines: {node: '>=6'} 1620 | hasBin: true 1621 | dev: true 1622 | 1623 | /jsonc-parser/3.2.0: 1624 | resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} 1625 | dev: true 1626 | 1627 | /kolorist/1.7.0: 1628 | resolution: {integrity: sha512-ymToLHqL02udwVdbkowNpzjFd6UzozMtshPQKVi5k1EjKRqKqBrOnE9QbLEb0/pV76SAiIT13hdL8R6suc+f3g==} 1629 | dev: false 1630 | 1631 | /lilconfig/2.0.6: 1632 | resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} 1633 | engines: {node: '>=10'} 1634 | dev: true 1635 | 1636 | /lines-and-columns/1.2.4: 1637 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 1638 | dev: true 1639 | 1640 | /load-tsconfig/0.2.3: 1641 | resolution: {integrity: sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ==} 1642 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1643 | dev: true 1644 | 1645 | /local-pkg/0.4.3: 1646 | resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} 1647 | engines: {node: '>=14'} 1648 | 1649 | /locate-path/6.0.0: 1650 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 1651 | engines: {node: '>=10'} 1652 | dependencies: 1653 | p-locate: 5.0.0 1654 | dev: false 1655 | 1656 | /lodash.sortby/4.7.0: 1657 | resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} 1658 | dev: true 1659 | 1660 | /loupe/2.3.6: 1661 | resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} 1662 | dependencies: 1663 | get-func-name: 2.0.0 1664 | dev: true 1665 | 1666 | /lru-cache/5.1.1: 1667 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} 1668 | dependencies: 1669 | yallist: 3.1.1 1670 | dev: true 1671 | 1672 | /magic-string/0.30.0: 1673 | resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} 1674 | engines: {node: '>=12'} 1675 | dependencies: 1676 | '@jridgewell/sourcemap-codec': 1.4.14 1677 | dev: false 1678 | 1679 | /mdn-data/2.0.30: 1680 | resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} 1681 | dev: false 1682 | 1683 | /merge-stream/2.0.0: 1684 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 1685 | 1686 | /merge2/1.4.1: 1687 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1688 | engines: {node: '>= 8'} 1689 | 1690 | /micromatch/4.0.5: 1691 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 1692 | engines: {node: '>=8.6'} 1693 | dependencies: 1694 | braces: 3.0.2 1695 | picomatch: 2.3.1 1696 | 1697 | /mimic-fn/2.1.0: 1698 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 1699 | engines: {node: '>=6'} 1700 | 1701 | /minimatch/3.1.2: 1702 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1703 | dependencies: 1704 | brace-expansion: 1.1.11 1705 | dev: true 1706 | 1707 | /mlly/1.2.0: 1708 | resolution: {integrity: sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==} 1709 | dependencies: 1710 | acorn: 8.8.2 1711 | pathe: 1.1.0 1712 | pkg-types: 1.0.2 1713 | ufo: 1.1.1 1714 | dev: true 1715 | 1716 | /mrmime/1.0.1: 1717 | resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} 1718 | engines: {node: '>=10'} 1719 | dev: false 1720 | 1721 | /ms/2.1.2: 1722 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1723 | 1724 | /mz/2.7.0: 1725 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 1726 | dependencies: 1727 | any-promise: 1.3.0 1728 | object-assign: 4.1.1 1729 | thenify-all: 1.6.0 1730 | dev: true 1731 | 1732 | /nanoid/3.3.4: 1733 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 1734 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1735 | hasBin: true 1736 | 1737 | /node-fetch-native/1.0.2: 1738 | resolution: {integrity: sha512-KIkvH1jl6b3O7es/0ShyCgWLcfXxlBrLBbP3rOr23WArC66IMcU4DeZEeYEOwnopYhawLTn7/y+YtmASe8DFVQ==} 1739 | dev: false 1740 | 1741 | /node-releases/2.0.9: 1742 | resolution: {integrity: sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==} 1743 | dev: true 1744 | 1745 | /normalize-path/3.0.0: 1746 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 1747 | engines: {node: '>=0.10.0'} 1748 | 1749 | /npm-run-path/4.0.1: 1750 | resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} 1751 | engines: {node: '>=8'} 1752 | dependencies: 1753 | path-key: 3.1.1 1754 | 1755 | /object-assign/4.1.1: 1756 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 1757 | engines: {node: '>=0.10.0'} 1758 | dev: true 1759 | 1760 | /ofetch/1.0.1: 1761 | resolution: {integrity: sha512-icBz2JYfEpt+wZz1FRoGcrMigjNKjzvufE26m9+yUiacRQRHwnNlGRPiDnW4op7WX/MR6aniwS8xw8jyVelF2g==} 1762 | dependencies: 1763 | destr: 1.2.2 1764 | node-fetch-native: 1.0.2 1765 | ufo: 1.1.1 1766 | dev: false 1767 | 1768 | /once/1.4.0: 1769 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 1770 | dependencies: 1771 | wrappy: 1.0.2 1772 | dev: true 1773 | 1774 | /onetime/5.1.2: 1775 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 1776 | engines: {node: '>=6'} 1777 | dependencies: 1778 | mimic-fn: 2.1.0 1779 | 1780 | /p-limit/3.1.0: 1781 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1782 | engines: {node: '>=10'} 1783 | dependencies: 1784 | yocto-queue: 0.1.0 1785 | dev: false 1786 | 1787 | /p-limit/4.0.0: 1788 | resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} 1789 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1790 | dependencies: 1791 | yocto-queue: 1.0.0 1792 | dev: true 1793 | 1794 | /p-locate/5.0.0: 1795 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 1796 | engines: {node: '>=10'} 1797 | dependencies: 1798 | p-limit: 3.1.0 1799 | dev: false 1800 | 1801 | /path-exists/4.0.0: 1802 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1803 | engines: {node: '>=8'} 1804 | dev: false 1805 | 1806 | /path-is-absolute/1.0.1: 1807 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 1808 | engines: {node: '>=0.10.0'} 1809 | dev: true 1810 | 1811 | /path-key/3.1.1: 1812 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1813 | engines: {node: '>=8'} 1814 | 1815 | /path-parse/1.0.7: 1816 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 1817 | 1818 | /path-type/4.0.0: 1819 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1820 | engines: {node: '>=8'} 1821 | dev: true 1822 | 1823 | /pathe/1.1.0: 1824 | resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==} 1825 | 1826 | /pathval/1.1.1: 1827 | resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} 1828 | dev: true 1829 | 1830 | /perfect-debounce/0.1.3: 1831 | resolution: {integrity: sha512-NOT9AcKiDGpnV/HBhI22Str++XWcErO/bALvHCuhv33owZW/CjH8KAFLZDCmu3727sihe0wTxpDhyGc6M8qacQ==} 1832 | dev: false 1833 | 1834 | /picocolors/1.0.0: 1835 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 1836 | 1837 | /picomatch/2.3.1: 1838 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1839 | engines: {node: '>=8.6'} 1840 | 1841 | /pirates/4.0.5: 1842 | resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} 1843 | engines: {node: '>= 6'} 1844 | dev: true 1845 | 1846 | /pkg-types/1.0.2: 1847 | resolution: {integrity: sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==} 1848 | dependencies: 1849 | jsonc-parser: 3.2.0 1850 | mlly: 1.2.0 1851 | pathe: 1.1.0 1852 | dev: true 1853 | 1854 | /postcss-load-config/3.1.4: 1855 | resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} 1856 | engines: {node: '>= 10'} 1857 | peerDependencies: 1858 | postcss: '>=8.0.9' 1859 | ts-node: '>=9.0.0' 1860 | peerDependenciesMeta: 1861 | postcss: 1862 | optional: true 1863 | ts-node: 1864 | optional: true 1865 | dependencies: 1866 | lilconfig: 2.0.6 1867 | yaml: 1.10.2 1868 | dev: true 1869 | 1870 | /postcss-value-parser/4.2.0: 1871 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 1872 | dev: false 1873 | 1874 | /postcss/8.4.21: 1875 | resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} 1876 | engines: {node: ^10 || ^12 || >=14} 1877 | dependencies: 1878 | nanoid: 3.3.4 1879 | picocolors: 1.0.0 1880 | source-map-js: 1.0.2 1881 | 1882 | /pretty-format/27.5.1: 1883 | resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} 1884 | engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} 1885 | dependencies: 1886 | ansi-regex: 5.0.1 1887 | ansi-styles: 5.2.0 1888 | react-is: 17.0.2 1889 | dev: true 1890 | 1891 | /punycode/2.3.0: 1892 | resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} 1893 | engines: {node: '>=6'} 1894 | dev: true 1895 | 1896 | /queue-microtask/1.2.3: 1897 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1898 | 1899 | /react-is/17.0.2: 1900 | resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} 1901 | dev: true 1902 | 1903 | /readdirp/3.6.0: 1904 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1905 | engines: {node: '>=8.10.0'} 1906 | dependencies: 1907 | picomatch: 2.3.1 1908 | 1909 | /resolve-from/5.0.0: 1910 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 1911 | engines: {node: '>=8'} 1912 | dev: true 1913 | 1914 | /resolve/1.22.1: 1915 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 1916 | hasBin: true 1917 | dependencies: 1918 | is-core-module: 2.11.0 1919 | path-parse: 1.0.7 1920 | supports-preserve-symlinks-flag: 1.0.0 1921 | 1922 | /reusify/1.0.4: 1923 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1924 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1925 | 1926 | /rollup/3.14.0: 1927 | resolution: {integrity: sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==} 1928 | engines: {node: '>=14.18.0', npm: '>=8.0.0'} 1929 | hasBin: true 1930 | optionalDependencies: 1931 | fsevents: 2.3.2 1932 | dev: true 1933 | 1934 | /rollup/3.19.1: 1935 | resolution: {integrity: sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==} 1936 | engines: {node: '>=14.18.0', npm: '>=8.0.0'} 1937 | hasBin: true 1938 | optionalDependencies: 1939 | fsevents: 2.3.2 1940 | 1941 | /run-parallel/1.2.0: 1942 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1943 | dependencies: 1944 | queue-microtask: 1.2.3 1945 | 1946 | /semver/6.3.0: 1947 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} 1948 | hasBin: true 1949 | dev: true 1950 | 1951 | /shebang-command/2.0.0: 1952 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1953 | engines: {node: '>=8'} 1954 | dependencies: 1955 | shebang-regex: 3.0.0 1956 | 1957 | /shebang-regex/3.0.0: 1958 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1959 | engines: {node: '>=8'} 1960 | 1961 | /siginfo/2.0.0: 1962 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 1963 | dev: true 1964 | 1965 | /signal-exit/3.0.7: 1966 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 1967 | 1968 | /sirv/2.0.2: 1969 | resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==} 1970 | engines: {node: '>= 10'} 1971 | dependencies: 1972 | '@polka/url': 1.0.0-next.21 1973 | mrmime: 1.0.1 1974 | totalist: 3.0.0 1975 | dev: false 1976 | 1977 | /slash/3.0.0: 1978 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 1979 | engines: {node: '>=8'} 1980 | dev: true 1981 | 1982 | /slice-ansi/5.0.0: 1983 | resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} 1984 | engines: {node: '>=12'} 1985 | dependencies: 1986 | ansi-styles: 6.2.1 1987 | is-fullwidth-code-point: 4.0.0 1988 | dev: true 1989 | 1990 | /source-map-js/1.0.2: 1991 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 1992 | engines: {node: '>=0.10.0'} 1993 | 1994 | /source-map-support/0.5.21: 1995 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 1996 | dependencies: 1997 | buffer-from: 1.1.2 1998 | source-map: 0.6.1 1999 | dev: true 2000 | 2001 | /source-map/0.6.1: 2002 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 2003 | engines: {node: '>=0.10.0'} 2004 | dev: true 2005 | 2006 | /source-map/0.8.0-beta.0: 2007 | resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} 2008 | engines: {node: '>= 8'} 2009 | dependencies: 2010 | whatwg-url: 7.1.0 2011 | dev: true 2012 | 2013 | /stackback/0.0.2: 2014 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 2015 | dev: true 2016 | 2017 | /std-env/3.3.2: 2018 | resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==} 2019 | dev: true 2020 | 2021 | /string-width/5.1.2: 2022 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 2023 | engines: {node: '>=12'} 2024 | dependencies: 2025 | eastasianwidth: 0.2.0 2026 | emoji-regex: 9.2.2 2027 | strip-ansi: 7.0.1 2028 | dev: true 2029 | 2030 | /strip-ansi/7.0.1: 2031 | resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} 2032 | engines: {node: '>=12'} 2033 | dependencies: 2034 | ansi-regex: 6.0.1 2035 | dev: true 2036 | 2037 | /strip-final-newline/2.0.0: 2038 | resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} 2039 | engines: {node: '>=6'} 2040 | 2041 | /strip-literal/1.0.1: 2042 | resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} 2043 | dependencies: 2044 | acorn: 8.8.2 2045 | dev: true 2046 | 2047 | /sucrase/3.29.0: 2048 | resolution: {integrity: sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==} 2049 | engines: {node: '>=8'} 2050 | hasBin: true 2051 | dependencies: 2052 | commander: 4.1.1 2053 | glob: 7.1.6 2054 | lines-and-columns: 1.2.4 2055 | mz: 2.7.0 2056 | pirates: 4.0.5 2057 | ts-interface-checker: 0.1.13 2058 | dev: true 2059 | 2060 | /supports-color/5.5.0: 2061 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 2062 | engines: {node: '>=4'} 2063 | dependencies: 2064 | has-flag: 3.0.0 2065 | dev: true 2066 | 2067 | /supports-preserve-symlinks-flag/1.0.0: 2068 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 2069 | engines: {node: '>= 0.4'} 2070 | 2071 | /thenify-all/1.6.0: 2072 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 2073 | engines: {node: '>=0.8'} 2074 | dependencies: 2075 | thenify: 3.3.1 2076 | dev: true 2077 | 2078 | /thenify/3.3.1: 2079 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} 2080 | dependencies: 2081 | any-promise: 1.3.0 2082 | dev: true 2083 | 2084 | /tinybench/2.4.0: 2085 | resolution: {integrity: sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==} 2086 | dev: true 2087 | 2088 | /tinypool/0.3.1: 2089 | resolution: {integrity: sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==} 2090 | engines: {node: '>=14.0.0'} 2091 | dev: true 2092 | 2093 | /tinyspy/1.1.1: 2094 | resolution: {integrity: sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==} 2095 | engines: {node: '>=14.0.0'} 2096 | dev: true 2097 | 2098 | /to-fast-properties/2.0.0: 2099 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 2100 | engines: {node: '>=4'} 2101 | 2102 | /to-regex-range/5.0.1: 2103 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 2104 | engines: {node: '>=8.0'} 2105 | dependencies: 2106 | is-number: 7.0.0 2107 | 2108 | /totalist/3.0.0: 2109 | resolution: {integrity: sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==} 2110 | engines: {node: '>=6'} 2111 | dev: false 2112 | 2113 | /tr46/1.0.1: 2114 | resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} 2115 | dependencies: 2116 | punycode: 2.3.0 2117 | dev: true 2118 | 2119 | /tree-kill/1.2.2: 2120 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 2121 | hasBin: true 2122 | dev: true 2123 | 2124 | /ts-interface-checker/0.1.13: 2125 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 2126 | dev: true 2127 | 2128 | /tsup/6.5.0_typescript@4.9.5: 2129 | resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==} 2130 | engines: {node: '>=14'} 2131 | hasBin: true 2132 | peerDependencies: 2133 | '@swc/core': ^1 2134 | postcss: ^8.4.12 2135 | typescript: ^4.1.0 2136 | peerDependenciesMeta: 2137 | '@swc/core': 2138 | optional: true 2139 | postcss: 2140 | optional: true 2141 | typescript: 2142 | optional: true 2143 | dependencies: 2144 | bundle-require: 3.1.2_esbuild@0.15.18 2145 | cac: 6.7.14 2146 | chokidar: 3.5.3 2147 | debug: 4.3.4 2148 | esbuild: 0.15.18 2149 | execa: 5.1.1 2150 | globby: 11.1.0 2151 | joycon: 3.1.1 2152 | postcss-load-config: 3.1.4 2153 | resolve-from: 5.0.0 2154 | rollup: 3.14.0 2155 | source-map: 0.8.0-beta.0 2156 | sucrase: 3.29.0 2157 | tree-kill: 1.2.2 2158 | typescript: 4.9.5 2159 | transitivePeerDependencies: 2160 | - supports-color 2161 | - ts-node 2162 | dev: true 2163 | 2164 | /tsx/3.12.2: 2165 | resolution: {integrity: sha512-ykAEkoBg30RXxeOMVeZwar+JH632dZn9EUJVyJwhfag62k6UO/dIyJEV58YuLF6e5BTdV/qmbQrpkWqjq9cUnQ==} 2166 | hasBin: true 2167 | dependencies: 2168 | '@esbuild-kit/cjs-loader': 2.4.1 2169 | '@esbuild-kit/core-utils': 3.0.0 2170 | '@esbuild-kit/esm-loader': 2.5.4 2171 | optionalDependencies: 2172 | fsevents: 2.3.2 2173 | dev: true 2174 | 2175 | /type-detect/4.0.8: 2176 | resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} 2177 | engines: {node: '>=4'} 2178 | dev: true 2179 | 2180 | /typescript/4.9.5: 2181 | resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} 2182 | engines: {node: '>=4.2.0'} 2183 | hasBin: true 2184 | dev: true 2185 | 2186 | /ufo/1.1.1: 2187 | resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==} 2188 | 2189 | /unconfig/0.3.7: 2190 | resolution: {integrity: sha512-1589b7oGa8ILBYpta7TndM5mLHLzHUqBfhszeZxuUBrjO/RoQ52VGVWsS3w0C0GLNxO9RPmqkf6BmIvBApaRdA==} 2191 | dependencies: 2192 | '@antfu/utils': 0.5.2 2193 | defu: 6.1.2 2194 | jiti: 1.17.2 2195 | dev: false 2196 | 2197 | /unocss/0.50.4_vite@4.2.0: 2198 | resolution: {integrity: sha512-9offjUEwVlAkR//0sidTyvKkSArRGkDdgSFeW4P4005GWnjmXnbx4amuAeS3Au4o8WoshZCCOi5EYrpO4aLdfg==} 2199 | engines: {node: '>=14'} 2200 | peerDependencies: 2201 | '@unocss/webpack': 0.50.4 2202 | peerDependenciesMeta: 2203 | '@unocss/webpack': 2204 | optional: true 2205 | dependencies: 2206 | '@unocss/astro': 0.50.4_vite@4.2.0 2207 | '@unocss/cli': 0.50.4 2208 | '@unocss/core': 0.50.4 2209 | '@unocss/postcss': 0.50.4 2210 | '@unocss/preset-attributify': 0.50.4 2211 | '@unocss/preset-icons': 0.50.4 2212 | '@unocss/preset-mini': 0.50.4 2213 | '@unocss/preset-tagify': 0.50.4 2214 | '@unocss/preset-typography': 0.50.4 2215 | '@unocss/preset-uno': 0.50.4 2216 | '@unocss/preset-web-fonts': 0.50.4 2217 | '@unocss/preset-wind': 0.50.4 2218 | '@unocss/reset': 0.50.4 2219 | '@unocss/transformer-attributify-jsx': 0.50.4 2220 | '@unocss/transformer-compile-class': 0.50.4 2221 | '@unocss/transformer-directives': 0.50.4 2222 | '@unocss/transformer-variant-group': 0.50.4 2223 | '@unocss/vite': 0.50.4_vite@4.2.0 2224 | transitivePeerDependencies: 2225 | - rollup 2226 | - supports-color 2227 | - vite 2228 | dev: false 2229 | 2230 | /update-browserslist-db/1.0.10_browserslist@4.21.5: 2231 | resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} 2232 | hasBin: true 2233 | peerDependencies: 2234 | browserslist: '>= 4.21.0' 2235 | dependencies: 2236 | browserslist: 4.21.5 2237 | escalade: 3.1.1 2238 | picocolors: 1.0.0 2239 | dev: true 2240 | 2241 | /vite-node/0.29.3_@types+node@18.15.3: 2242 | resolution: {integrity: sha512-QYzYSA4Yt2IiduEjYbccfZQfxKp+T1Do8/HEpSX/G5WIECTFKJADwLs9c94aQH4o0A+UtCKU61lj1m5KvbxxQA==} 2243 | engines: {node: '>=v14.16.0'} 2244 | hasBin: true 2245 | dependencies: 2246 | cac: 6.7.14 2247 | debug: 4.3.4 2248 | mlly: 1.2.0 2249 | pathe: 1.1.0 2250 | picocolors: 1.0.0 2251 | vite: 4.2.0_@types+node@18.15.3 2252 | transitivePeerDependencies: 2253 | - '@types/node' 2254 | - less 2255 | - sass 2256 | - stylus 2257 | - sugarss 2258 | - supports-color 2259 | - terser 2260 | dev: true 2261 | 2262 | /vite/4.2.0_@types+node@18.11.18: 2263 | resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} 2264 | engines: {node: ^14.18.0 || >=16.0.0} 2265 | hasBin: true 2266 | peerDependencies: 2267 | '@types/node': '>= 14' 2268 | less: '*' 2269 | sass: '*' 2270 | stylus: '*' 2271 | sugarss: '*' 2272 | terser: ^5.4.0 2273 | peerDependenciesMeta: 2274 | '@types/node': 2275 | optional: true 2276 | less: 2277 | optional: true 2278 | sass: 2279 | optional: true 2280 | stylus: 2281 | optional: true 2282 | sugarss: 2283 | optional: true 2284 | terser: 2285 | optional: true 2286 | dependencies: 2287 | '@types/node': 18.11.18 2288 | esbuild: 0.17.11 2289 | postcss: 8.4.21 2290 | resolve: 1.22.1 2291 | rollup: 3.19.1 2292 | optionalDependencies: 2293 | fsevents: 2.3.2 2294 | 2295 | /vite/4.2.0_@types+node@18.15.3: 2296 | resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} 2297 | engines: {node: ^14.18.0 || >=16.0.0} 2298 | hasBin: true 2299 | peerDependencies: 2300 | '@types/node': '>= 14' 2301 | less: '*' 2302 | sass: '*' 2303 | stylus: '*' 2304 | sugarss: '*' 2305 | terser: ^5.4.0 2306 | peerDependenciesMeta: 2307 | '@types/node': 2308 | optional: true 2309 | less: 2310 | optional: true 2311 | sass: 2312 | optional: true 2313 | stylus: 2314 | optional: true 2315 | sugarss: 2316 | optional: true 2317 | terser: 2318 | optional: true 2319 | dependencies: 2320 | '@types/node': 18.15.3 2321 | esbuild: 0.17.11 2322 | postcss: 8.4.21 2323 | resolve: 1.22.1 2324 | rollup: 3.19.1 2325 | optionalDependencies: 2326 | fsevents: 2.3.2 2327 | dev: true 2328 | 2329 | /vitest/0.29.3: 2330 | resolution: {integrity: sha512-muMsbXnZsrzDGiyqf/09BKQsGeUxxlyLeLK/sFFM4EXdURPQRv8y7dco32DXaRORYP0bvyN19C835dT23mL0ow==} 2331 | engines: {node: '>=v14.16.0'} 2332 | hasBin: true 2333 | peerDependencies: 2334 | '@edge-runtime/vm': '*' 2335 | '@vitest/browser': '*' 2336 | '@vitest/ui': '*' 2337 | happy-dom: '*' 2338 | jsdom: '*' 2339 | peerDependenciesMeta: 2340 | '@edge-runtime/vm': 2341 | optional: true 2342 | '@vitest/browser': 2343 | optional: true 2344 | '@vitest/ui': 2345 | optional: true 2346 | happy-dom: 2347 | optional: true 2348 | jsdom: 2349 | optional: true 2350 | dependencies: 2351 | '@types/chai': 4.3.4 2352 | '@types/chai-subset': 1.3.3 2353 | '@types/node': 18.15.3 2354 | '@vitest/expect': 0.29.3 2355 | '@vitest/runner': 0.29.3 2356 | '@vitest/spy': 0.29.3 2357 | '@vitest/utils': 0.29.3 2358 | acorn: 8.8.2 2359 | acorn-walk: 8.2.0 2360 | cac: 6.7.14 2361 | chai: 4.3.7 2362 | debug: 4.3.4 2363 | local-pkg: 0.4.3 2364 | pathe: 1.1.0 2365 | picocolors: 1.0.0 2366 | source-map: 0.6.1 2367 | std-env: 3.3.2 2368 | strip-literal: 1.0.1 2369 | tinybench: 2.4.0 2370 | tinypool: 0.3.1 2371 | tinyspy: 1.1.1 2372 | vite: 4.2.0_@types+node@18.15.3 2373 | vite-node: 0.29.3_@types+node@18.15.3 2374 | why-is-node-running: 2.2.2 2375 | transitivePeerDependencies: 2376 | - less 2377 | - sass 2378 | - stylus 2379 | - sugarss 2380 | - supports-color 2381 | - terser 2382 | dev: true 2383 | 2384 | /webidl-conversions/4.0.2: 2385 | resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} 2386 | dev: true 2387 | 2388 | /whatwg-url/7.1.0: 2389 | resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} 2390 | dependencies: 2391 | lodash.sortby: 4.7.0 2392 | tr46: 1.0.1 2393 | webidl-conversions: 4.0.2 2394 | dev: true 2395 | 2396 | /which/2.0.2: 2397 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 2398 | engines: {node: '>= 8'} 2399 | hasBin: true 2400 | dependencies: 2401 | isexe: 2.0.0 2402 | 2403 | /why-is-node-running/2.2.2: 2404 | resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} 2405 | engines: {node: '>=8'} 2406 | hasBin: true 2407 | dependencies: 2408 | siginfo: 2.0.0 2409 | stackback: 0.0.2 2410 | dev: true 2411 | 2412 | /wrappy/1.0.2: 2413 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 2414 | dev: true 2415 | 2416 | /yallist/3.1.1: 2417 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} 2418 | dev: true 2419 | 2420 | /yaml/1.10.2: 2421 | resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} 2422 | engines: {node: '>= 6'} 2423 | dev: true 2424 | 2425 | /yocto-queue/0.1.0: 2426 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 2427 | engines: {node: '>=10'} 2428 | dev: false 2429 | 2430 | /yocto-queue/1.0.0: 2431 | resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} 2432 | engines: {node: '>=12.20'} 2433 | dev: true 2434 | -------------------------------------------------------------------------------- /src/babel.ts: -------------------------------------------------------------------------------- 1 | import babel, { PluginObj } from '@babel/core'; 2 | import { addNamed } from '@babel/helper-module-imports'; 3 | 4 | /** 5 | * 将 6 | * 处理为 7 | * @param classNamePath 8 | */ 9 | function processOpeningElement( 10 | classNamePath: babel.NodePath, 11 | t: typeof babel['types'] 12 | ) { 13 | const jsxElementPath = classNamePath.findParent( 14 | (v) => v.type === 'JSXElement' 15 | )! as babel.NodePath; 16 | const jsxOpeningElementPath = 17 | classNamePath.parentPath as babel.NodePath; 18 | 19 | const openingElementName = jsxOpeningElementPath.node 20 | .name as babel.types.JSXIdentifier; 21 | 22 | jsxOpeningElementPath.node.attributes.push( 23 | t.jSXAttribute( 24 | t.jSXIdentifier('component'), 25 | t.jsxExpressionContainer(t.identifier(openingElementName.name)) 26 | ) 27 | ); 28 | 29 | // rename jsx tag name 30 | [jsxElementPath.node.openingElement, jsxElementPath.node.closingElement] 31 | .filter(Boolean) 32 | .forEach((node) => { 33 | if (node!.name.type === 'JSXIdentifier') { 34 | node!.name.name = '_UnoStyled'; 35 | } 36 | }); 37 | 38 | const programPath = classNamePath.findParent( 39 | (v) => v.type === 'Program' 40 | ) as any; 41 | if (programPath.__process) return; 42 | // add _ prefix 43 | programPath.__process = true; 44 | addNamed(programPath, 'UnoStyled', 'unonative'); 45 | } 46 | 47 | export default ({ types }: typeof babel): PluginObj => { 48 | return { 49 | visitor: { 50 | Program: { 51 | enter(program) {}, 52 | exit(program) {}, 53 | }, 54 | JSXAttribute(classNamePath) { 55 | if (classNamePath.node.name.name !== 'className') return; 56 | processOpeningElement(classNamePath, types); 57 | }, 58 | }, 59 | }; 60 | }; 61 | -------------------------------------------------------------------------------- /src/hoc/hub.ts: -------------------------------------------------------------------------------- 1 | import type { StyleProp, ViewStyle } from 'react-native'; 2 | 3 | class Hub { 4 | private styleHub = new Map(); 5 | register = (styleObject: Record) => { 6 | for (const [k, v] of Object.entries(styleObject)) { 7 | this.styleHub.set(k, v); 8 | } 9 | }; 10 | get(v: string) { 11 | return this.styleHub.get(v.trim()); 12 | } 13 | } 14 | 15 | const hub = new Hub(); 16 | 17 | function uno(className: string): StyleProp { 18 | className = className || ''; 19 | const style = className.split(' ').map((v) => hub.get(v)); 20 | 21 | return style; 22 | } 23 | 24 | export { uno, hub }; 25 | -------------------------------------------------------------------------------- /src/hoc/icon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text } from 'react-native'; 3 | 4 | const stylesToObject = (styles: Record[]) => { 5 | return styles.reduce((prev, current) => { 6 | return Object.assign(prev, current); 7 | }, {}); 8 | }; 9 | 10 | function tryRequireSvgXml() { 11 | try { 12 | return require('react-native-svg').SvgXml; 13 | } catch (e) { 14 | return null; 15 | } 16 | } 17 | 18 | const SvgXml = tryRequireSvgXml(); 19 | function IconSvgXml(props: { icon: string; className: string }) { 20 | // @ts-ignore 21 | const { icon, style } = props; 22 | const styles = React.useMemo(() => stylesToObject(style), [props.className]); 23 | if (!icon.startsWith(' 26 | {icon} not found 27 | 28 | ); 29 | 30 | return ( 31 | 38 | ); 39 | } 40 | 41 | function IconNotImplement(props: { icon: string; className: string }) { 42 | return ( 43 | 44 | react-native-svg not resolve 45 | 46 | ); 47 | } 48 | 49 | export function Icon(props: { icon: string; className: string }) { 50 | return SvgXml ? : ; 51 | } 52 | -------------------------------------------------------------------------------- /src/hoc/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as UnoStyled } from './uno-styled'; 2 | export { Icon } from './icon'; 3 | export * from './hub'; 4 | -------------------------------------------------------------------------------- /src/hoc/uno-styled.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { uno } from './hub'; 3 | 4 | export default function UnoStyled(props: any) { 5 | const { component: Component, ...rest } = props; 6 | 7 | const style = uno(rest.className); 8 | 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { UnoStyled, uno, hub as default } from './hoc'; 2 | export { Icon } from './hoc'; 3 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/colors.ts: -------------------------------------------------------------------------------- 1 | // based on the colors from Tailwind CSS 2 | // https://github.com/tailwindlabs/tailwindcss/blob/master/src/public/colors.js 3 | // 4 | // and Windi CSS 5 | // https://github.com/windicss/windicss/blob/main/src/config/colors.ts 6 | 7 | import type { Theme } from './types' 8 | 9 | export const colors = { 10 | inherit: 'inherit', 11 | current: 'currentColor', 12 | transparent: 'transparent', 13 | black: '#000', 14 | white: '#fff', 15 | rose: { 16 | 50: '#fff1f2', 17 | 100: '#ffe4e6', 18 | 200: '#fecdd3', 19 | 300: '#fda4af', 20 | 400: '#fb7185', 21 | 500: '#f43f5e', 22 | 600: '#e11d48', 23 | 700: '#be123c', 24 | 800: '#9f1239', 25 | 900: '#881337', 26 | }, 27 | pink: { 28 | 50: '#fdf2f8', 29 | 100: '#fce7f3', 30 | 200: '#fbcfe8', 31 | 300: '#f9a8d4', 32 | 400: '#f472b6', 33 | 500: '#ec4899', 34 | 600: '#db2777', 35 | 700: '#be185d', 36 | 800: '#9d174d', 37 | 900: '#831843', 38 | }, 39 | fuchsia: { 40 | 50: '#fdf4ff', 41 | 100: '#fae8ff', 42 | 200: '#f5d0fe', 43 | 300: '#f0abfc', 44 | 400: '#e879f9', 45 | 500: '#d946ef', 46 | 600: '#c026d3', 47 | 700: '#a21caf', 48 | 800: '#86198f', 49 | 900: '#701a75', 50 | }, 51 | purple: { 52 | 50: '#faf5ff', 53 | 100: '#f3e8ff', 54 | 200: '#e9d5ff', 55 | 300: '#d8b4fe', 56 | 400: '#c084fc', 57 | 500: '#a855f7', 58 | 600: '#9333ea', 59 | 700: '#7e22ce', 60 | 800: '#6b21a8', 61 | 900: '#581c87', 62 | }, 63 | violet: { 64 | 50: '#f5f3ff', 65 | 100: '#ede9fe', 66 | 200: '#ddd6fe', 67 | 300: '#c4b5fd', 68 | 400: '#a78bfa', 69 | 500: '#8b5cf6', 70 | 600: '#7c3aed', 71 | 700: '#6d28d9', 72 | 800: '#5b21b6', 73 | 900: '#4c1d95', 74 | }, 75 | indigo: { 76 | 50: '#eef2ff', 77 | 100: '#e0e7ff', 78 | 200: '#c7d2fe', 79 | 300: '#a5b4fc', 80 | 400: '#818cf8', 81 | 500: '#6366f1', 82 | 600: '#4f46e5', 83 | 700: '#4338ca', 84 | 800: '#3730a3', 85 | 900: '#312e81', 86 | }, 87 | blue: { 88 | 50: '#eff6ff', 89 | 100: '#dbeafe', 90 | 200: '#bfdbfe', 91 | 300: '#93c5fd', 92 | 400: '#60a5fa', 93 | 500: '#3b82f6', 94 | 600: '#2563eb', 95 | 700: '#1d4ed8', 96 | 800: '#1e40af', 97 | 900: '#1e3a8a', 98 | }, 99 | sky: { 100 | 50: '#f0f9ff', 101 | 100: '#e0f2fe', 102 | 200: '#bae6fd', 103 | 300: '#7dd3fc', 104 | 400: '#38bdf8', 105 | 500: '#0ea5e9', 106 | 600: '#0284c7', 107 | 700: '#0369a1', 108 | 800: '#075985', 109 | 900: '#0c4a6e', 110 | }, 111 | cyan: { 112 | 50: '#ecfeff', 113 | 100: '#cffafe', 114 | 200: '#a5f3fc', 115 | 300: '#67e8f9', 116 | 400: '#22d3ee', 117 | 500: '#06b6d4', 118 | 600: '#0891b2', 119 | 700: '#0e7490', 120 | 800: '#155e75', 121 | 900: '#164e63', 122 | }, 123 | teal: { 124 | 50: '#f0fdfa', 125 | 100: '#ccfbf1', 126 | 200: '#99f6e4', 127 | 300: '#5eead4', 128 | 400: '#2dd4bf', 129 | 500: '#14b8a6', 130 | 600: '#0d9488', 131 | 700: '#0f766e', 132 | 800: '#115e59', 133 | 900: '#134e4a', 134 | }, 135 | emerald: { 136 | 50: '#ecfdf5', 137 | 100: '#d1fae5', 138 | 200: '#a7f3d0', 139 | 300: '#6ee7b7', 140 | 400: '#34d399', 141 | 500: '#10b981', 142 | 600: '#059669', 143 | 700: '#047857', 144 | 800: '#065f46', 145 | 900: '#064e3b', 146 | }, 147 | green: { 148 | 50: '#f0fdf4', 149 | 100: '#dcfce7', 150 | 200: '#bbf7d0', 151 | 300: '#86efac', 152 | 400: '#4ade80', 153 | 500: '#22c55e', 154 | 600: '#16a34a', 155 | 700: '#15803d', 156 | 800: '#166534', 157 | 900: '#14532d', 158 | }, 159 | lime: { 160 | 50: '#f7fee7', 161 | 100: '#ecfccb', 162 | 200: '#d9f99d', 163 | 300: '#bef264', 164 | 400: '#a3e635', 165 | 500: '#84cc16', 166 | 600: '#65a30d', 167 | 700: '#4d7c0f', 168 | 800: '#3f6212', 169 | 900: '#365314', 170 | }, 171 | yellow: { 172 | 50: '#fefce8', 173 | 100: '#fef9c3', 174 | 200: '#fef08a', 175 | 300: '#fde047', 176 | 400: '#facc15', 177 | 500: '#eab308', 178 | 600: '#ca8a04', 179 | 700: '#a16207', 180 | 800: '#854d0e', 181 | 900: '#713f12', 182 | }, 183 | amber: { 184 | 50: '#fffbeb', 185 | 100: '#fef3c7', 186 | 200: '#fde68a', 187 | 300: '#fcd34d', 188 | 400: '#fbbf24', 189 | 500: '#f59e0b', 190 | 600: '#d97706', 191 | 700: '#b45309', 192 | 800: '#92400e', 193 | 900: '#78350f', 194 | }, 195 | orange: { 196 | 50: '#fff7ed', 197 | 100: '#ffedd5', 198 | 200: '#fed7aa', 199 | 300: '#fdba74', 200 | 400: '#fb923c', 201 | 500: '#f97316', 202 | 600: '#ea580c', 203 | 700: '#c2410c', 204 | 800: '#9a3412', 205 | 900: '#7c2d12', 206 | }, 207 | red: { 208 | 50: '#fef2f2', 209 | 100: '#fee2e2', 210 | 200: '#fecaca', 211 | 300: '#fca5a5', 212 | 400: '#f87171', 213 | 500: '#ef4444', 214 | 600: '#dc2626', 215 | 700: '#b91c1c', 216 | 800: '#991b1b', 217 | 900: '#7f1d1d', 218 | }, 219 | gray: { 220 | 50: '#f9fafb', 221 | 100: '#f3f4f6', 222 | 200: '#e5e7eb', 223 | 300: '#d1d5db', 224 | 400: '#9ca3af', 225 | 500: '#6b7280', 226 | 600: '#4b5563', 227 | 700: '#374151', 228 | 800: '#1f2937', 229 | 900: '#111827', 230 | }, 231 | 232 | slate: { 233 | 50: '#f8fafc', 234 | 100: '#f1f5f9', 235 | 200: '#e2e8f0', 236 | 300: '#cbd5e1', 237 | 400: '#94a3b8', 238 | 500: '#64748b', 239 | 600: '#475569', 240 | 700: '#334155', 241 | 800: '#1e293b', 242 | 900: '#0f172a', 243 | }, 244 | zinc: { 245 | 50: '#fafafa', 246 | 100: '#f4f4f5', 247 | 200: '#e4e4e7', 248 | 300: '#d4d4d8', 249 | 400: '#a1a1aa', 250 | 500: '#71717a', 251 | 600: '#52525b', 252 | 700: '#3f3f46', 253 | 800: '#27272a', 254 | 900: '#18181b', 255 | }, 256 | neutral: { 257 | 50: '#fafafa', 258 | 100: '#f5f5f5', 259 | 200: '#e5e5e5', 260 | 300: '#d4d4d4', 261 | 400: '#a3a3a3', 262 | 500: '#737373', 263 | 600: '#525252', 264 | 700: '#404040', 265 | 800: '#262626', 266 | 900: '#171717', 267 | }, 268 | stone: { 269 | 50: '#fafaf9', 270 | 100: '#f5f5f4', 271 | 200: '#e7e5e4', 272 | 300: '#d6d3d1', 273 | 400: '#a8a29e', 274 | 500: '#78716c', 275 | 600: '#57534e', 276 | 700: '#44403c', 277 | 800: '#292524', 278 | 900: '#1c1917', 279 | }, 280 | light: { 281 | 50: '#fdfdfd', 282 | 100: '#fcfcfc', 283 | 200: '#fafafa', 284 | 300: '#f8f9fa', 285 | 400: '#f6f6f6', 286 | 500: '#f2f2f2', 287 | 600: '#f1f3f5', 288 | 700: '#e9ecef', 289 | 800: '#dee2e6', 290 | 900: '#dde1e3', 291 | }, 292 | dark: { 293 | 50: '#4a4a4a', 294 | 100: '#3c3c3c', 295 | 200: '#323232', 296 | 300: '#2d2d2d', 297 | 400: '#222222', 298 | 500: '#1f1f1f', 299 | 600: '#1c1c1e', 300 | 700: '#1b1b1b', 301 | 800: '#181818', 302 | 900: '#0f0f0f', 303 | }, 304 | get lightblue() { 305 | return this.sky 306 | }, 307 | get lightBlue() { 308 | return this.sky 309 | }, 310 | get warmgray() { 311 | return this.stone 312 | }, 313 | get warmGray() { 314 | return this.stone 315 | }, 316 | get truegray() { 317 | return this.neutral 318 | }, 319 | get trueGray() { 320 | return this.neutral 321 | }, 322 | get coolgray() { 323 | return this.gray 324 | }, 325 | get coolGray() { 326 | return this.gray 327 | }, 328 | get bluegray() { 329 | return this.slate 330 | }, 331 | get blueGray() { 332 | return this.slate 333 | }, 334 | } satisfies Theme['colors'] 335 | 336 | // assign default color, and color shortcuts 337 | Object.values(colors as Required['colors']).forEach((color) => { 338 | if (typeof color !== 'string') { 339 | color.DEFAULT = color.DEFAULT || color[400] 340 | Object.keys(color).forEach((key) => { 341 | const short = +key / 100 342 | if (short === Math.round(short)) 343 | color[short] = color[key] 344 | }) 345 | } 346 | }) 347 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/default.ts: -------------------------------------------------------------------------------- 1 | import { colors } from './colors' 2 | import { fontFamily, fontSize, letterSpacing, lineHeight, textIndent, textShadow, textStrokeWidth, wordSpacing } from './font' 3 | import { borderRadius, boxShadow, breakpoints, duration, easing, lineWidth, ringWidth, spacing, verticalBreakpoints } from './misc' 4 | import { blur, dropShadow } from './filters' 5 | import { containers, height, maxHeight, maxWidth, width } from './size' 6 | import type { Theme } from './types' 7 | import { preflightBase } from './preflight' 8 | 9 | export const theme = { 10 | width, 11 | height, 12 | maxWidth, 13 | maxHeight, 14 | minWidth: maxWidth, 15 | minHeight: maxHeight, 16 | inlineSize: width, 17 | blockSize: height, 18 | maxInlineSize: maxWidth, 19 | maxBlockSize: maxHeight, 20 | minInlineSize: maxWidth, 21 | minBlockSize: maxHeight, 22 | colors, 23 | fontFamily, 24 | fontSize, 25 | breakpoints, 26 | verticalBreakpoints, 27 | borderRadius, 28 | lineHeight, 29 | letterSpacing, 30 | wordSpacing, 31 | boxShadow, 32 | textIndent, 33 | textShadow, 34 | textStrokeWidth, 35 | blur, 36 | dropShadow, 37 | easing, 38 | lineWidth, 39 | spacing, 40 | duration, 41 | ringWidth, 42 | preflightBase, 43 | containers, 44 | } satisfies Theme 45 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/filters.ts: -------------------------------------------------------------------------------- 1 | export const blur = { 2 | 'DEFAULT': '8px', 3 | '0': '0', 4 | 'sm': '4px', 5 | 'md': '12px', 6 | 'lg': '16px', 7 | 'xl': '24px', 8 | '2xl': '40px', 9 | '3xl': '64px', 10 | } 11 | 12 | export const dropShadow = { 13 | 'DEFAULT': ['0 1px 2px rgba(0,0,0,0.1)', '0 1px 1px rgba(0,0,0,0.06)'], 14 | 'sm': '0 1px 1px rgba(0,0,0,0.05)', 15 | 'md': ['0 4px 3px rgba(0,0,0,0.07)', '0 2px 2px rgba(0,0,0,0.06)'], 16 | 'lg': ['0 10px 8px rgba(0,0,0,0.04)', '0 4px 3px rgba(0,0,0,0.1)'], 17 | 'xl': ['0 20px 13px rgba(0,0,0,0.03)', '0 8px 5px rgba(0,0,0,0.08)'], 18 | '2xl': '0 25px 25px rgba(0,0,0,0.15)', 19 | 'none': '0 0 rgba(0,0,0,0)', 20 | } 21 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/font.ts: -------------------------------------------------------------------------------- 1 | import type { Theme } from './types' 2 | 3 | export const fontFamily = { 4 | sans: [ 5 | 'ui-sans-serif', 6 | 'system-ui', 7 | '-apple-system', 8 | 'BlinkMacSystemFont', 9 | '"Segoe UI"', 10 | 'Roboto', 11 | '"Helvetica Neue"', 12 | 'Arial', 13 | '"Noto Sans"', 14 | 'sans-serif', 15 | '"Apple Color Emoji"', 16 | '"Segoe UI Emoji"', 17 | '"Segoe UI Symbol"', 18 | '"Noto Color Emoji"', 19 | ].join(','), 20 | serif: [ 21 | 'ui-serif', 22 | 'Georgia', 23 | 'Cambria', 24 | '"Times New Roman"', 25 | 'Times', 26 | 'serif', 27 | ].join(','), 28 | mono: [ 29 | 'ui-monospace', 30 | 'SFMono-Regular', 31 | 'Menlo', 32 | 'Monaco', 33 | 'Consolas', 34 | '"Liberation Mono"', 35 | '"Courier New"', 36 | 'monospace', 37 | ].join(','), 38 | } satisfies Theme['fontFamily'] 39 | 40 | export const fontSize: Theme['fontSize'] = { 41 | 'xs': ['0.75rem', '1rem'], 42 | 'sm': ['0.875rem', '1.25rem'], 43 | 'base': ['1rem', '1.5rem'], 44 | 'lg': ['1.125rem', '1.75rem'], 45 | 'xl': ['1.25rem', '1.75rem'], 46 | '2xl': ['1.5rem', '2rem'], 47 | '3xl': ['1.875rem', '2.25rem'], 48 | '4xl': ['2.25rem', '2.5rem'], 49 | '5xl': ['3rem', '1'], 50 | '6xl': ['3.75rem', '1'], 51 | '7xl': ['4.5rem', '1'], 52 | '8xl': ['6rem', '1'], 53 | '9xl': ['8rem', '1'], 54 | }satisfies Theme['fontSize'] 55 | 56 | export const textIndent: Theme['textIndent'] = { 57 | 'DEFAULT': '1.5rem', 58 | 'xs': '0.5rem', 59 | 'sm': '1rem', 60 | 'md': '1.5rem', 61 | 'lg': '2rem', 62 | 'xl': '2.5rem', 63 | '2xl': '3rem', 64 | '3xl': '4rem', 65 | } satisfies Theme['textIndent'] 66 | 67 | export const textStrokeWidth: Theme['textStrokeWidth'] = { 68 | DEFAULT: '1.5rem', 69 | none: '0', 70 | sm: 'thin', 71 | md: 'medium', 72 | lg: 'thick', 73 | } satisfies Theme['textStrokeWidth'] 74 | 75 | export const textShadow = { 76 | DEFAULT: ['0 0 1px rgba(0,0,0,0.2)', '0 0 1px rgba(1,0,5,0.1)'], 77 | none: '0 0 rgba(0,0,0,0)', 78 | sm: '1px 1px 3px rgba(36,37,47,0.25)', 79 | md: ['0 1px 2px rgba(30,29,39,0.19)', '1px 2px 4px rgba(54,64,147,0.18)'], 80 | lg: ['3px 3px 6px rgba(0,0,0,0.26)', '0 0 5px rgba(15,3,86,0.22)'], 81 | xl: ['1px 1px 3px rgba(0,0,0,0.29)', '2px 4px 7px rgba(73,64,125,0.35)'], 82 | } satisfies Theme['textShadow'] 83 | 84 | export const lineHeight = { 85 | none: '1', 86 | tight: '1.25', 87 | snug: '1.375', 88 | normal: '1.5', 89 | relaxed: '1.625', 90 | loose: '2', 91 | } satisfies Theme['lineHeight'] 92 | 93 | export const letterSpacing = { 94 | tighter: '-0.05em', 95 | tight: '-0.025em', 96 | normal: '0em', 97 | wide: '0.025em', 98 | wider: '0.05em', 99 | widest: '0.1em', 100 | } satisfies Theme['letterSpacing'] 101 | 102 | export const wordSpacing = letterSpacing satisfies Theme['letterSpacing'] 103 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/index.ts: -------------------------------------------------------------------------------- 1 | /* @export-submodules */ 2 | export * from './colors' 3 | export * from './default' 4 | export * from './filters' 5 | export * from './font' 6 | export * from './misc' 7 | export * from './preflight' 8 | export * from './size' 9 | export * from './types' 10 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/misc.ts: -------------------------------------------------------------------------------- 1 | import type { Theme } from './types' 2 | 3 | // keep in ASC order: container.ts and breakpoints.ts need that order 4 | export const breakpoints = { 5 | 'sm': '640px', 6 | 'md': '768px', 7 | 'lg': '1024px', 8 | 'xl': '1280px', 9 | '2xl': '1536px', 10 | } satisfies Theme['breakpoints'] 11 | 12 | export const verticalBreakpoints = { ...breakpoints } satisfies Theme['breakpoints'] 13 | 14 | export const lineWidth = { 15 | DEFAULT: '1px', 16 | none: '0', 17 | } satisfies Theme['lineWidth'] 18 | 19 | export const spacing = { 20 | 'DEFAULT': '1rem', 21 | 'none': '0', 22 | 'xs': '0.75rem', 23 | 'sm': '0.875rem', 24 | 'lg': '1.125rem', 25 | 'xl': '1.25rem', 26 | '2xl': '1.5rem', 27 | '3xl': '1.875rem', 28 | '4xl': '2.25rem', 29 | '5xl': '3rem', 30 | '6xl': '3.75rem', 31 | '7xl': '4.5rem', 32 | '8xl': '6rem', 33 | '9xl': '8rem', 34 | } satisfies Theme['spacing'] 35 | 36 | export const duration = { 37 | DEFAULT: '150ms', 38 | none: '0s', 39 | 75: '75ms', 40 | 100: '100ms', 41 | 150: '150ms', 42 | 200: '200ms', 43 | 300: '300ms', 44 | 500: '500ms', 45 | 700: '700ms', 46 | 1000: '1000ms', 47 | } satisfies Theme['duration'] 48 | 49 | export const borderRadius = { 50 | 'DEFAULT': '0.25rem', 51 | 'none': '0', 52 | 'sm': '0.125rem', 53 | 'md': '0.375rem', 54 | 'lg': '0.5rem', 55 | 'xl': '0.75rem', 56 | '2xl': '1rem', 57 | '3xl': '1.5rem', 58 | 'full': '9999px', 59 | } satisfies Theme['borderRadius'] 60 | 61 | export const boxShadow = { 62 | 'DEFAULT': ['var(--un-shadow-inset) 0 1px 3px 0 rgba(0,0,0,0.1)', 'var(--un-shadow-inset) 0 1px 2px -1px rgba(0,0,0,0.1)'], 63 | 'none': '0 0 rgba(0,0,0,0)', 64 | 'sm': 'var(--un-shadow-inset) 0 1px 2px 0 rgba(0,0,0,0.05)', 65 | 'md': ['var(--un-shadow-inset) 0 4px 6px -1px rgba(0,0,0,0.1)', 'var(--un-shadow-inset) 0 2px 4px -2px rgba(0,0,0,0.1)'], 66 | 'lg': ['var(--un-shadow-inset) 0 10px 15px -3px rgba(0,0,0,0.1)', 'var(--un-shadow-inset) 0 4px 6px -4px rgba(0,0,0,0.1)'], 67 | 'xl': ['var(--un-shadow-inset) 0 20px 25px -5px rgba(0,0,0,0.1)', 'var(--un-shadow-inset) 0 8px 10px -6px rgba(0,0,0,0.1)'], 68 | '2xl': 'var(--un-shadow-inset) 0 25px 50px -12px rgba(0,0,0,0.25)', 69 | 'inner': 'inset 0 2px 4px 0 rgba(0,0,0,0.05)', 70 | } satisfies Theme['boxShadow'] 71 | 72 | export const easing = { 73 | 'DEFAULT': 'cubic-bezier(0.4, 0, 0.2, 1)', 74 | 'linear': 'linear', 75 | 'in': 'cubic-bezier(0.4, 0, 1, 1)', 76 | 'out': 'cubic-bezier(0, 0, 0.2, 1)', 77 | 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', 78 | } satisfies Theme['easing'] 79 | 80 | export const ringWidth = { 81 | DEFAULT: '1px', 82 | none: '0', 83 | } satisfies Theme['ringWidth'] 84 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/preflight.ts: -------------------------------------------------------------------------------- 1 | import type { Theme } from './types'; 2 | 3 | export const preflightBase = {} satisfies Theme['preflightBase']; 4 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/size.ts: -------------------------------------------------------------------------------- 1 | import type { Theme } from './types' 2 | 3 | export const baseSize = { 4 | 'xs': '20rem', 5 | 'sm': '24rem', 6 | 'md': '28rem', 7 | 'lg': '32rem', 8 | 'xl': '36rem', 9 | '2xl': '42rem', 10 | '3xl': '48rem', 11 | '4xl': '56rem', 12 | '5xl': '64rem', 13 | '6xl': '72rem', 14 | '7xl': '80rem', 15 | 'prose': '65ch', 16 | } 17 | 18 | export const width = { 19 | auto: 'auto', 20 | ...baseSize, 21 | screen: '100vw', 22 | } satisfies Theme['width'] 23 | 24 | export const maxWidth = { 25 | none: 'none', 26 | ...baseSize, 27 | screen: '100vw', 28 | } satisfies Theme['maxWidth'] 29 | 30 | export const height = { 31 | auto: 'auto', 32 | ...baseSize, 33 | screen: '100vh', 34 | } satisfies Theme['height'] 35 | 36 | export const maxHeight = { 37 | none: 'none', 38 | ...baseSize, 39 | screen: '100vh', 40 | } satisfies Theme['maxHeight'] 41 | 42 | export const containers = Object.fromEntries(Object.entries(baseSize).map(([k, v]) => [k, `(min-width: ${v})`])) satisfies Theme['containers'] 43 | -------------------------------------------------------------------------------- /src/preset-react-native/_theme/types.ts: -------------------------------------------------------------------------------- 1 | import type { Arrayable } from 'unocss' 2 | 3 | export interface ThemeAnimation { 4 | keyframes?: Record 5 | durations?: Record 6 | timingFns?: Record 7 | properties?: Record 8 | counts?: Record 9 | } 10 | 11 | export interface Colors { 12 | [key: string]: Colors | string 13 | } 14 | 15 | export interface Theme { 16 | width?: Record 17 | height?: Record 18 | maxWidth?: Record 19 | maxHeight?: Record 20 | minWidth?: Record 21 | minHeight?: Record 22 | inlineSize?: Record 23 | blockSize?: Record 24 | maxInlineSize?: Record 25 | maxBlockSize?: Record 26 | minInlineSize?: Record 27 | minBlockSize?: Record 28 | borderRadius?: Record 29 | breakpoints?: Record 30 | verticalBreakpoints?: Record 31 | colors?: Colors 32 | fontFamily?: Record 33 | fontSize?: Record 34 | lineHeight?: Record 35 | letterSpacing?: Record 36 | wordSpacing?: Record 37 | boxShadow?: Record 38 | textIndent?: Record 39 | textShadow?: Record 40 | textStrokeWidth?: Record 41 | ringWidth?: Record 42 | lineWidth?: Record 43 | spacing?: Record 44 | duration?: Record 45 | aria?: Record 46 | data?: Record 47 | // filters 48 | blur?: Record 49 | dropShadow?: Record 50 | // transitions 51 | easing?: Record 52 | // media queries 53 | media?: Record 54 | // supports queries 55 | supports?: Record 56 | // container queries 57 | containers?: Record 58 | // animation 59 | animation?: ThemeAnimation 60 | // grids 61 | gridAutoColumn?: Record 62 | gridAutoRow?: Record 63 | gridColumn?: Record 64 | gridRow?: Record 65 | gridTemplateColumn?: Record 66 | gridTemplateRow?: Record 67 | // container 68 | container?: { 69 | center?: boolean 70 | padding?: string | Record 71 | maxWidth?: Record 72 | } 73 | // vars 74 | /** Used to generate CSS variables placeholder in preflight */ 75 | preflightRoot?: Arrayable 76 | preflightBase?: Record 77 | } 78 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/colors.ts: -------------------------------------------------------------------------------- 1 | import type { CSSColorValue, RGBAColorValue } from '@unocss/core' 2 | import { escapeRegExp } from '@unocss/core' 3 | import { getComponents } from './utilities' 4 | 5 | /* eslint-disable no-case-declarations */ 6 | 7 | const cssColorFunctions = ['hsl', 'hsla', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'rgb', 'rgba'] 8 | const alphaPlaceholders = ['%alpha', ''] 9 | const alphaPlaceholdersRE = new RegExp(alphaPlaceholders.map(v => escapeRegExp(v)).join('|')) 10 | 11 | export function hex2rgba(hex = ''): RGBAColorValue | undefined { 12 | const color = parseHexColor(hex) 13 | if (color != null) { 14 | const { components, alpha } = color 15 | if (alpha == null) 16 | return components as [number, number, number] 17 | return [...components, alpha] as [number, number, number, number] 18 | } 19 | } 20 | 21 | export function parseCssColor(str = ''): CSSColorValue | undefined { 22 | const color = parseColor(str) 23 | if (color == null || color === false) 24 | return 25 | 26 | const { type: casedType, components, alpha } = color 27 | const type = casedType.toLowerCase() 28 | 29 | if (components.length === 0) 30 | return 31 | 32 | if (['rgba', 'hsla'].includes(type) && alpha == null) 33 | return 34 | 35 | if (cssColorFunctions.includes(type) && ![1, 3].includes(components.length)) 36 | return 37 | 38 | return { 39 | type, 40 | components: components.map(c => typeof c === 'string' ? c.trim() : c), 41 | alpha: typeof alpha === 'string' ? alpha.trim() : alpha, 42 | } 43 | } 44 | 45 | export function colorOpacityToString(color: CSSColorValue) { 46 | const alpha = color.alpha ?? 1 47 | return (typeof alpha === 'string' && alphaPlaceholders.includes(alpha)) 48 | ? 1 49 | : alpha 50 | } 51 | 52 | export function colorToString(color: CSSColorValue | string, alphaOverride?: string | number) { 53 | if (typeof color === 'string') 54 | return color.replace(alphaPlaceholdersRE, `${alphaOverride ?? 1}`) 55 | 56 | const { components } = color 57 | let { alpha, type } = color 58 | alpha = alphaOverride ?? alpha 59 | type = type.toLowerCase() 60 | 61 | // Comma separated functions 62 | if (['hsla', 'hsl', 'rgba', 'rgb'].includes(type)) 63 | return `${type.replace('a', '')}a(${components.join(',')}${alpha == null ? '' : `,${alpha}`})` 64 | 65 | alpha = alpha == null ? '' : ` / ${alpha}` 66 | if (cssColorFunctions.includes(type)) 67 | return `${type}(${components.join(' ')}${alpha})` 68 | return `color(${type} ${components.join(' ')}${alpha})` 69 | } 70 | 71 | function parseColor(str: string) { 72 | if (!str) 73 | return 74 | 75 | let color: CSSColorValue | false | undefined = parseHexColor(str) 76 | if (color != null) 77 | return color 78 | 79 | color = cssColorKeyword(str) 80 | if (color != null) 81 | return color 82 | 83 | color = parseCssCommaColorFunction(str) 84 | if (color != null) 85 | return color 86 | 87 | color = parseCssSpaceColorFunction(str) 88 | if (color != null) 89 | return color 90 | 91 | color = parseCssColorFunction(str) 92 | if (color != null) 93 | return color 94 | } 95 | 96 | function parseHexColor(str: string): CSSColorValue | undefined { 97 | const [, body] = str.match(/^#([\da-f]+)$/i) || [] 98 | if (!body) 99 | return 100 | 101 | switch (body.length) { 102 | case 3: 103 | case 4: 104 | const digits = Array.from(body, s => Number.parseInt(s, 16)).map(n => (n << 4) | n) 105 | return { 106 | type: 'rgb', 107 | components: digits.slice(0, 3), 108 | alpha: body.length === 3 109 | ? undefined 110 | : Math.round(digits[3] / 255 * 100) / 100, 111 | } 112 | 113 | case 6: 114 | case 8: 115 | const value = Number.parseInt(body, 16) 116 | return { 117 | type: 'rgb', 118 | components: body.length === 6 119 | ? [(value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF] 120 | : [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF], 121 | alpha: body.length === 6 122 | ? undefined 123 | : Math.round((value & 0xFF) / 255 * 100) / 100, 124 | } 125 | } 126 | } 127 | 128 | function cssColorKeyword(str: string): CSSColorValue | undefined { 129 | const color = { 130 | rebeccapurple: [102, 51, 153, 1], 131 | }[str] 132 | 133 | if (color != null) { 134 | return { 135 | type: 'rgb', 136 | components: color.slice(0, 3), 137 | alpha: color[3], 138 | } 139 | } 140 | } 141 | 142 | function parseCssCommaColorFunction(color: string): CSSColorValue | false | undefined { 143 | const match = color.match(/^(rgb|rgba|hsl|hsla)\((.+)\)$/i) 144 | if (!match) 145 | return 146 | 147 | const [, type, componentString] = match 148 | // With min 3 (rgb) and max 4 (rgba), try to get 5 components 149 | const components = getComponents(componentString, ',', 5) 150 | if (components) { 151 | if ([3, 4].includes(components.length)) { 152 | return { 153 | type, 154 | components: components.slice(0, 3), 155 | alpha: components[3], 156 | } 157 | } 158 | else if (components.length !== 1) { 159 | return false 160 | } 161 | } 162 | } 163 | 164 | const cssColorFunctionsRe = new RegExp(`^(${cssColorFunctions.join('|')})\\((.+)\\)$`, 'i') 165 | function parseCssSpaceColorFunction(color: string): CSSColorValue | undefined { 166 | const match = color.match(cssColorFunctionsRe) 167 | if (!match) 168 | return 169 | 170 | const [, fn, componentString] = match 171 | const parsed = parseCssSpaceColorValues(`${fn} ${componentString}`) 172 | if (parsed) { 173 | const { alpha, components: [type, ...components] } = parsed 174 | return { 175 | type, 176 | components, 177 | alpha, 178 | } 179 | } 180 | } 181 | 182 | function parseCssColorFunction(color: string): CSSColorValue | undefined { 183 | const match = color.match(/^color\((.+)\)$/) 184 | if (!match) 185 | return 186 | 187 | const parsed = parseCssSpaceColorValues(match[1]) 188 | if (parsed) { 189 | const { alpha, components: [type, ...components] } = parsed 190 | return { 191 | type, 192 | components, 193 | alpha, 194 | } 195 | } 196 | } 197 | 198 | function parseCssSpaceColorValues(componentString: string) { 199 | const components = getComponents(componentString, ' ') 200 | if (!components) 201 | return 202 | 203 | let totalComponents = components.length 204 | 205 | // (fn 1 2 3 / 4) 206 | if (components[totalComponents - 2] === '/') { 207 | return { 208 | components: components.slice(0, totalComponents - 2), 209 | alpha: components[totalComponents - 1], 210 | } 211 | } 212 | 213 | // (fn 1 2 3/ 4) or (fn 1 2 3 /4) 214 | if (components[totalComponents - 2] != null && (components[totalComponents - 2].endsWith('/') || components[totalComponents - 1].startsWith('/'))) { 215 | const removed = components.splice(totalComponents - 2) 216 | components.push(removed.join(' ')) 217 | --totalComponents 218 | } 219 | 220 | // maybe (fn 1 2 3/4) 221 | const withAlpha = getComponents(components[totalComponents - 1], '/', 2) 222 | if (!withAlpha) 223 | return 224 | 225 | // without alpha 226 | if (withAlpha.length === 1 || withAlpha[withAlpha.length - 1] === '') 227 | return { components } 228 | 229 | const alpha = withAlpha.pop() 230 | components[totalComponents - 1] = withAlpha.join('/') 231 | return { 232 | components, 233 | alpha, 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/handlers/handlers.ts: -------------------------------------------------------------------------------- 1 | import { escapeSelector } from '@unocss/core' 2 | import { globalKeywords } from '../mappings' 3 | import { numberRE, numberWithUnitRE, unitOnlyRE } from './regex' 4 | 5 | // Not all, but covers most high frequency attributes 6 | const cssProps = [ 7 | // basic props 8 | 'color', 'border-color', 'background-color', 'flex-grow', 'flex', 'flex-shrink', 9 | 'caret-color', 'font', 'gap', 'opacity', 'visibility', 'z-index', 'font-weight', 10 | 'zoom', 'text-shadow', 'transform', 'box-shadow', 11 | 12 | // positions 13 | 'background-position', 'left', 'right', 'top', 'bottom', 'object-position', 14 | 15 | // sizes 16 | 'max-height', 'min-height', 'max-width', 'min-width', 'height', 'width', 17 | 'border-width', 'margin', 'padding', 'outline-width', 'outline-offset', 18 | 'font-size', 'line-height', 'text-indent', 'vertical-align', 19 | 'border-spacing', 'letter-spacing', 'word-spacing', 20 | 21 | // enhances 22 | 'stroke', 'filter', 'backdrop-filter', 'fill', 'mask', 'mask-size', 'mask-border', 'clip-path', 'clip', 23 | 'border-radius', 24 | ] 25 | 26 | function round(n: number) { 27 | return n.toFixed(10).replace(/\.0+$/, '').replace(/(\.\d+?)0+$/, '$1') 28 | } 29 | 30 | export function numberWithUnit(str: string) { 31 | const match = str.match(numberWithUnitRE) 32 | if (!match) 33 | return 34 | const [, n, unit] = match 35 | const num = parseFloat(n) 36 | if (unit && !Number.isNaN(num)) 37 | return `${round(num)}${unit}` 38 | } 39 | 40 | export function auto(str: string) { 41 | if (str === 'auto' || str === 'a') 42 | return 'auto' 43 | } 44 | 45 | export function rem(str: string) { 46 | if (str.match(unitOnlyRE)) 47 | return `1${str}` 48 | const match = str.match(numberWithUnitRE) 49 | if (!match) 50 | return 51 | const [, n, unit] = match 52 | const num = parseFloat(n) 53 | if (!Number.isNaN(num)) { 54 | if (num === 0) 55 | return '0' 56 | return unit ? `${round(num)}${unit}` : `${round(num / 4)}rem` 57 | } 58 | } 59 | 60 | export function px(str: string) { 61 | if (str.match(unitOnlyRE)) 62 | return `1${str}` 63 | const match = str.match(numberWithUnitRE) 64 | if (!match) 65 | return 66 | const [, n, unit] = match 67 | const num = parseFloat(n) 68 | if (!Number.isNaN(num)) { 69 | if (num === 0) 70 | return '0' 71 | return unit ? `${round(num)}${unit}` : `${round(num)}px` 72 | } 73 | } 74 | 75 | export function number(str: string) { 76 | if (!numberRE.test(str)) 77 | return 78 | const num = parseFloat(str) 79 | if (!Number.isNaN(num)) 80 | return round(num) 81 | } 82 | 83 | export function percent(str: string) { 84 | if (str.endsWith('%')) 85 | str = str.slice(0, -1) 86 | const num = parseFloat(str) 87 | if (!Number.isNaN(num)) 88 | return `${round(num / 100)}` 89 | } 90 | 91 | export function fraction(str: string) { 92 | if (str === 'full') 93 | return '100%' 94 | const [left, right] = str.split('/') 95 | const num = parseFloat(left) / parseFloat(right) 96 | if (!Number.isNaN(num)) { 97 | if (num === 0) 98 | return '0' 99 | return `${round(num * 100)}%` 100 | } 101 | } 102 | 103 | const bracketTypeRe = /^\[(color|length|position|quoted|string):/i 104 | function bracketWithType(str: string, requiredType?: string) { 105 | if (str && str.startsWith('[') && str.endsWith(']')) { 106 | let base: string | undefined 107 | let hintedType: string | undefined 108 | 109 | const match = str.match(bracketTypeRe) 110 | if (!match) { 111 | base = str.slice(1, -1) 112 | } 113 | else { 114 | if (!requiredType) 115 | hintedType = match[1] 116 | base = str.slice(match[0].length, -1) 117 | } 118 | 119 | if (!base) 120 | return 121 | 122 | // test/preset-attributify.test.ts > fixture5 123 | if (base === '=""') 124 | return 125 | 126 | let curly = 0 127 | for (const i of base) { 128 | if (i === '[') { 129 | curly += 1 130 | } 131 | else if (i === ']') { 132 | curly -= 1 133 | if (curly < 0) 134 | return 135 | } 136 | } 137 | if (curly) 138 | return 139 | 140 | switch (hintedType) { 141 | case 'string': return base 142 | .replace(/(^|[^\\])_/g, '$1 ') 143 | .replace(/\\_/g, '_') 144 | 145 | case 'quoted': return base 146 | .replace(/(^|[^\\])_/g, '$1 ') 147 | .replace(/\\_/g, '_') 148 | .replace(/(["\\])/g, '\\$1') 149 | .replace(/^(.+)$/, '"$1"') 150 | } 151 | 152 | return base 153 | .replace(/(url\(.*?\))/g, v => v.replace(/_/g, '\\_')) 154 | .replace(/(^|[^\\])_/g, '$1 ') 155 | .replace(/\\_/g, '_') 156 | .replace(/(?:calc|clamp|max|min)\((.*)/g, (match) => { 157 | const vars: string[] = [] 158 | return match 159 | .replace(/var\((--.+?)[,)]/g, (match, g1) => { 160 | vars.push(g1) 161 | return match.replace(g1, '--un-calc') 162 | }) 163 | .replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 ') 164 | .replace(/--un-calc/g, () => vars.shift()!) 165 | }) 166 | } 167 | } 168 | 169 | export function bracket(str: string) { 170 | return bracketWithType(str) 171 | } 172 | 173 | export function bracketOfColor(str: string) { 174 | return bracketWithType(str, 'color') 175 | } 176 | 177 | export function bracketOfLength(str: string) { 178 | return bracketWithType(str, 'length') 179 | } 180 | 181 | export function bracketOfPosition(str: string) { 182 | return bracketWithType(str, 'position') 183 | } 184 | 185 | export function cssvar(str: string) { 186 | if (str.match(/^\$\S/)) 187 | return `var(--${escapeSelector(str.slice(1))})` 188 | } 189 | 190 | export function time(str: string) { 191 | const match = str.match(/^(-?[0-9.]+)(s|ms)?$/i) 192 | if (!match) 193 | return 194 | const [, n, unit] = match 195 | const num = parseFloat(n) 196 | if (!Number.isNaN(num)) { 197 | if (num === 0 && !unit) 198 | return '0s' 199 | return unit ? `${round(num)}${unit}` : `${round(num)}ms` 200 | } 201 | } 202 | 203 | export function degree(str: string) { 204 | const match = str.match(/^(-?[0-9.]+)(deg|rad|grad|turn)?$/i) 205 | if (!match) 206 | return 207 | const [, n, unit] = match 208 | const num = parseFloat(n) 209 | if (!Number.isNaN(num)) { 210 | if (num === 0) 211 | return '0' 212 | return unit ? `${round(num)}${unit}` : `${round(num)}deg` 213 | } 214 | } 215 | 216 | export function global(str: string) { 217 | if (globalKeywords.includes(str)) 218 | return str 219 | } 220 | 221 | export function properties(str: string) { 222 | if (str.split(',').every(prop => cssProps.includes(prop))) 223 | return str 224 | } 225 | 226 | export function position(str: string) { 227 | if (['top', 'left', 'right', 'bottom', 'center'].includes(str)) 228 | return str 229 | } 230 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/handlers/index.ts: -------------------------------------------------------------------------------- 1 | import { createValueHandler } from '@unocss/core' 2 | import * as valueHandlers from './handlers' 3 | 4 | export const handler = createValueHandler(valueHandlers) 5 | export const h = handler 6 | 7 | export { valueHandlers } 8 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/handlers/regex.ts: -------------------------------------------------------------------------------- 1 | export const numberWithUnitRE = /^(-?\d*(?:\.\d+)?)(px|pt|pc|%|r?(?:em|ex|lh|cap|ch|ic)|(?:[sld]?v|cq)(?:[whib]|min|max)|in|cm|mm|rpx)?$/i 2 | export const numberRE = /^(-?\d*(?:\.\d+)?)$/i 3 | export const unitOnlyRE = /^(px)$/i 4 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './colors' 2 | export * from './mappings' 3 | export * from './handlers' 4 | export * from './variants' 5 | export * from './utilities' 6 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/mappings.ts: -------------------------------------------------------------------------------- 1 | export const directionMap: Record = { 2 | 'l': ['-left'], 3 | 'r': ['-right'], 4 | 't': ['-top'], 5 | 'b': ['-bottom'], 6 | 's': ['-inline-start'], 7 | 'e': ['-inline-end'], 8 | 'x': ['-left', '-right'], 9 | 'y': ['-top', '-bottom'], 10 | '': [''], 11 | 'bs': ['-block-start'], 12 | 'be': ['-block-end'], 13 | 'is': ['-inline-start'], 14 | 'ie': ['-inline-end'], 15 | 'block': ['-block-start', '-block-end'], 16 | 'inline': ['-inline-start', '-inline-end'], 17 | } 18 | 19 | export const insetMap: Record = { 20 | ...directionMap, 21 | s: ['-inset-inline-start'], 22 | start: ['-inset-inline-start'], 23 | e: ['-inset-inline-end'], 24 | end: ['-inset-inline-end'], 25 | bs: ['-inset-block-start'], 26 | be: ['-inset-block-end'], 27 | is: ['-inset-inline-start'], 28 | ie: ['-inset-inline-end'], 29 | block: ['-inset-block-start', '-inset-block-end'], 30 | inline: ['-inset-inline-start', '-inset-inline-end'], 31 | } 32 | 33 | export const cornerMap: Record = { 34 | 'l': ['-top-left', '-bottom-left'], 35 | 'r': ['-top-right', '-bottom-right'], 36 | 't': ['-top-left', '-top-right'], 37 | 'b': ['-bottom-left', '-bottom-right'], 38 | 'tl': ['-top-left'], 39 | 'lt': ['-top-left'], 40 | 'tr': ['-top-right'], 41 | 'rt': ['-top-right'], 42 | 'bl': ['-bottom-left'], 43 | 'lb': ['-bottom-left'], 44 | 'br': ['-bottom-right'], 45 | 'rb': ['-bottom-right'], 46 | '': [''], 47 | 'bs': ['-start-start', '-start-end'], 48 | 'be': ['-end-start', '-end-end'], 49 | 's': ['-end-start', '-start-start'], 50 | 'is': ['-end-start', '-start-start'], 51 | 'e': ['-start-end', '-end-end'], 52 | 'ie': ['-start-end', '-end-end'], 53 | 'ss': ['-start-start'], 54 | 'bs-is': ['-start-start'], 55 | 'is-bs': ['-start-start'], 56 | 'se': ['-start-end'], 57 | 'bs-ie': ['-start-end'], 58 | 'ie-bs': ['-start-end'], 59 | 'es': ['-end-start'], 60 | 'be-is': ['-end-start'], 61 | 'is-be': ['-end-start'], 62 | 'ee': ['-end-end'], 63 | 'be-ie': ['-end-end'], 64 | 'ie-be': ['-end-end'], 65 | } 66 | 67 | export const xyzMap: Record = { 68 | 'x': ['-x'], 69 | 'y': ['-y'], 70 | 'z': ['-z'], 71 | '': ['-x', '-y'], 72 | } 73 | 74 | const basePositionMap = [ 75 | 'top', 76 | 'top center', 77 | 'top left', 78 | 'top right', 79 | 'bottom', 80 | 'bottom center', 81 | 'bottom left', 82 | 'bottom right', 83 | 'left', 84 | 'left center', 85 | 'left top', 86 | 'left bottom', 87 | 'right', 88 | 'right center', 89 | 'right top', 90 | 'right bottom', 91 | 'center', 92 | 'center top', 93 | 'center bottom', 94 | 'center left', 95 | 'center right', 96 | 'center center', 97 | ] 98 | 99 | export const positionMap: Record = Object.assign( 100 | {}, 101 | 102 | // [{ top: 'top' }, { 'top-center': 'top center' }, ...] 103 | ...basePositionMap.map(p => ({ [p.replace(/ /, '-')]: p })), 104 | 105 | // [{ t: 'top' }, { tc: 'top center' }, ...] 106 | ...basePositionMap.map(p => ({ [p.replace(/\b(\w)\w+/g, '$1').replace(/ /, '')]: p })), 107 | ) 108 | 109 | export const globalKeywords = [ 110 | 'inherit', 111 | 'initial', 112 | 'revert', 113 | 'revert-layer', 114 | 'unset', 115 | ] 116 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/utilities.ts: -------------------------------------------------------------------------------- 1 | import type { CSSEntries, CSSObject, DynamicMatcher, ParsedColorValue, Rule, RuleContext, VariantContext } from '@unocss/core' 2 | import { isString, toArray } from '@unocss/core' 3 | import type { Theme } from '../_theme'; 4 | import { colorOpacityToString, colorToString, parseCssColor } from './colors' 5 | import { handler as h } from './handlers' 6 | import { directionMap, globalKeywords } from './mappings' 7 | 8 | export const CONTROL_MINI_NO_NEGATIVE = '$$mini-no-negative' 9 | 10 | /** 11 | * Provide {@link DynamicMatcher} function returning spacing definition. See spacing rules. 12 | * 13 | * @param {string} propertyPrefix - Property for the css value to be created. Postfix will be appended according to direction matched. 14 | * @see {@link directionMap} 15 | */ 16 | export function directionSize(propertyPrefix: string): DynamicMatcher { 17 | return ([_, direction, size]: string[], { theme }: RuleContext): CSSEntries | undefined => { 18 | const v = theme.spacing?.[size || 'DEFAULT'] ?? h.bracket.cssvar.global.auto.fraction.rem(size) 19 | if (v != null) 20 | return directionMap[direction].map(i => [`${propertyPrefix}${i}`, v]) 21 | } 22 | } 23 | 24 | /** 25 | * Obtain color from theme by camel-casing colors. 26 | */ 27 | function getThemeColor(theme: Theme, colors: string[]) { 28 | let obj: Theme['colors'] | string = theme.colors 29 | let index = -1 30 | 31 | for (const c of colors) { 32 | index += 1 33 | if (obj && typeof obj !== 'string') { 34 | const camel = colors.slice(index).join('-').replace(/(-[a-z])/g, n => n.slice(1).toUpperCase()) 35 | if (obj[camel]) 36 | return obj[camel] 37 | 38 | if (obj[c]) { 39 | obj = obj[c] 40 | continue 41 | } 42 | } 43 | return undefined 44 | } 45 | 46 | return obj 47 | } 48 | 49 | /** 50 | * Split utility shorthand delimited by / or : 51 | */ 52 | export function splitShorthand(body: string, type: string) { 53 | const split = body.split(/(?:\/|:)/) 54 | 55 | if (split[0] === `[${type}`) { 56 | return [ 57 | split.slice(0, 2).join(':'), 58 | split[2], 59 | ] 60 | } 61 | 62 | return split 63 | } 64 | 65 | /** 66 | * Parse color string into {@link ParsedColorValue} (if possible). Color value will first be matched to theme object before parsing. 67 | * See also color.tests.ts for more examples. 68 | * 69 | * @example Parseable strings: 70 | * 'red' // From theme, if 'red' is available 71 | * 'red-100' // From theme, plus scale 72 | * 'red-100/20' // From theme, plus scale/opacity 73 | * '[rgb(100,2,3)]/[var(--op)]' // Bracket with rgb color and bracket with opacity 74 | * 75 | * @param {string} body - Color string to be parsed. 76 | * @param {Theme} theme - {@link Theme} object. 77 | * @return {ParsedColorValue|undefined} {@link ParsedColorValue} object if string is parseable. 78 | */ 79 | export function parseColor(body: string, theme: Theme): ParsedColorValue | undefined { 80 | const [main, opacity] = splitShorthand(body, 'color') 81 | 82 | const colors = main 83 | .replace(/([a-z])([0-9])/g, '$1-$2') 84 | .split(/-/g) 85 | const [name] = colors 86 | 87 | if (!name) 88 | return 89 | 90 | let color: string | undefined 91 | const bracket = h.bracketOfColor(main) 92 | const bracketOrMain = bracket || main 93 | 94 | if (bracketOrMain.match(/^#[\da-fA-F]+/g)) 95 | color = bracketOrMain 96 | else if (bracketOrMain.match(/^hex-[\da-fA-F]+/g)) 97 | color = `#${bracketOrMain.slice(4)}` 98 | else if (main.startsWith('$')) 99 | color = h.cssvar(main) 100 | 101 | color = color || bracket 102 | 103 | let no = 'DEFAULT' 104 | if (!color) { 105 | let colorData 106 | const [scale] = colors.slice(-1) 107 | if (scale.match(/^\d+$/)) { 108 | no = scale 109 | colorData = getThemeColor(theme, colors.slice(0, -1)) 110 | if (!colorData || typeof colorData === 'string') 111 | color = undefined 112 | else 113 | color = colorData[no] as string 114 | } 115 | else { 116 | colorData = getThemeColor(theme, colors) 117 | if (!colorData && colors.length <= 2) { 118 | [, no = no] = colors 119 | colorData = getThemeColor(theme, [name]) 120 | } 121 | if (typeof colorData === 'string') 122 | color = colorData 123 | else if (no && colorData) 124 | color = colorData[no] as string 125 | } 126 | } 127 | 128 | return { 129 | opacity, 130 | name, 131 | no, 132 | color, 133 | cssColor: parseCssColor(color), 134 | alpha: h.bracket.cssvar.percent(opacity ?? '100'), 135 | } 136 | } 137 | 138 | /** 139 | * Provide {@link DynamicMatcher} function to produce color value matched from rule. 140 | * 141 | * @see {@link parseColor} 142 | * 143 | * @example Resolving 'red' from theme: 144 | * colorResolver('background-color', 'background')('', 'red') 145 | * return { 'background-color': '#f12' } 146 | * 147 | * @example Resolving 'red-100' from theme: 148 | * colorResolver('background-color', 'background')('', 'red-100') 149 | * return { '--un-background-opacity': '1', 'background-color': 'rgba(254,226,226,var(--un-background-opacity))' } 150 | * 151 | * @example Resolving 'red-100/20' from theme: 152 | * colorResolver('background-color', 'background')('', 'red-100/20') 153 | * return { 'background-color': 'rgba(204,251,241,0.22)' } 154 | * 155 | * @example Resolving 'hex-124': 156 | * colorResolver('color', 'text')('', 'hex-124') 157 | * return { '--un-text-opacity': '1', 'color': 'rgba(17,34,68,var(--un-text-opacity))' } 158 | * 159 | * @param {string} property - Property for the css value to be created. 160 | * @param {string} varName - Base name for the opacity variable. 161 | * @param {function} [shouldPass] - Function to decide whether to pass the css. 162 | * @return {@link DynamicMatcher} object. 163 | */ 164 | export function colorResolver(property: string, varName: string, shouldPass?: (css: CSSObject) => boolean): DynamicMatcher { 165 | return ([, body]: string[], { theme }: RuleContext): CSSObject | undefined => { 166 | const data = parseColor(body, theme) 167 | 168 | if (!data) 169 | return 170 | 171 | const { alpha , color, cssColor } = data 172 | 173 | const css: CSSObject = {} 174 | if (cssColor) { 175 | if (alpha != null) { 176 | css[property] = colorToString(cssColor, alpha) 177 | } 178 | else { 179 | css[`--un-${varName}-opacity`] = colorOpacityToString(cssColor) 180 | css[property] = colorToString(cssColor, `var(--un-${varName}-opacity)`) 181 | } 182 | } 183 | else if (color) { 184 | css[property] = colorToString(color, alpha) 185 | } 186 | 187 | if (shouldPass?.(css) !== false) 188 | return css 189 | } 190 | } 191 | 192 | export function colorableShadows(shadows: string | string[], colorVar: string) { 193 | const colored = [] 194 | shadows = toArray(shadows) 195 | for (let i = 0; i < shadows.length; i++) { 196 | // shadow values are between 3 to 6 terms including color 197 | const components = getComponents(shadows[i], ' ', 6) 198 | if (!components || components.length < 3) 199 | return shadows 200 | const color = parseCssColor(components.pop()) 201 | if (color == null) 202 | return shadows 203 | colored.push(`${components.join(' ')} var(${colorVar}, ${colorToString(color)})`) 204 | } 205 | return colored 206 | } 207 | 208 | export function hasParseableColor(color: string | undefined, theme: Theme) { 209 | return color != null && !!parseColor(color, theme)?.color 210 | } 211 | 212 | export function resolveBreakpoints({ theme, generator }: Readonly>) { 213 | let breakpoints: Record | undefined 214 | if (generator.userConfig && generator.userConfig.theme) 215 | breakpoints = (generator.userConfig.theme as any).breakpoints 216 | 217 | if (!breakpoints) 218 | breakpoints = theme.breakpoints 219 | 220 | return breakpoints 221 | } 222 | 223 | export function resolveVerticalBreakpoints({ theme, generator }: Readonly>) { 224 | let verticalBreakpoints: Record | undefined 225 | if (generator.userConfig && generator.userConfig.theme) 226 | verticalBreakpoints = (generator.userConfig.theme as any).verticalBreakpoints 227 | 228 | if (!verticalBreakpoints) 229 | verticalBreakpoints = theme.verticalBreakpoints 230 | 231 | return verticalBreakpoints 232 | } 233 | 234 | export function makeGlobalStaticRules(prefix: string, property?: string) { 235 | return globalKeywords.map(keyword => [`${prefix}-${keyword}`, { [property ?? prefix]: keyword }] as Rule) 236 | } 237 | 238 | export function getBracket(str: string, open: string, close: string) { 239 | if (str === '') 240 | return 241 | 242 | const l = str.length 243 | let parenthesis = 0 244 | let opened = false 245 | let openAt = 0 246 | for (let i = 0; i < l; i++) { 247 | switch (str[i]) { 248 | case open: 249 | if (!opened) { 250 | opened = true 251 | openAt = i 252 | } 253 | parenthesis++ 254 | break 255 | 256 | case close: 257 | --parenthesis 258 | if (parenthesis < 0) 259 | return 260 | if (parenthesis === 0) { 261 | return [ 262 | str.slice(openAt, i + 1), 263 | str.slice(i + 1), 264 | str.slice(0, openAt), 265 | ] 266 | } 267 | break 268 | } 269 | } 270 | } 271 | 272 | export function getComponent(str: string, open: string, close: string, separators: string | string[]) { 273 | if (str === '') 274 | return 275 | 276 | if (isString(separators)) 277 | separators = [separators] 278 | 279 | if (separators.length === 0) 280 | return 281 | 282 | const l = str.length 283 | let parenthesis = 0 284 | for (let i = 0; i < l; i++) { 285 | switch (str[i]) { 286 | case open: 287 | parenthesis++ 288 | break 289 | 290 | case close: 291 | if (--parenthesis < 0) 292 | return 293 | break 294 | 295 | default: 296 | for (const separator of separators) { 297 | const separatorLength = separator.length 298 | if (separatorLength && separator === str.slice(i, i + separatorLength) && parenthesis === 0) { 299 | if (i === 0 || i === l - separatorLength) 300 | return 301 | return [ 302 | str.slice(0, i), 303 | str.slice(i + separatorLength), 304 | ] 305 | } 306 | } 307 | } 308 | } 309 | 310 | return [ 311 | str, 312 | '', 313 | ] 314 | } 315 | 316 | export function getComponents(str: string, separators: string | string[], limit?: number) { 317 | limit = limit ?? 10 318 | const components = [] 319 | let i = 0 320 | while (str !== '') { 321 | if (++i > limit) 322 | return 323 | const componentPair = getComponent(str, '(', ')', separators) 324 | if (!componentPair) 325 | return 326 | const [component, rest] = componentPair 327 | components.push(component) 328 | str = rest 329 | } 330 | if (components.length > 0) 331 | return components 332 | } 333 | -------------------------------------------------------------------------------- /src/preset-react-native/_utils/variants.ts: -------------------------------------------------------------------------------- 1 | import type { VariantHandlerContext, VariantObject } from '@unocss/core' 2 | import { escapeRegExp } from '@unocss/core' 3 | import { getBracket } from '../utils' 4 | 5 | export const variantMatcher = (name: string, handler: (input: VariantHandlerContext) => Record): VariantObject => { 6 | let re: RegExp 7 | return { 8 | name, 9 | match(input, ctx) { 10 | if (!re) 11 | re = new RegExp(`^${escapeRegExp(name)}(?:${ctx.generator.config.separators.join('|')})`) 12 | 13 | const match = input.match(re) 14 | if (match) { 15 | return { 16 | matcher: input.slice(match[0].length), 17 | handle: (input, next) => next({ 18 | ...input, 19 | ...handler(input), 20 | }), 21 | } 22 | } 23 | }, 24 | autocomplete: `${name}:`, 25 | } 26 | } 27 | 28 | export const variantParentMatcher = (name: string, parent: string): VariantObject => { 29 | let re: RegExp 30 | return { 31 | name, 32 | match(input, ctx) { 33 | if (!re) 34 | re = new RegExp(`^${escapeRegExp(name)}(?:${ctx.generator.config.separators.join('|')})`) 35 | 36 | const match = input.match(re) 37 | if (match) { 38 | return { 39 | matcher: input.slice(match[0].length), 40 | handle: (input, next) => next({ 41 | ...input, 42 | parent: `${input.parent ? `${input.parent} $$ ` : ''}${parent}`, 43 | }), 44 | } 45 | } 46 | }, 47 | autocomplete: `${name}:`, 48 | } 49 | } 50 | 51 | export const variantGetBracket = (prefix: string, matcher: string, separators: string[]): string[] | undefined => { 52 | if (matcher.startsWith(`${prefix}[`)) { 53 | const [match, rest] = getBracket(matcher.slice(prefix.length), '[', ']') ?? [] 54 | if (match && rest) { 55 | for (const separator of separators) { 56 | if (rest.startsWith(separator)) 57 | return [match, rest.slice(separator.length), separator] 58 | } 59 | return [match, rest, ''] 60 | } 61 | } 62 | } 63 | 64 | export const variantGetParameter = (prefix: string, matcher: string, separators: string[]): string[] | undefined => { 65 | if (matcher.startsWith(prefix)) { 66 | const body = variantGetBracket(prefix, matcher, separators) 67 | if (body) { 68 | const [label = '', rest = body[1]] = variantGetParameter('/', body[1], separators) ?? [] 69 | return [body[0], rest, label] 70 | } 71 | for (const separator of separators.filter(x => x !== '/')) { 72 | const pos = matcher.indexOf(separator, prefix.length) 73 | if (pos !== -1) { 74 | const labelPos = matcher.indexOf('/', prefix.length) 75 | const unlabelled = labelPos === -1 || pos <= labelPos 76 | return [ 77 | matcher.slice(prefix.length, unlabelled ? pos : labelPos), 78 | matcher.slice(pos + separator.length), 79 | unlabelled ? '' : matcher.slice(labelPos + 1, pos), 80 | ] 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/preset-react-native/index.ts: -------------------------------------------------------------------------------- 1 | import { Preset, PresetOptions } from '@unocss/core'; 2 | import { rules } from './rules'; 3 | import { theme } from './_theme'; 4 | export interface Theme { 5 | width?: Record; 6 | height?: Record; 7 | maxWidth?: Record; 8 | maxHeight?: Record; 9 | minWidth?: Record; 10 | minHeight?: Record; 11 | inlineSize?: Record; 12 | blockSize?: Record; 13 | maxInlineSize?: Record; 14 | maxBlockSize?: Record; 15 | minInlineSize?: Record; 16 | minBlockSize?: Record; 17 | borderRadius?: Record; 18 | breakpoints?: Record; 19 | verticalBreakpoints?: Record; 20 | fontFamily?: Record; 21 | fontSize?: Record; 22 | lineHeight?: Record; 23 | letterSpacing?: Record; 24 | wordSpacing?: Record; 25 | boxShadow?: Record; 26 | textIndent?: Record; 27 | textShadow?: Record; 28 | textStrokeWidth?: Record; 29 | ringWidth?: Record; 30 | lineWidth?: Record; 31 | spacing?: Record; 32 | duration?: Record; 33 | aria?: Record; 34 | data?: Record; 35 | // filters 36 | blur?: Record; 37 | dropShadow?: Record; 38 | // transitions 39 | easing?: Record; 40 | // media queries 41 | media?: Record; 42 | // supports queries 43 | supports?: Record; 44 | // container queries 45 | containers?: Record; 46 | // grids 47 | gridAutoColumn?: Record; 48 | gridAutoRow?: Record; 49 | gridColumn?: Record; 50 | gridRow?: Record; 51 | gridTemplateColumn?: Record; 52 | gridTemplateRow?: Record; 53 | // container 54 | container?: { 55 | center?: boolean; 56 | padding?: string | Record; 57 | maxWidth?: Record; 58 | }; 59 | // vars 60 | /** Used to generate CSS variables placeholder in preflight */ 61 | preflightBase?: Record; 62 | } 63 | 64 | export const presetReactNative = (options: PresetOptions = {}): Preset => { 65 | options.dark = options.dark ?? 'class'; 66 | options.attributifyPseudo = options.attributifyPseudo ?? false; 67 | options.preflight = false; 68 | options.variablePrefix = options.variablePrefix ?? 'un-'; 69 | 70 | return { 71 | name: 'unonative/preset-react', 72 | options, 73 | prefix: options.prefix, 74 | theme: theme, 75 | rules, 76 | }; 77 | }; 78 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/align.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { globalKeywords } from '../_utils/mappings' 3 | 4 | const verticalAlignAlias: Record = { 5 | 'mid': 'middle', 6 | 'base': 'baseline', 7 | 'btm': 'bottom', 8 | 'baseline': 'baseline', 9 | 'top': 'top', 10 | 'start': 'top', 11 | 'middle': 'middle', 12 | 'bottom': 'bottom', 13 | 'end': 'bottom', 14 | 'text-top': 'text-top', 15 | 'text-bottom': 'text-bottom', 16 | 'sub': 'sub', 17 | 'super': 'super', 18 | ...Object.fromEntries(globalKeywords.map(x => [x, x])), 19 | } 20 | 21 | export const verticalAligns: Rule[] = [ 22 | [/^(?:vertical|align|v)-([-\w]+)$/, ([, v]) => ({ 'vertical-align': verticalAlignAlias[v] }), { autocomplete: `(vertical|align|v)-(${Object.keys(verticalAlignAlias).join('|')})` }], 23 | ] 24 | 25 | export const textAligns: Rule[] = ['center', 'left', 'right', 'justify', 'start', 'end'].map(v => [`text-${v}`, { 'text-align': v }]) 26 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/border.ts: -------------------------------------------------------------------------------- 1 | import type { CSSEntries, CSSObject, Rule, RuleContext } from '@unocss/core' 2 | import type { Theme } from '../theme' 3 | import { colorOpacityToString, colorToString, cornerMap, directionMap, globalKeywords, handler as h, hasParseableColor, parseColor } from '../utils' 4 | 5 | export const borderStyles = ['solid', 'dashed', 'dotted', 'double', 'hidden', 'none', 'groove', 'ridge', 'inset', 'outset', ...globalKeywords] 6 | 7 | export const borders: Rule[] = [ 8 | // compound 9 | [/^(?:border|b)()(?:-(.+))?$/, handlerBorder, { autocomplete: '(border|b)-' }], 10 | [/^(?:border|b)-([xy])(?:-(.+))?$/, handlerBorder], 11 | [/^(?:border|b)-([rltbse])(?:-(.+))?$/, handlerBorder], 12 | [/^(?:border|b)-(block|inline)(?:-(.+))?$/, handlerBorder], 13 | [/^(?:border|b)-([bi][se])(?:-(.+))?$/, handlerBorder], 14 | 15 | // size 16 | [/^(?:border|b)-()(?:width|size)-(.+)$/, handlerBorderSize, { autocomplete: ['(border|b)-', '(border|b)--'] }], 17 | [/^(?:border|b)-([xy])-(?:width|size)-(.+)$/, handlerBorderSize], 18 | [/^(?:border|b)-([rltbse])-(?:width|size)-(.+)$/, handlerBorderSize], 19 | [/^(?:border|b)-(block|inline)-(?:width|size)-(.+)$/, handlerBorderSize], 20 | [/^(?:border|b)-([bi][se])-(?:width|size)-(.+)$/, handlerBorderSize], 21 | 22 | // colors 23 | [/^(?:border|b)-()(?:color-)?(.+)$/, handlerBorderColor, { autocomplete: ['(border|b)-$colors', '(border|b)--$colors'] }], 24 | [/^(?:border|b)-([xy])-(?:color-)?(.+)$/, handlerBorderColor], 25 | [/^(?:border|b)-([rltbse])-(?:color-)?(.+)$/, handlerBorderColor], 26 | [/^(?:border|b)-(block|inline)-(?:color-)?(.+)$/, handlerBorderColor], 27 | [/^(?:border|b)-([bi][se])-(?:color-)?(.+)$/, handlerBorderColor], 28 | 29 | // radius 30 | [/^(?:border-|b-)?(?:rounded|rd)()(?:-(.+))?$/, handlerRounded, { autocomplete: ['(border|b)-(rounded|rd)', '(border|b)-(rounded|rd)-', '(rounded|rd)', '(rounded|rd)-'] }], 31 | [/^(?:border-|b-)?(?:rounded|rd)-([rltbse])(?:-(.+))?$/, handlerRounded], 32 | [/^(?:border-|b-)?(?:rounded|rd)-([rltb]{2})(?:-(.+))?$/, handlerRounded], 33 | [/^(?:border-|b-)?(?:rounded|rd)-([bise][se])(?:-(.+))?$/, handlerRounded], 34 | [/^(?:border-|b-)?(?:rounded|rd)-([bi][se]-[bi][se])(?:-(.+))?$/, handlerRounded], 35 | 36 | // style 37 | [/^(?:border|b)-(?:style-)?()(.+)$/, handlerBorderStyle, { autocomplete: ['(border|b)-style', `(border|b)-(${borderStyles.join('|')})`, '(border|b)--style', `(border|b)--(${borderStyles.join('|')})`, `(border|b)--style-(${borderStyles.join('|')})`, `(border|b)-style-(${borderStyles.join('|')})`] }], 38 | [/^(?:border|b)-([xy])-(?:style-)?(.+)$/, handlerBorderStyle], 39 | [/^(?:border|b)-([rltbse])-(?:style-)?(.+)$/, handlerBorderStyle], 40 | [/^(?:border|b)-(block|inline)-(?:style-)?(.+)$/, handlerBorderStyle], 41 | [/^(?:border|b)-([bi][se])-(?:style-)?(.+)$/, handlerBorderStyle], 42 | ] 43 | 44 | const borderColorResolver = (direction: string) => ([, body]: string[], theme: Theme): CSSObject | undefined => { 45 | const data = parseColor(body, theme) 46 | 47 | if (!data) 48 | return 49 | 50 | const { alpha, color, cssColor } = data 51 | 52 | if (cssColor) { 53 | if (alpha != null) { 54 | return { 55 | [`border${direction}-color`]: colorToString(cssColor, alpha), 56 | } 57 | } 58 | } 59 | else if (color) { 60 | return { 61 | [`border${direction}-color`]: colorToString(color, alpha), 62 | } 63 | } 64 | } 65 | 66 | function handlerBorder(m: string[], ctx: RuleContext): CSSEntries | undefined { 67 | return handlerBorderSize(m, ctx) 68 | } 69 | 70 | function handlerBorderSize([, a = '', b]: string[], { theme }: RuleContext): CSSEntries | undefined { 71 | const v = theme.lineWidth?.[b || 'DEFAULT'] ?? h.bracket.cssvar.global.px(b || '1') 72 | if (a in directionMap && v != null) 73 | return directionMap[a].map(i => [`border${i}-width`, v]) 74 | } 75 | 76 | function handlerBorderColor([, a = '', c]: string[], { theme }: RuleContext): CSSObject | undefined { 77 | if (a in directionMap && hasParseableColor(c, theme)) { 78 | return Object.assign( 79 | {}, 80 | ...directionMap[a].map(i => borderColorResolver(i)(['', c], theme)), 81 | ) 82 | } 83 | } 84 | 85 | function handlerRounded([, a = '', s]: string[], { theme }: RuleContext): CSSEntries | undefined { 86 | const v = theme.borderRadius?.[s || 'DEFAULT'] || h.bracket.cssvar.global.fraction.rem(s || '1') 87 | if (a in cornerMap && v != null) 88 | return cornerMap[a].map(i => [`border${i}-radius`, v]) 89 | } 90 | 91 | export function handlerBorderStyle([, a = '', s]: string[]): CSSEntries | undefined { 92 | if (borderStyles.includes(s) && a in directionMap) 93 | return directionMap[a].map(i => [`border${i}-style`, s]) 94 | } 95 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/color.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { colorResolver, globalKeywords, handler as h } from '../utils' 3 | import { numberWithUnitRE } from '../_utils/handlers/regex' 4 | 5 | /** 6 | * @example op10 op-30 opacity-100 7 | */ 8 | export const opacity: Rule[] = [ 9 | [/^op(?:acity)?-?(.+)$/, ([, d]) => ({ opacity: h.bracket.percent.cssvar(d) })], 10 | ] 11 | 12 | /** 13 | * @example c-red color-red5 text-red-300 14 | */ 15 | export const textColors: Rule[] = [ 16 | [/^(?:color|c)-(.+)$/, colorResolver('color', 'text'), { autocomplete: '(color|c)-$colors' }], 17 | // auto detection and fallback to font-size if the content looks like a size 18 | [/^text-(.+)$/, colorResolver('color', 'text', css => !css.color?.toString().match(numberWithUnitRE)), { autocomplete: 'text-$colors' }], 19 | [/^(?:text|color|c)-(.+)$/, ([, v]) => globalKeywords.includes(v) ? { color: v } : undefined, { autocomplete: `(text|color|c)-(${globalKeywords.join('|')})` }], 20 | ] 21 | 22 | export const bgColors: Rule[] = [ 23 | [/^bg-(.+)$/, colorResolver('background-color', 'bg'), { autocomplete: 'bg-$colors' }], 24 | ] 25 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/decoration.ts: -------------------------------------------------------------------------------- 1 | import type { CSSObject, Rule } from '@unocss/core' 2 | import type { Theme } from '../theme' 3 | import { colorResolver, globalKeywords, handler as h } from '../utils' 4 | 5 | const decorationStyles = ['solid', 'double', 'dotted', 'dashed', 'wavy', ...globalKeywords] 6 | 7 | export const textDecorations: Rule[] = [ 8 | [/^(?:decoration-)?(underline|overline|line-through)$/, ([, s]) => ({ 'text-decoration-line': s }), { autocomplete: 'decoration-(underline|overline|line-through)' }], 9 | 10 | // size 11 | [/^(?:underline|decoration)-(?:size-)?(.+)$/, ([, s], { theme }) => ({ 'text-decoration-thickness': theme.lineWidth?.[s] ?? h.bracket.cssvar.global.px(s) }), { autocomplete: '(underline|decoration)-' }], 12 | [/^(?:underline|decoration)-(auto|from-font)$/, ([, s]) => ({ 'text-decoration-thickness': s }), { autocomplete: '(underline|decoration)-(auto|from-font)' }], 13 | 14 | // colors 15 | [/^(?:underline|decoration)-(.+)$/, (match, ctx) => { 16 | const result = colorResolver('text-decoration-color', 'line')(match, ctx) as CSSObject | undefined 17 | if (result) { 18 | return { 19 | '-webkit-text-decoration-color': result['text-decoration-color'], 20 | ...result, 21 | } 22 | } 23 | }, { autocomplete: '(underline|decoration)-$colors' }], 24 | [/^(?:underline|decoration)-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-line-opacity': h.bracket.percent(opacity) }), { autocomplete: '(underline|decoration)-(op|opacity)-' }], 25 | 26 | // offset 27 | [/^(?:underline|decoration)-offset-(.+)$/, ([, s], { theme }) => ({ 'text-underline-offset': theme.lineWidth?.[s] ?? h.auto.bracket.cssvar.global.px(s) }), { autocomplete: '(underline|decoration)-(offset)-' }], 28 | 29 | // style 30 | ...decorationStyles.map(v => [`underline-${v}`, { 'text-decoration-style': v }] as Rule), 31 | ...decorationStyles.map(v => [`decoration-${v}`, { 'text-decoration-style': v }] as Rule), 32 | ['no-underline', { 'text-decoration': 'none' }], 33 | ['decoration-none', { 'text-decoration': 'none' }], 34 | ] 35 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/default.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core'; 2 | import { transitions } from './transition'; 3 | import { borders } from './border'; 4 | import { bgColors, opacity, textColors } from './color'; 5 | import { flex } from './flex'; 6 | import { 7 | fonts, 8 | tabSizes, 9 | textIndents, 10 | textShadows, 11 | textStrokes, 12 | } from './typography'; 13 | import { gaps } from './gap'; 14 | import { overflows } from './layout'; 15 | import { 16 | alignments, 17 | boxSizing, 18 | floats, 19 | insets, 20 | justifies, 21 | orders, 22 | placements, 23 | positions, 24 | zIndexes, 25 | } from './position'; 26 | import { aspectRatio, sizes } from './size'; 27 | import { margins, paddings } from './spacing'; 28 | import { 29 | appearances, 30 | breaks, 31 | contains, 32 | contentVisibility, 33 | contents, 34 | cursors, 35 | displays, 36 | fontSmoothings, 37 | fontStyles, 38 | pointerEvents, 39 | resizes, 40 | textOverflows, 41 | textTransforms, 42 | userSelects, 43 | whitespaces, 44 | } from './static'; 45 | import { transforms } from './transform'; 46 | import { cssProperty, cssVariables } from './variables'; 47 | import { textAligns, verticalAligns } from './align'; 48 | import { textDecorations } from './decoration'; 49 | 50 | export const rules: Rule[] = [ 51 | cssVariables, 52 | cssProperty, 53 | paddings, 54 | margins, 55 | displays, 56 | opacity, 57 | bgColors, 58 | borders, 59 | contentVisibility, 60 | contents, 61 | fonts, 62 | tabSizes, 63 | textIndents, 64 | textOverflows, 65 | textDecorations, 66 | textStrokes, 67 | textShadows, 68 | textTransforms, 69 | textAligns, 70 | textColors, 71 | fontStyles, 72 | fontSmoothings, 73 | flex, 74 | gaps, 75 | positions, 76 | sizes, 77 | aspectRatio, 78 | cursors, 79 | appearances, 80 | pointerEvents, 81 | resizes, 82 | verticalAligns, 83 | userSelects, 84 | whitespaces, 85 | breaks, 86 | overflows, 87 | orders, 88 | justifies, 89 | alignments, 90 | placements, 91 | insets, 92 | floats, 93 | zIndexes, 94 | boxSizing, 95 | transitions, 96 | transforms, 97 | contains, 98 | ].flat(1); 99 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/flex.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import type { Theme } from '../theme' 3 | import { handler as h } from '../utils' 4 | 5 | export const flex: Rule[] = [ 6 | // display 7 | ['flex', { display: 'flex' }], 8 | ['inline-flex', { display: 'inline-flex' }], 9 | ['flex-inline', { display: 'inline-flex' }], 10 | 11 | // flex 12 | [/^flex-(.*)$/, ([, d]) => ({ flex: h.bracket(d) != null ? h.bracket(d)!.split(' ').map(e => h.cssvar.fraction(e) ?? e).join(' ') : h.cssvar.fraction(d) })], 13 | ['flex-1', { flex: '1 1 0%' }], 14 | ['flex-auto', { flex: '1 1 auto' }], 15 | ['flex-initial', { flex: '0 1 auto' }], 16 | ['flex-none', { flex: 'none' }], 17 | 18 | // shrink/grow/basis 19 | [/^(?:flex-)?shrink(?:-(.*))?$/, ([, d = '']) => ({ 'flex-shrink': h.bracket.cssvar.number(d) ?? 1 }), { autocomplete: ['flex-shrink-', 'shrink-'] }], 20 | [/^(?:flex-)?grow(?:-(.*))?$/, ([, d = '']) => ({ 'flex-grow': h.bracket.cssvar.number(d) ?? 1 }), { autocomplete: ['flex-grow-', 'grow-'] }], 21 | [/^(?:flex-)?basis-(.+)$/, ([, d], { theme }) => ({ 'flex-basis': theme.spacing?.[d] ?? h.bracket.cssvar.auto.fraction.rem(d) }), { autocomplete: ['flex-basis-$spacing', 'basis-$spacing'] }], 22 | 23 | // directions 24 | ['flex-row', { 'flex-direction': 'row' }], 25 | ['flex-row-reverse', { 'flex-direction': 'row-reverse' }], 26 | ['flex-col', { 'flex-direction': 'column' }], 27 | ['flex-col-reverse', { 'flex-direction': 'column-reverse' }], 28 | 29 | // wraps 30 | ['flex-wrap', { 'flex-wrap': 'wrap' }], 31 | ['flex-wrap-reverse', { 'flex-wrap': 'wrap-reverse' }], 32 | ['flex-nowrap', { 'flex-wrap': 'nowrap' }], 33 | ] 34 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/gap.ts: -------------------------------------------------------------------------------- 1 | import type { Rule, RuleContext } from '@unocss/core' 2 | import type { Theme } from '../theme' 3 | import { handler as h } from '../utils' 4 | 5 | const directions: Record = { 6 | '': '', 7 | 'x': 'column-', 8 | 'y': 'row-', 9 | } 10 | 11 | const handleGap = ([, d = '', s]: string[], { theme }: RuleContext) => { 12 | const v = theme.spacing?.[s] ?? h.bracket.cssvar.global.rem(s) 13 | if (v != null) { 14 | return { 15 | [`grid-${directions[d]}gap`]: v, 16 | [`${directions[d]}gap`]: v, 17 | } 18 | } 19 | } 20 | 21 | export const gaps: Rule[] = [ 22 | [/^(?:flex-|grid-)?gap-?()(.+)$/, handleGap, { autocomplete: ['gap-$spacing', 'gap-'] }], 23 | [/^(?:flex-|grid-)?gap-([xy])-?(.+)$/, handleGap, { autocomplete: ['gap-(x|y)-$spacing', 'gap-(x|y)-'] }], 24 | ] 25 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './default'; 2 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/layout.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { globalKeywords } from '../utils' 3 | 4 | const overflowValues = [ 5 | 'auto', 6 | 'hidden', 7 | 'clip', 8 | 'visible', 9 | 'scroll', 10 | 'overlay', 11 | ...globalKeywords, 12 | ] 13 | 14 | export const overflows: Rule[] = [ 15 | [/^(?:overflow|of)-(.+)$/, ([, v]) => overflowValues.includes(v) ? { overflow: v } : undefined, { autocomplete: [`(overflow|of)-(${overflowValues.join('|')})`, `(overflow|of)-(x|y)-(${overflowValues.join('|')})`] }], 16 | [/^(?:overflow|of)-([xy])-(.+)$/, ([, d, v]) => overflowValues.includes(v) ? { [`overflow-${d}`]: v } : undefined], 17 | ] 18 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/position.ts: -------------------------------------------------------------------------------- 1 | import type { CSSEntries, Rule, RuleContext } from '@unocss/core' 2 | import type { Theme } from '../theme' 3 | import { globalKeywords, handler as h, insetMap, makeGlobalStaticRules } from '../utils' 4 | 5 | export const positions: Rule[] = [ 6 | [/^(?:position-|pos-)?(relative|absolute|fixed|sticky)$/, ([, v]) => ({ position: v })], 7 | [/^(?:position-|pos-)([-\w]+)$/, ([, v]) => globalKeywords.includes(v) ? { position: v } : undefined], 8 | [/^(?:position-|pos-)?(static)$/, ([, v]) => ({ position: v })], 9 | ] 10 | 11 | export const justifies: Rule[] = [ 12 | // contents 13 | ['justify-start', { 'justify-content': 'flex-start' }], 14 | ['justify-end', { 'justify-content': 'flex-end' }], 15 | ['justify-center', { 'justify-content': 'center' }], 16 | ['justify-between', { 'justify-content': 'space-between' }], 17 | ['justify-around', { 'justify-content': 'space-around' }], 18 | ['justify-evenly', { 'justify-content': 'space-evenly' }], 19 | ...makeGlobalStaticRules('justify', 'justify-content'), 20 | 21 | // items 22 | ['justify-items-start', { 'justify-items': 'start' }], 23 | ['justify-items-end', { 'justify-items': 'end' }], 24 | ['justify-items-center', { 'justify-items': 'center' }], 25 | ['justify-items-stretch', { 'justify-items': 'stretch' }], 26 | ...makeGlobalStaticRules('justify-items'), 27 | 28 | // selfs 29 | ['justify-self-auto', { 'justify-self': 'auto' }], 30 | ['justify-self-start', { 'justify-self': 'start' }], 31 | ['justify-self-end', { 'justify-self': 'end' }], 32 | ['justify-self-center', { 'justify-self': 'center' }], 33 | ['justify-self-stretch', { 'justify-self': 'stretch' }], 34 | ...makeGlobalStaticRules('justify-self'), 35 | ] 36 | 37 | export const orders: Rule[] = [ 38 | [/^order-(.+)$/, ([, v]) => ({ order: h.bracket.cssvar.number(v) })], 39 | ['order-first', { order: '-9999' }], 40 | ['order-last', { order: '9999' }], 41 | ['order-none', { order: '0' }], 42 | ] 43 | 44 | export const alignments: Rule[] = [ 45 | // contents 46 | ['content-center', { 'align-content': 'center' }], 47 | ['content-start', { 'align-content': 'flex-start' }], 48 | ['content-end', { 'align-content': 'flex-end' }], 49 | ['content-between', { 'align-content': 'space-between' }], 50 | ['content-around', { 'align-content': 'space-around' }], 51 | ['content-evenly', { 'align-content': 'space-evenly' }], 52 | ...makeGlobalStaticRules('content', 'align-content'), 53 | 54 | // items 55 | ['items-start', { 'align-items': 'flex-start' }], 56 | ['items-end', { 'align-items': 'flex-end' }], 57 | ['items-center', { 'align-items': 'center' }], 58 | ['items-baseline', { 'align-items': 'baseline' }], 59 | ['items-stretch', { 'align-items': 'stretch' }], 60 | ...makeGlobalStaticRules('items', 'align-items'), 61 | 62 | // selfs 63 | ['self-auto', { 'align-self': 'auto' }], 64 | ['self-start', { 'align-self': 'flex-start' }], 65 | ['self-end', { 'align-self': 'flex-end' }], 66 | ['self-center', { 'align-self': 'center' }], 67 | ['self-stretch', { 'align-self': 'stretch' }], 68 | ['self-baseline', { 'align-self': 'baseline' }], 69 | ...makeGlobalStaticRules('self', 'align-self'), 70 | ] 71 | 72 | export const placements: Rule[] = [ 73 | // contents 74 | ['place-content-center', { 'place-content': 'center' }], 75 | ['place-content-start', { 'place-content': 'start' }], 76 | ['place-content-end', { 'place-content': 'end' }], 77 | ['place-content-between', { 'place-content': 'space-between' }], 78 | ['place-content-around', { 'place-content': 'space-around' }], 79 | ['place-content-evenly', { 'place-content': 'space-evenly' }], 80 | ['place-content-stretch', { 'place-content': 'stretch' }], 81 | ...makeGlobalStaticRules('place-content'), 82 | 83 | // items 84 | ['place-items-start', { 'place-items': 'start' }], 85 | ['place-items-end', { 'place-items': 'end' }], 86 | ['place-items-center', { 'place-items': 'center' }], 87 | ['place-items-stretch', { 'place-items': 'stretch' }], 88 | ...makeGlobalStaticRules('place-items'), 89 | 90 | // selfs 91 | ['place-self-auto', { 'place-self': 'auto' }], 92 | ['place-self-start', { 'place-self': 'start' }], 93 | ['place-self-end', { 'place-self': 'end' }], 94 | ['place-self-center', { 'place-self': 'center' }], 95 | ['place-self-stretch', { 'place-self': 'stretch' }], 96 | ...makeGlobalStaticRules('place-self'), 97 | ] 98 | 99 | function handleInsetValue(v: string, { theme }: RuleContext): string | number | undefined { 100 | return theme.spacing?.[v] ?? h.bracket.cssvar.global.auto.fraction.rem(v) 101 | } 102 | 103 | function handleInsetValues([, d, v]: string[], ctx: RuleContext): CSSEntries | undefined { 104 | const r = handleInsetValue(v, ctx) 105 | if (r != null && d in insetMap) 106 | return insetMap[d].map(i => [i.slice(1), r]) 107 | } 108 | 109 | export const insets: Rule[] = [ 110 | [/^(?:position-|pos-)?inset-(.+)$/, ([, v], ctx) => ({ inset: handleInsetValue(v, ctx) }), 111 | { 112 | autocomplete: [ 113 | '(position|pos)-inset--$spacing', 114 | '(position|pos)-inset-(block|inline)-$spacing', 115 | '(position|pos)-inset-(bs|be|is|ie)-$spacing', 116 | '(position|pos)-(top|left|right|bottom)-$spacing', 117 | ], 118 | }, 119 | ], 120 | [/^(?:position-|pos-)?(start|end)-(.+)$/, handleInsetValues], 121 | [/^(?:position-|pos-)?inset-([xy])-(.+)$/, handleInsetValues], 122 | [/^(?:position-|pos-)?inset-([rltbse])-(.+)$/, handleInsetValues], 123 | [/^(?:position-|pos-)?inset-(block|inline)-(.+)$/, handleInsetValues], 124 | [/^(?:position-|pos-)?inset-([bi][se])-(.+)$/, handleInsetValues], 125 | [/^(?:position-|pos-)?(top|left|right|bottom)-(.+)$/, ([, d, v], ctx) => ({ [d]: handleInsetValue(v, ctx) })], 126 | ] 127 | 128 | export const floats: Rule[] = [ 129 | // floats 130 | ['float-left', { float: 'left' }], 131 | ['float-right', { float: 'right' }], 132 | ['float-none', { float: 'none' }], 133 | ...makeGlobalStaticRules('float'), 134 | 135 | // clears 136 | ['clear-left', { clear: 'left' }], 137 | ['clear-right', { clear: 'right' }], 138 | ['clear-both', { clear: 'both' }], 139 | ['clear-none', { clear: 'none' }], 140 | ...makeGlobalStaticRules('clear'), 141 | ] 142 | 143 | export const zIndexes: Rule[] = [ 144 | [/^(?:position-|pos-)?z([\d.]+)$/, ([, v]) => ({ 'z-index': h.number(v) })], 145 | [/^(?:position-|pos-)?z-(.+)$/, ([, v]) => ({ 'z-index': h.bracket.cssvar.global.auto.number(v) }), { autocomplete: 'z-' }], 146 | ] 147 | 148 | export const boxSizing: Rule[] = [ 149 | ['box-border', { 'box-sizing': 'border-box' }], 150 | ['box-content', { 'box-sizing': 'content-box' }], 151 | ...makeGlobalStaticRules('box', 'box-sizing'), 152 | ] 153 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/size.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import type { Theme } from '../theme' 3 | import { handler as h, resolveBreakpoints, resolveVerticalBreakpoints } from '../utils' 4 | 5 | const sizeMapping: Record = { 6 | h: 'height', 7 | w: 'width', 8 | inline: 'inline-size', 9 | block: 'block-size', 10 | } 11 | 12 | function getPropName(minmax: string, hw: string) { 13 | return `${minmax || ''}${sizeMapping[hw]}` 14 | } 15 | 16 | type SizeProps = 'width' | 'height' | 'maxWidth' | 'maxHeight' | 'minWidth' | 'minHeight' | 'inlineSize' | 'blockSize' | 'maxInlineSize' | 'maxBlockSize' | 'minInlineSize' | 'minBlockSize' 17 | 18 | function getSizeValue(minmax: string, hw: string, theme: Theme, prop: string) { 19 | const str = getPropName(minmax, hw).replace(/-(\w)/g, (_, p) => p.toUpperCase()) as SizeProps 20 | const v = theme[str]?.[prop] 21 | if (v != null) 22 | return v 23 | 24 | switch (prop) { 25 | case 'fit': 26 | case 'max': 27 | case 'min': 28 | return `${prop}-content` 29 | } 30 | 31 | return h.bracket.cssvar.global.auto.fraction.rem(prop) 32 | } 33 | 34 | export const sizes: Rule[] = [ 35 | [/^(?:size-)?(min-|max-)?([wh])-?(.+)$/, ([, m, w, s], { theme }) => ({ [getPropName(m, w)]: getSizeValue(m, w, theme, s) })], 36 | [/^(?:size-)?(min-|max-)?(block|inline)-(.+)$/, ([, m, w, s], { theme }) => ({ [getPropName(m, w)]: getSizeValue(m, w, theme, s) }), { 37 | autocomplete: [ 38 | '(w|h)-$width|height|maxWidth|maxHeight|minWidth|minHeight|inlineSize|blockSize|maxInlineSize|maxBlockSize|minInlineSize|minBlockSize', 39 | '(block|inline)-$width|height|maxWidth|maxHeight|minWidth|minHeight|inlineSize|blockSize|maxInlineSize|maxBlockSize|minInlineSize|minBlockSize', 40 | '(max|min)-(w|h|block|inline)', 41 | '(max|min)-(w|h|block|inline)-$width|height|maxWidth|maxHeight|minWidth|minHeight|inlineSize|blockSize|maxInlineSize|maxBlockSize|minInlineSize|minBlockSize', 42 | ], 43 | }], 44 | [/^(?:size-)?(min-|max-)?(h)-screen-(.+)$/, ([, m, w, s], context) => ({ [getPropName(m, w)]: resolveVerticalBreakpoints(context)?.[s] })], 45 | [/^(?:size-)?(min-|max-)?(w)-screen-(.+)$/, ([, m, w, s], context) => ({ [getPropName(m, w)]: resolveBreakpoints(context)?.[s] }), { 46 | autocomplete: [ 47 | '(w|h)-screen', 48 | '(min|max)-(w|h)-screen', 49 | 'h-screen-$verticalBreakpoints', 50 | '(min|max)-h-screen-$verticalBreakpoints', 51 | 'w-screen-$breakpoints', 52 | '(min|max)-w-screen-$breakpoints', 53 | ], 54 | }], 55 | ] 56 | 57 | function getAspectRatio(prop: string) { 58 | if (/^\d+\/\d+$/.test(prop)) 59 | return prop 60 | 61 | switch (prop) { 62 | case 'square': return '1/1' 63 | case 'video': return '16/9' 64 | } 65 | 66 | return h.bracket.cssvar.global.auto.number(prop) 67 | } 68 | 69 | export const aspectRatio: Rule[] = [ 70 | [/^(?:size-)?aspect-(?:ratio-)?(.+)$/, ([, d]: string[]) => ({ 'aspect-ratio': getAspectRatio(d) }), { autocomplete: ['aspect-(square|video|ratio)', 'aspect-ratio-(square|video)'] }], 71 | ] 72 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/spacing.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { directionSize } from '../utils' 3 | 4 | export const paddings: Rule[] = [ 5 | [/^pa?()-?(-?.+)$/, directionSize('padding'), { autocomplete: ['(m|p)', '(m|p)-'] }], 6 | [/^p-?xy()()$/, directionSize('padding'), { autocomplete: '(m|p)-(xy)' }], 7 | [/^p-?([xy])(?:-?(-?.+))?$/, directionSize('padding')], 8 | [/^p-?([rltbse])(?:-?(-?.+))?$/, directionSize('padding'), { autocomplete: '(m|p)-' }], 9 | [/^p-(block|inline)(?:-(-?.+))?$/, directionSize('padding'), { autocomplete: '(m|p)-(block|inline)-' }], 10 | [/^p-?([bi][se])(?:-?(-?.+))?$/, directionSize('padding'), { autocomplete: '(m|p)-(bs|be|is|ie)-' }], 11 | ] 12 | 13 | export const margins: Rule[] = [ 14 | [/^ma?()-?(-?.+)$/, directionSize('margin')], 15 | [/^m-?xy()()$/, directionSize('margin')], 16 | [/^m-?([xy])(?:-?(-?.+))?$/, directionSize('margin')], 17 | [/^m-?([rltbse])(?:-?(-?.+))?$/, directionSize('margin')], 18 | [/^m-(block|inline)(?:-(-?.+))?$/, directionSize('margin')], 19 | [/^m-?([bi][se])(?:-?(-?.+))?$/, directionSize('margin')], 20 | ] 21 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/static.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { globalKeywords, handler as h, makeGlobalStaticRules } from '../utils' 3 | 4 | const cursorValues = ['auto', 'default', 'none', 'context-menu', 'help', 'pointer', 'progress', 'wait', 'cell', 'crosshair', 'text', 'vertical-text', 'alias', 'copy', 'move', 'no-drop', 'not-allowed', 'grab', 'grabbing', 'all-scroll', 'col-resize', 'row-resize', 'n-resize', 'e-resize', 's-resize', 'w-resize', 'ne-resize', 'nw-resize', 'se-resize', 'sw-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out'] 5 | const containValues = ['none', 'strict', 'content', 'size', 'inline-size', 'layout', 'style', 'paint'] 6 | 7 | export const varEmpty = ' ' 8 | 9 | // display table included on table.ts 10 | export const displays: Rule[] = [ 11 | ['inline', { display: 'inline' }], 12 | ['block', { display: 'block' }], 13 | ['inline-block', { display: 'inline-block' }], 14 | ['contents', { display: 'contents' }], 15 | ['flow-root', { display: 'flow-root' }], 16 | ['list-item', { display: 'list-item' }], 17 | ['hidden', { display: 'none' }], 18 | [/^display-(.+)$/, ([, c]) => ({ display: h.bracket.cssvar.global(c) || c })], 19 | ] 20 | 21 | export const appearances: Rule[] = [ 22 | ['visible', { visibility: 'visible' }], 23 | ['invisible', { visibility: 'hidden' }], 24 | ['backface-visible', { 'backface-visibility': 'visible' }], 25 | ['backface-hidden', { 'backface-visibility': 'hidden' }], 26 | ...makeGlobalStaticRules('backface', 'backface-visibility'), 27 | ] 28 | 29 | export const cursors: Rule[] = [ 30 | [/^cursor-(.+)$/, ([, c]) => ({ cursor: h.bracket.cssvar.global(c) })], 31 | ...cursorValues.map((v): Rule => [`cursor-${v}`, { cursor: v }]), 32 | ] 33 | 34 | export const contains: Rule[] = [ 35 | [/^contain-(.*)$/, ([, d]) => { 36 | if (h.bracket(d) != null) { 37 | return { 38 | contain: h.bracket(d)!.split(' ').map(e => h.cssvar.fraction(e) ?? e).join(' '), 39 | } 40 | } 41 | 42 | return containValues.includes(d) ? { contain: d } : undefined 43 | }], 44 | ] 45 | 46 | export const pointerEvents: Rule[] = [ 47 | ['pointer-events-auto', { 'pointer-events': 'auto' }], 48 | ['pointer-events-none', { 'pointer-events': 'none' }], 49 | ...makeGlobalStaticRules('pointer-events'), 50 | ] 51 | 52 | export const resizes: Rule[] = [ 53 | ['resize-x', { resize: 'horizontal' }], 54 | ['resize-y', { resize: 'vertical' }], 55 | ['resize', { resize: 'both' }], 56 | ['resize-none', { resize: 'none' }], 57 | ...makeGlobalStaticRules('resize'), 58 | ] 59 | 60 | export const userSelects: Rule[] = [ 61 | ['select-auto', { 'user-select': 'auto' }], 62 | ['select-all', { 'user-select': 'all' }], 63 | ['select-text', { 'user-select': 'text' }], 64 | ['select-none', { 'user-select': 'none' }], 65 | ...makeGlobalStaticRules('select', 'user-select'), 66 | ] 67 | 68 | export const whitespaces: Rule[] = [ 69 | [ 70 | /^(?:whitespace-|ws-)([-\w]+)$/, 71 | ([, v]) => ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces', ...globalKeywords].includes(v) ? { 'white-space': v } : undefined, 72 | { autocomplete: '(whitespace|ws)-(normal|nowrap|pre|pre-line|pre-wrap|break-spaces)' }, 73 | ], 74 | ] 75 | 76 | export const contentVisibility: Rule[] = [ 77 | [/^intrinsic-size-(.+)$/, ([, d]) => ({ 'contain-intrinsic-size': h.bracket.cssvar.global.fraction.rem(d) }), { autocomplete: 'intrinsic-size-' }], 78 | ['content-visibility-visible', { 'content-visibility': 'visible' }], 79 | ['content-visibility-hidden', { 'content-visibility': 'hidden' }], 80 | ['content-visibility-auto', { 'content-visibility': 'auto' }], 81 | ...makeGlobalStaticRules('content-visibility'), 82 | ] 83 | 84 | export const contents: Rule[] = [ 85 | [/^content-(.+)$/, ([, v]) => ({ content: h.bracket.cssvar(v) })], 86 | ['content-empty', { content: '""' }], 87 | ['content-none', { content: '""' }], 88 | ] 89 | 90 | export const breaks: Rule[] = [ 91 | ['break-normal', { 'overflow-wrap': 'normal', 'word-break': 'normal' }], 92 | ['break-words', { 'overflow-wrap': 'break-word' }], 93 | ['break-all', { 'word-break': 'break-all' }], 94 | ['break-keep', { 'word-break': 'keep-all' }], 95 | ] 96 | 97 | export const textOverflows: Rule[] = [ 98 | ['truncate', { 'overflow': 'hidden', 'text-overflow': 'ellipsis', 'white-space': 'nowrap' }], 99 | ['text-ellipsis', { 'text-overflow': 'ellipsis' }], 100 | ['text-clip', { 'text-overflow': 'clip' }], 101 | ] 102 | 103 | export const textTransforms: Rule[] = [ 104 | ['case-upper', { 'text-transform': 'uppercase' }], 105 | ['case-lower', { 'text-transform': 'lowercase' }], 106 | ['case-capital', { 'text-transform': 'capitalize' }], 107 | ['case-normal', { 'text-transform': 'none' }], 108 | ...makeGlobalStaticRules('case', 'text-transform'), 109 | ] 110 | 111 | export const fontStyles: Rule[] = [ 112 | ['italic', { 'font-style': 'italic' }], 113 | ['not-italic', { 'font-style': 'normal' }], 114 | ['font-italic', { 'font-style': 'italic' }], 115 | ['font-not-italic', { 'font-style': 'normal' }], 116 | ['oblique', { 'font-style': 'oblique' }], 117 | ['not-oblique', { 'font-style': 'normal' }], 118 | ['font-oblique', { 'font-style': 'oblique' }], 119 | ['font-not-oblique', { 'font-style': 'normal' }], 120 | ] 121 | 122 | export const fontSmoothings: Rule[] = [ 123 | ['antialiased', { 124 | '-webkit-font-smoothing': 'antialiased', 125 | '-moz-osx-font-smoothing': 'grayscale', 126 | 'font-smoothing': 'grayscale', 127 | }], 128 | ['subpixel-antialiased', { 129 | '-webkit-font-smoothing': 'auto', 130 | '-moz-osx-font-smoothing': 'auto', 131 | 'font-smoothing': 'auto', 132 | }], 133 | ] 134 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/transform.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { handler as h } from '../utils' 3 | 4 | export const transforms: Rule[] = [ 5 | // base 6 | [/transform-(.*)$/, ([_, str]) => { 7 | return { transform: h.bracket(str) || str }; 8 | }], 9 | ['transform-none', { transform: '' }], 10 | ] 11 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/transition.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import type { Theme } from '../theme' 3 | import { globalKeywords, handler as h, makeGlobalStaticRules } from '../utils' 4 | 5 | const transitionPropertyGroup: Record = { 6 | all: 'all', 7 | colors: ['color', 'background-color', 'border-color', 'outline-color', 'text-decoration-color', 'fill', 'stroke'].join(','), 8 | none: 'none', 9 | opacity: 'opacity', 10 | shadow: 'box-shadow', 11 | transform: 'transform', 12 | } 13 | 14 | const transitionProperty = (prop: string): string | undefined => { 15 | return h.properties(prop) ?? transitionPropertyGroup[prop] 16 | } 17 | 18 | export const transitions: Rule[] = [ 19 | // transition 20 | [/^transition(?:-([a-z-]+(?:,[a-z-]+)*))?(?:-(\d+))?$/, ([, prop, d], { theme }) => { 21 | const p = prop != null 22 | ? transitionProperty(prop) 23 | : [transitionPropertyGroup.colors, 'opacity', 'box-shadow', 'transform', 'filter', 'backdrop-filter'].join(',') 24 | if (p) { 25 | const duration = theme.duration?.[d || 'DEFAULT'] ?? h.time(d || '150') 26 | return { 27 | 'transition-property': p, 28 | 'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)', 29 | 'transition-duration': duration, 30 | } 31 | } 32 | }, { autocomplete: `transition-(${Object.keys(transitionPropertyGroup).join('|')})` }], 33 | 34 | // timings 35 | [/^(?:transition-)?duration-(.+)$/, 36 | ([, d], { theme }) => ({ 'transition-duration': theme.duration?.[d || 'DEFAULT'] ?? h.bracket.cssvar.time(d) }), 37 | { autocomplete: ['transition-duration-$duration', 'duration-$duration'] }], 38 | 39 | [/^(?:transition-)?delay-(.+)$/, 40 | ([, d], { theme }) => ({ 'transition-delay': theme.duration?.[d || 'DEFAULT'] ?? h.bracket.cssvar.time(d) }), 41 | { autocomplete: ['transition-delay-$duration', 'delay-$duration'] }], 42 | 43 | [/^(?:transition-)?ease(?:-(.+))?$/, 44 | ([, d], { theme }) => ({ 'transition-timing-function': theme.easing?.[d || 'DEFAULT'] ?? h.bracket.cssvar(d) }), 45 | { autocomplete: ['transition-ease-(linear|in|out|in-out|DEFAULT)', 'ease-(linear|in|out|in-out|DEFAULT)'] }], 46 | 47 | // props 48 | [/^(?:transition-)?property-(.+)$/, 49 | ([, v]) => ({ 'transition-property': h.bracket.global(v) || transitionProperty(v) }), 50 | { autocomplete: [`transition-property-(${[...globalKeywords, ...Object.keys(transitionPropertyGroup)].join('|')})`] }], 51 | 52 | // none 53 | ['transition-none', { transition: 'none' }], 54 | ...makeGlobalStaticRules('transition'), 55 | ] 56 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/typography.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { toArray } from '@unocss/core' 3 | import type { Theme } from '../theme' 4 | import { colorResolver, colorableShadows, handler as h, splitShorthand } from '../utils' 5 | 6 | const weightMap: Record = { 7 | thin: '100', 8 | extralight: '200', 9 | light: '300', 10 | normal: '400', 11 | medium: '500', 12 | semibold: '600', 13 | bold: '700', 14 | extrabold: '800', 15 | black: '900', 16 | // int[0, 900] -> int 17 | } 18 | 19 | function handleLineHeight(s: string, theme: Theme) { 20 | return theme.lineHeight?.[s] || h.bracket.cssvar.global.rem(s) 21 | } 22 | 23 | export const fonts: Rule[] = [ 24 | // family 25 | [ 26 | /^font-(.+)$/, 27 | ([, d], { theme }) => ({ 'font-family': theme.fontFamily?.[d] || h.bracket.cssvar.global(d) }), 28 | { autocomplete: 'font-$fontFamily' }, 29 | ], 30 | 31 | // size 32 | [ 33 | /^text-(.+)$/, 34 | ([, s = 'base'], { theme }) => { 35 | const [size, leading] = splitShorthand(s, 'length') 36 | const sizePairs = toArray(theme.fontSize?.[size]) 37 | const lineHeight = leading ? handleLineHeight(leading, theme) : undefined 38 | 39 | if (sizePairs?.[0]) { 40 | const [fontSize] = sizePairs 41 | return { 'font-size': fontSize } 42 | } 43 | 44 | const fontSize = h.bracketOfLength.rem(size) 45 | if (lineHeight && fontSize) { 46 | return { 47 | 'font-size': fontSize, 48 | 'line-height': lineHeight, 49 | } 50 | } 51 | 52 | return { 'font-size': h.bracketOfLength.rem(s) } 53 | }, 54 | { autocomplete: 'text-$fontSize' }, 55 | ], 56 | [/^text-size-(.+)$/, ([, s], { theme }) => { 57 | const themed = toArray(theme.fontSize?.[s]) 58 | const size = themed?.[0] ?? h.bracket.cssvar.global.rem(s) 59 | if (size != null) 60 | return { 'font-size': size } 61 | }, { autocomplete: 'text-size-$fontSize' }], 62 | 63 | // weights 64 | [ 65 | /^(?:font|fw)-?([^-]+)$/, 66 | ([, s]) => ({ 'font-weight': weightMap[s] || h.global.number(s) }), 67 | { autocomplete: `(font|fw)-(100|200|300|400|500|600|700|800|900|${Object.keys(weightMap).join('|')})` }, 68 | ], 69 | 70 | // leadings 71 | [ 72 | /^(?:font-)?(?:leading|lh)-(.+)$/, 73 | ([, s], { theme }) => ({ 'line-height': handleLineHeight(s, theme) }), 74 | { autocomplete: '(leading|lh)-$lineHeight' }, 75 | ], 76 | 77 | // synthesis 78 | ['font-synthesis-weight', { 'font-synthesis': 'weight' }], 79 | ['font-synthesis-style', { 'font-synthesis': 'style' }], 80 | ['font-synthesis-small-caps', { 'font-synthesis': 'small-caps' }], 81 | ['font-synthesis-none', { 'font-synthesis': 'none' }], 82 | [/^font-synthesis-(.+)$/, ([, s]) => ({ 'font-synthesis': h.bracket.cssvar.global(s) })], 83 | 84 | // tracking 85 | [ 86 | /^(?:font-)?tracking-(.+)$/, 87 | ([, s], { theme }) => ({ 'letter-spacing': theme.letterSpacing?.[s] || h.bracket.cssvar.global.rem(s) }), 88 | { autocomplete: 'tracking-$letterSpacing' }, 89 | ], 90 | 91 | // word-spacing 92 | [ 93 | /^(?:font-)?word-spacing-(.+)$/, 94 | ([, s], { theme }) => ({ 'word-spacing': theme.wordSpacing?.[s] || h.bracket.cssvar.global.rem(s) }), 95 | { autocomplete: 'word-spacing-$wordSpacing' }, 96 | ], 97 | ] 98 | 99 | export const tabSizes: Rule[] = [ 100 | [/^tab(?:-(.+))?$/, ([, s]) => { 101 | const v = h.bracket.cssvar.global.number(s || '4') 102 | if (v != null) { 103 | return { 104 | '-moz-tab-size': v, 105 | '-o-tab-size': v, 106 | 'tab-size': v, 107 | } 108 | } 109 | }], 110 | ] 111 | 112 | export const textIndents: Rule[] = [ 113 | [/^indent(?:-(.+))?$/, ([, s], { theme }) => ({ 'text-indent': theme.textIndent?.[s || 'DEFAULT'] || h.bracket.cssvar.global.fraction.rem(s) }), { autocomplete: 'indent-$textIndent' }], 114 | ] 115 | 116 | export const textStrokes: Rule[] = [ 117 | // widths 118 | [/^text-stroke(?:-(.+))?$/, ([, s], { theme }) => ({ '-webkit-text-stroke-width': theme.textStrokeWidth?.[s || 'DEFAULT'] || h.bracket.cssvar.px(s) }), { autocomplete: 'text-stroke-$textStrokeWidth' }], 119 | 120 | // colors 121 | [/^text-stroke-(.+)$/, colorResolver('-webkit-text-stroke-color', 'text-stroke'), { autocomplete: 'text-stroke-$colors' }], 122 | [/^text-stroke-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-text-stroke-opacity': h.bracket.percent(opacity) }), { autocomplete: 'text-stroke-(op|opacity)-' }], 123 | ] 124 | 125 | export const textShadows: Rule[] = [ 126 | [/^text-shadow(?:-(.+))?$/, ([, s], { theme }) => { 127 | const v = theme.textShadow?.[s || 'DEFAULT'] 128 | if (v != null) { 129 | return { 130 | '--un-text-shadow': colorableShadows(v, '--un-text-shadow-color').join(','), 131 | 'text-shadow': 'var(--un-text-shadow)', 132 | } 133 | } 134 | return { 'text-shadow': h.bracket.cssvar.global(s) } 135 | }, { autocomplete: 'text-shadow-$textShadow' }], 136 | 137 | // colors 138 | [/^text-shadow-color-(.+)$/, colorResolver('--un-text-shadow-color', 'text-shadow'), { autocomplete: 'text-shadow-color-$colors' }], 139 | [/^text-shadow-color-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-text-shadow-opacity': h.bracket.percent(opacity) }), { autocomplete: 'text-shadow-color-(op|opacity)-' }], 140 | ] 141 | -------------------------------------------------------------------------------- /src/preset-react-native/rules/variables.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from '@unocss/core' 2 | import { handler as h } from '../utils' 3 | 4 | const variablesAbbrMap: Record = { 5 | backface: 'backface-visibility', 6 | break: 'word-break', 7 | case: 'text-transform', 8 | content: 'align-content', 9 | fw: 'font-weight', 10 | items: 'align-items', 11 | justify: 'justify-content', 12 | select: 'user-select', 13 | self: 'align-self', 14 | vertical: 'vertical-align', 15 | visible: 'visibility', 16 | whitespace: 'white-space', 17 | ws: 'white-space', 18 | } 19 | 20 | export const cssVariables: Rule[] = [ 21 | [/^(.+?)-(\$.+)$/, ([, name, varname]) => { 22 | const prop = variablesAbbrMap[name] 23 | if (prop) 24 | return { [prop]: h.cssvar(varname) } 25 | }], 26 | ] 27 | 28 | export const cssProperty: Rule[] = [ 29 | [/^\[(--(\w|\\\W)+|[\w-]+):([^:].*)\]$/, ([match, prop,, value]) => { 30 | if (!isURI(match.slice(1, -1))) 31 | return { [prop]: h.bracket(`[${value}]`) } 32 | }], 33 | ] 34 | 35 | function isURI(declaration: string) { 36 | if (!declaration.includes('://')) 37 | return false 38 | 39 | try { 40 | return new URL(declaration).host !== '' 41 | } 42 | catch (err) { 43 | return false 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/preset-react-native/theme.ts: -------------------------------------------------------------------------------- 1 | export * from './_theme/index' 2 | -------------------------------------------------------------------------------- /src/preset-react-native/utils.ts: -------------------------------------------------------------------------------- 1 | export * from './_utils/index' 2 | -------------------------------------------------------------------------------- /src/preset.ts: -------------------------------------------------------------------------------- 1 | import { presetReactNative } from './preset-react-native'; 2 | import remToPxPreset from './transformer/style-processor'; 3 | 4 | export const preset = [presetReactNative(), remToPxPreset()]; 5 | -------------------------------------------------------------------------------- /src/transformer/index.ts: -------------------------------------------------------------------------------- 1 | import styleTransformer from './style-transformer'; 2 | import svgTransformer from './svg-transformer'; 3 | 4 | export const pipeline = [styleTransformer, svgTransformer]; 5 | 6 | export default async function transform( 7 | source: string, 8 | context: { projectRoot: string } 9 | ) { 10 | let result = source; 11 | for (const trans of pipeline) { 12 | result = await trans(result, context); 13 | } 14 | return result; 15 | } 16 | 17 | export { styleTransformer, svgTransformer }; 18 | -------------------------------------------------------------------------------- /src/transformer/style-processor.ts: -------------------------------------------------------------------------------- 1 | import { loadConfig } from '@unocss/config'; 2 | import transform from 'css-to-react-native'; 3 | import cssom from 'cssom'; 4 | import { Preset, UnoGenerator } from '@unocss/core'; 5 | import { presetReactNative } from '../preset-react-native'; 6 | 7 | const remRE = /(-?[\.\d]+)rem/g; 8 | 9 | export interface RemToPxOptions { 10 | /** 11 | * 1rem = n px 12 | * @default 16 13 | */ 14 | baseFontSize?: number; 15 | } 16 | export default function remToPxPreset(options: RemToPxOptions = {}): Preset { 17 | const { baseFontSize = 16 } = options; 18 | 19 | return { 20 | name: '@unocss/preset-rem-to-px', 21 | postprocess: (util) => { 22 | util.entries.forEach((i) => { 23 | const value = i[1]; 24 | if (value && typeof value === 'string' && remRE.test(value)) 25 | i[1] = value.replace(remRE, (_, p1) => `${p1 * baseFontSize}px`); 26 | }); 27 | }, 28 | }; 29 | } 30 | 31 | export const preset = [presetReactNative(), remToPxPreset()]; 32 | 33 | function toTuple(style: any) { 34 | const tuple: [string, string][] = []; 35 | for (let i = 0; i < style.length; i++) { 36 | const key = style[i]; 37 | const value = style.getPropertyValue(key); 38 | tuple.push([key, value]); 39 | } 40 | 41 | return tuple; 42 | } 43 | 44 | class StyleSheet { 45 | private styleSheet: Record = {}; 46 | add(rule: string, sheet: any) { 47 | // 因为不是 css规则,所以不需要转义 48 | this.styleSheet[rule.replaceAll('\\', '')] = sheet; 49 | } 50 | get text() { 51 | return JSON.stringify(this.styleSheet); 52 | } 53 | get sheet() { 54 | return this.styleSheet; 55 | } 56 | get size() { 57 | return Object.keys(this.styleSheet).length; 58 | } 59 | } 60 | 61 | function uniq(arr: any[]) { 62 | const result: any[] = []; 63 | for (const item of arr) { 64 | if (!result.includes(item)) result.push(item); 65 | } 66 | 67 | return result; 68 | } 69 | 70 | export async function loadUnoConfig(workdir: string) { 71 | const defaultConfig = { presets: preset }; 72 | if (!workdir) return defaultConfig; 73 | 74 | const { config, sources } = await loadConfig(workdir); 75 | if (!sources.length) { 76 | return defaultConfig; 77 | } 78 | 79 | config.presets ??= []; 80 | // @ts-ignore 81 | config.presets = uniq([...config.presets, ...preset]); 82 | 83 | return config; 84 | } 85 | 86 | let _generator: UnoGenerator; 87 | export async function resolveGenerator(workdir: string) { 88 | if (process.env.NODE_ENV !== 'test' && _generator) { 89 | return _generator; 90 | } 91 | 92 | const config = await loadUnoConfig(workdir); 93 | // @ts-ignore 94 | _generator = new UnoGenerator(config); 95 | return _generator; 96 | } 97 | 98 | export async function genStyle(source: string, workdir: string = '') { 99 | const generator = await resolveGenerator(workdir); 100 | const tokens = await generator.applyExtractors(source); 101 | const result = await generator.generate(tokens); 102 | const ast = cssom.parse(result.css); 103 | 104 | const styleSheet = new StyleSheet(); 105 | 106 | for (const rule of ast.cssRules) { 107 | for (const selector of rule.selectorText.split(',')) { 108 | let _select = selector.trim().replace(/^./, ''); 109 | styleSheet.add(_select, transform(toTuple(rule.style))); 110 | } 111 | } 112 | 113 | return styleSheet; 114 | } 115 | -------------------------------------------------------------------------------- /src/transformer/style-transformer.ts: -------------------------------------------------------------------------------- 1 | import { genStyle } from './style-processor'; 2 | 3 | export default async function styleTransformer( 4 | source: string, 5 | context: { projectRoot: string } 6 | ): Promise { 7 | const style = await genStyle(source, context.projectRoot); 8 | if (!style.size) return source; 9 | 10 | const buf = ['import __unonative__ from "unonative"']; 11 | buf.push(source); 12 | buf.push(`__unonative__.register(${style.text})`); 13 | return buf.join('\n'); 14 | } 15 | -------------------------------------------------------------------------------- /src/transformer/svg-transformer.ts: -------------------------------------------------------------------------------- 1 | import { loadNodeIcon } from '@iconify/utils/lib/loader/node-loader'; 2 | const collections = [ 3 | 'academicons', 4 | 'akar-icons', 5 | 'ant-design', 6 | 'arcticons', 7 | 'basil', 8 | 'bi', 9 | 'bpmn', 10 | 'brandico', 11 | 'bx', 12 | 'bxl', 13 | 'bxs', 14 | 'bytesize', 15 | 'carbon', 16 | 'charm', 17 | 'ci', 18 | 'cib', 19 | 'cif', 20 | 'cil', 21 | 'circle-flags', 22 | 'circum', 23 | 'clarity', 24 | 'codicon', 25 | 'cryptocurrency-color', 26 | 'cryptocurrency', 27 | 'dashicons', 28 | 'ei', 29 | 'el', 30 | 'emblemicons', 31 | 'emojione-monotone', 32 | 'emojione-v1', 33 | 'emojione', 34 | 'entypo-social', 35 | 'entypo', 36 | 'eos-icons', 37 | 'ep', 38 | 'et', 39 | 'eva', 40 | 'fa-brands', 41 | 'fa-regular', 42 | 'fa-solid', 43 | 'fa', 44 | 'fa6-brands', 45 | 'fa6-regular', 46 | 'fa6-solid', 47 | 'fad', 48 | 'fe', 49 | 'feather', 50 | 'file-icons', 51 | 'flag', 52 | 'flagpack', 53 | 'flat-color-icons', 54 | 'flat-ui', 55 | 'fluent-emoji-flat', 56 | 'fluent-emoji-high-contrast', 57 | 'fluent-emoji', 58 | 'fluent-mdl2', 59 | 'fluent', 60 | 'fontelico', 61 | 'fontisto', 62 | 'foundation', 63 | 'fxemoji', 64 | 'gala', 65 | 'game-icons', 66 | 'geo', 67 | 'gg', 68 | 'gis', 69 | 'gridicons', 70 | 'grommet-icons', 71 | 'healthicons', 72 | 'heroicons-outline', 73 | 'heroicons-solid', 74 | 'heroicons', 75 | 'humbleicons', 76 | 'ic', 77 | 'icomoon-free', 78 | 'icon-park-outline', 79 | 'icon-park-solid', 80 | 'icon-park-twotone', 81 | 'icon-park', 82 | 'iconoir', 83 | 'icons8', 84 | 'il', 85 | 'ion', 86 | 'iwwa', 87 | 'jam', 88 | 'la', 89 | 'line-md', 90 | 'logos', 91 | 'ls', 92 | 'lucide', 93 | 'majesticons', 94 | 'maki', 95 | 'map', 96 | 'material-symbols', 97 | 'mdi-light', 98 | 'mdi', 99 | 'medical-icon', 100 | 'memory', 101 | 'mi', 102 | 'mingcute', 103 | 'mono-icons', 104 | 'nimbus', 105 | 'nonicons', 106 | 'noto-v1', 107 | 'noto', 108 | 'octicon', 109 | 'oi', 110 | 'ooui', 111 | 'openmoji', 112 | 'pajamas', 113 | 'pepicons-pop', 114 | 'pepicons-print', 115 | 'pepicons', 116 | 'ph', 117 | 'pixelarticons', 118 | 'prime', 119 | 'ps', 120 | 'quill', 121 | 'radix-icons', 122 | 'raphael', 123 | 'ri', 124 | 'si-glyph', 125 | 'simple-icons', 126 | 'simple-line-icons', 127 | 'skill-icons', 128 | 'subway', 129 | 'svg-spinners', 130 | 'system-uicons', 131 | 'tabler', 132 | 'teenyicons', 133 | 'topcoat', 134 | 'twemoji', 135 | 'typcn', 136 | 'uil', 137 | 'uim', 138 | 'uis', 139 | 'uit', 140 | 'uiw', 141 | 'vaadin', 142 | 'vs', 143 | 'vscode-icons', 144 | 'websymbol', 145 | 'whh', 146 | 'wi', 147 | 'wpf', 148 | 'zmdi', 149 | 'zondicons', 150 | ]; 151 | 152 | export default async function svgTransformer(source: string) { 153 | const tokens: string[] = []; 154 | 155 | source.replace(/icon=["'](.*?)["']/g, (matched, group) => { 156 | tokens.push(group); 157 | return matched; 158 | }); 159 | if (!tokens.length) return source; 160 | 161 | const parsedToken = tokens.map((token) => { 162 | // i-[icon set]-[...icon names] 163 | const [collection, ...rest] = token.split('-'); 164 | if (!collections.includes(collection)) return null; 165 | return [collection.trim(), rest.join('-').trim()]; 166 | }); 167 | 168 | const xmlStrings = await Promise.all( 169 | parsedToken.map(async (v) => { 170 | if (!v) return undefined; 171 | 172 | const [collection, icon] = v; 173 | return loadNodeIcon(collection, icon); 174 | }) 175 | ); 176 | 177 | return source.replace(/icon=["'](.*?)["']/g, (matched, group) => { 178 | const xmlString = xmlStrings.shift(); 179 | if (!xmlString) return matched; 180 | 181 | return `icon='${xmlString}'`; 182 | }); 183 | } 184 | -------------------------------------------------------------------------------- /src/transformerEntry.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import upstreamTransformer from 'metro-react-native-babel-transformer'; 3 | import transform from './transformer'; 4 | 5 | const unoTransformer = { 6 | async transform(info: any) { 7 | let { filename, options, src, plugins } = info; 8 | if (!filename.startsWith('node_modules')) { 9 | src = await transform(src, options); 10 | } 11 | return upstreamTransformer.transform({ filename, options, src, plugins }); 12 | }, 13 | }; 14 | 15 | export = unoTransformer; 16 | -------------------------------------------------------------------------------- /src/type.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'cssom' { 2 | interface Ast { 3 | cssRules: { 4 | selectorText: string; 5 | style: { cssText: string }; 6 | }[]; 7 | } 8 | 9 | function parse(str: string): Ast; 10 | 11 | export { parse }; 12 | } 13 | 14 | declare module "@babel/helper-module-imports" { 15 | export function addNamed(path: unknown, name: string, source: string): void; 16 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "esModuleInterop": true, 5 | "target": "ESNext", 6 | "moduleResolution": "node", 7 | "sourceMap": true, 8 | "outDir": "dist", 9 | "lib": ["ESNext"], 10 | "forceConsistentCasingInFileNames": true, 11 | "strict": true, 12 | "jsx": "react-native" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ 5 | 'src/index.ts', 6 | 'src/transformerEntry.ts', 7 | 'src/preset.ts', 8 | 'src/babel.ts', 9 | ], 10 | splitting: false, 11 | sourcemap: false, 12 | clean: true, 13 | dts: true, 14 | format: ['cjs', 'esm'], 15 | external: [ 16 | 'metro-react-native-babel-transformer', 17 | 'react', 18 | 'react-native', 19 | 'react-native-svg', 20 | '@babel/helper-module-imports', 21 | ], 22 | }); 23 | -------------------------------------------------------------------------------- /type.d.ts: -------------------------------------------------------------------------------- 1 | import "react-native"; 2 | import type { VirtualizedListProps } from "react-native"; 3 | 4 | declare module "react-native" { 5 | type ClassNameValue = string | number | boolean | undefined | null; 6 | type ClassNameMapping = Record; 7 | interface ClassNameArgumentArray extends Array {} 8 | type ClassList = ClassNameValue | ClassNameMapping | ClassNameArgumentArray; 9 | 10 | interface FlatListProps extends VirtualizedListProps { 11 | className?: string; 12 | classList?: ClassList; 13 | } 14 | 15 | interface ImagePropsBase { 16 | className?: string; 17 | classList?: ClassList; 18 | } 19 | 20 | interface ViewProps { 21 | className?: string; 22 | classList?: ClassList; 23 | } 24 | 25 | interface TextProps { 26 | className?: string; 27 | classList?: ClassList; 28 | } 29 | 30 | interface SwitchProps { 31 | className?: string; 32 | classList?: ClassList; 33 | } 34 | 35 | interface InputAccessoryViewProps { 36 | className?: string; 37 | classList?: ClassList; 38 | } 39 | 40 | interface TouchableWithoutFeedbackProps { 41 | className?: string; 42 | classList?: ClassList; 43 | } 44 | 45 | type UnoClass = { 46 | className?: string; 47 | classList?: ClassList; 48 | } & T; 49 | } 50 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | // ... 6 | } 7 | }) 8 | --------------------------------------------------------------------------------