├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── CHANGELOG.md ├── LICENSE.md ├── biome.json ├── examples ├── date_json-serializer.js ├── date_json.js ├── flat.js ├── inspect.js ├── json-serializer.js ├── simple.js └── test.js ├── index.mjs ├── package.json ├── parse.d.ts ├── parse.js ├── pnpm-lock.yaml ├── readme.md ├── readme.template.md ├── src ├── parse.ts ├── stringify.ts ├── types.ts └── utils │ ├── isCallable.ts │ ├── isKeyDotNotationCompatible.ts │ ├── isObject.ts │ ├── isReactElement.ts │ └── replacerWithPath.ts ├── stringify.d.ts ├── stringify.js ├── test ├── error-handling.spec.js ├── misc.spec.js ├── serialize.spec.js └── user-defined-replacer.spec.ts ├── tsconfig.cjs.json └── tsconfig.json /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: pnpm/action-setup@v4 13 | with: 14 | version: 10.11.0 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: 22 18 | cache: "pnpm" 19 | - run: pnpm install 20 | - run: pnpm run build 21 | - run: pnpm run test 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /dist/ 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | examples/ 2 | *.template.md 3 | !dist/ 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | semi: false 2 | tabWidth: 2 3 | singleQuote: true 4 | printWidth: 120 5 | trailingComma: all 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.5.15](https://github.com/brillout/json-serializer/compare/v0.5.14...v0.5.15) (2024-12-09) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * workaround unexpected Node.js condition resolving (fix vikejs/vike[#2016](https://github.com/brillout/json-serializer/issues/2016)) ([f0caec5](https://github.com/brillout/json-serializer/commit/f0caec5fc7263655ace432d7812ba348035f10ab)) 7 | 8 | 9 | 10 | ## [0.5.14](https://github.com/brillout/json-serializer/compare/v0.5.13...v0.5.14) (2024-12-09) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * improve exports conditions ([#14](https://github.com/brillout/json-serializer/issues/14)) ([85ca88d](https://github.com/brillout/json-serializer/commit/85ca88d6d0bedaa17a023f76478a8afae1dfbaa8)) 16 | 17 | 18 | 19 | ## [0.5.13](https://github.com/brillout/json-serializer/compare/v0.5.12...v0.5.13) (2024-07-10) 20 | 21 | 22 | ### Bug Fixes 23 | 24 | * fix pathString ([83a0bc8](https://github.com/brillout/json-serializer/commit/83a0bc8847d192ec40cef1dc322818e0af228957)) 25 | 26 | 27 | 28 | ## [0.5.12](https://github.com/brillout/json-serializer/compare/v0.5.11...v0.5.12) (2024-07-10) 29 | 30 | 31 | ### Bug Fixes 32 | 33 | * improve messageCore type ([0bcf56e](https://github.com/brillout/json-serializer/commit/0bcf56e238064dd0146d151051fadc7e26408441)) 34 | * pass more usefull pathString value ([eb063d6](https://github.com/brillout/json-serializer/commit/eb063d6ee9fe6729a45e4b6a3b06bd0c4a38e04c)) 35 | 36 | 37 | ### Features 38 | 39 | * add subjectName to serialization error object ([7220453](https://github.com/brillout/json-serializer/commit/72204538f347b05df362047c1b01cc3fc392b44b)) 40 | 41 | 42 | 43 | ## [0.5.11](https://github.com/brillout/json-serializer/compare/v0.5.10...v0.5.11) (2024-07-10) 44 | 45 | 46 | ### Bug Fixes 47 | 48 | * stop passing pathString to user-land replacer ([3d4fd16](https://github.com/brillout/json-serializer/commit/3d4fd161aa7a4854dd2f8c557884f132f09fa623)) 49 | 50 | 51 | ### Features 52 | 53 | * add more information to serializatoin error object ([d173e8a](https://github.com/brillout/json-serializer/commit/d173e8a0cd0d3a7af42e8cea5c2e6d7610f4c21a)) 54 | 55 | 56 | ### BREAKING CHANGES 57 | 58 | * `replacer()` doesn't recevied the `pathString` argument anymore: 59 | ```diff 60 | stringify(something, { 61 | - replacer(key, val, pathString) { 62 | + replacer(key, val) { 63 | // ... 64 | } 65 | } 66 | ``` 67 | 68 | 69 | 70 | ## [0.5.10](https://github.com/brillout/json-serializer/compare/v0.5.9...v0.5.10) (2024-05-02) 71 | 72 | 73 | ### Features 74 | 75 | * expose parseTransform() ([481e63c](https://github.com/brillout/json-serializer/commit/481e63cf16462bb037e28a2baa63837a8aff150f)) 76 | 77 | 78 | 79 | ## [0.5.9](https://github.com/brillout/json-serializer/compare/v0.5.8...v0.5.9) (2024-05-02) 80 | 81 | 82 | ### Features 83 | 84 | * user-defined replacer ([76ddf95](https://github.com/brillout/json-serializer/commit/76ddf95cdfe36c39b99400a41bc22d2f243ed5c4)) 85 | 86 | 87 | 88 | ## [0.5.8](https://github.com/brillout/json-serializer/compare/v0.5.7...v0.5.8) (2023-11-02) 89 | 90 | 91 | ### Bug Fixes 92 | 93 | * type re-export ([21c56c0](https://github.com/brillout/json-serializer/commit/21c56c04058f3096529366ad140b61231dcdabda)) 94 | 95 | 96 | 97 | ## [0.5.7](https://github.com/brillout/json-serializer/compare/v0.5.6...v0.5.7) (2023-11-02) 98 | 99 | 100 | ### Features 101 | 102 | * isJsonSerializerError() (vikejs/vike[#1232](https://github.com/brillout/json-serializer/issues/1232)) ([1e3509e](https://github.com/brillout/json-serializer/commit/1e3509e7dade243d1f79bf4445433e5713c6562e)) 103 | 104 | 105 | 106 | ## [0.5.6](https://github.com/brillout/json-serializer/compare/v0.5.5...v0.5.6) (2023-09-03) 107 | 108 | 109 | ### Bug Fixes 110 | 111 | * make error messages prettier ([313bb24](https://github.com/brillout/json-serializer/commit/313bb2457c5efb070ff6359bfc31688657f306eb)) 112 | * make error messages prettier ([a448408](https://github.com/brillout/json-serializer/commit/a448408c2eec3e1cc70cc56f0d811a7babb26021)) 113 | * make error messages prettier ([e4b5781](https://github.com/brillout/json-serializer/commit/e4b578126f40d065b03818ac65256e633da1c31d)) 114 | * make paths prettier ([1d04319](https://github.com/brillout/json-serializer/commit/1d043190e0269242c28033a6edff72bbdf3a8bed)) 115 | * object value path in error messages ([5d9f0dd](https://github.com/brillout/json-serializer/commit/5d9f0dd908a3125173ba3e9ab96fde41cf863a9a)) 116 | 117 | 118 | ### Features 119 | 120 | * make error message core available at err.messageCore ([3d08d57](https://github.com/brillout/json-serializer/commit/3d08d5747939b85a67b94b11ecb11e0b1bf77083)) 121 | 122 | 123 | 124 | ## [0.5.5](https://github.com/brillout/json-serializer/compare/v0.5.4...v0.5.5) (2023-08-26) 125 | 126 | 127 | ### Bug Fixes 128 | 129 | * add License to package.json ([b3ef4c4](https://github.com/brillout/json-serializer/commit/b3ef4c4a149d346fa8b00d5210ef67c8df2da7c3)) 130 | 131 | 132 | 133 | ## [0.5.4](https://github.com/brillout/json-serializer/compare/v0.5.3...v0.5.4) (2023-07-15) 134 | 135 | 136 | ### Bug Fixes 137 | 138 | * improve serialization error message ([19a18ca](https://github.com/brillout/json-serializer/commit/19a18ca30f3224d85cb920cd58725f48c429ad5d)) 139 | 140 | 141 | 142 | ## [0.5.3](https://github.com/brillout/json-serializer/compare/v0.5.2...v0.5.3) (2022-11-03) 143 | 144 | 145 | ### Bug Fixes 146 | 147 | * add index.mjs to npm package ([#9](https://github.com/brillout/json-serializer/issues/9)) ([df5b103](https://github.com/brillout/json-serializer/commit/df5b103778c86523e736d2fe3bf11c81411afd41)) 148 | 149 | 150 | 151 | ## [0.5.2](https://github.com/brillout/json-serializer/compare/v0.5.1...v0.5.2) (2022-11-03) 152 | 153 | 154 | ### Bug Fixes 155 | 156 | * workaround Vite SSR externalizing bug ([a26b069](https://github.com/brillout/json-serializer/commit/a26b0698972b3b27e92a50bf84421e22ff2ec1e6)) 157 | 158 | 159 | 160 | ## [0.5.1](https://github.com/brillout/json-serializer/compare/v0.5.0...v0.5.1) (2022-09-03) 161 | 162 | 163 | ### Bug Fixes 164 | 165 | * fix TypeScript types ([f599ac6](https://github.com/brillout/json-serializer/commit/f599ac661a9f57703c21fc2d5b395705b7571799)) 166 | 167 | 168 | 169 | # [0.5.0](https://github.com/brillout/json-serializer/compare/v0.4.6...v0.5.0) (2022-09-02) 170 | 171 | 172 | * perf!: forbid loading both `parse()` and `stringify()` at the same time ([8365764](https://github.com/brillout/json-serializer/commit/8365764bd377fb2b1048e0266c92cdae54070dde)) 173 | 174 | 175 | ### Features 176 | 177 | * new option `sortObjectKeys` for stable hashing ([6579f21](https://github.com/brillout/json-serializer/commit/6579f214c731c1b1de8bbece05f01b5bcca34c4a)) 178 | 179 | 180 | ### BREAKING CHANGES 181 | 182 | * Module `@brillout/json-serializer` doesn't exist anymore: load `@brillout/json-serializer/parse` and `@brillout/json-serializer/stringify` instead. (To reduce loaded KBs on the browser-side.) 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-present Romuald Brillout 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", 3 | "files": { 4 | "ignore": ["dist/", "package.json"] 5 | }, 6 | "formatter": { 7 | "indentWidth": 2, 8 | "indentStyle": "space" 9 | }, 10 | "javascript": { 11 | "formatter": { 12 | "semicolons": "asNeeded", 13 | "lineWidth": 120, 14 | "quoteStyle": "single", 15 | "trailingComma": "all" 16 | } 17 | }, 18 | "linter": { 19 | "enabled": false 20 | }, 21 | "vcs": { 22 | "enabled": true, 23 | "clientKind": "git" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/date_json-serializer.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const { parse } = require('@brillout/json-serializer/parse') 3 | const { stringify } = require('@brillout/json-serializer/stringify') 4 | 5 | let obj = { 6 | time: new Date('2042-01-01'), 7 | } 8 | 9 | // `@brillout/json-serializer` preserves Date 10 | assert(obj.time.constructor === Date) 11 | obj = parse(stringify(obj)) 12 | assert(obj.time.constructor === Date) 13 | assert(obj.time.getTime() === new Date('2042-01-01').getTime()) 14 | -------------------------------------------------------------------------------- /examples/date_json.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | let obj = { 4 | time: new Date('2042-01-01'), 5 | } 6 | 7 | // JSON converts dates to strings 8 | assert(obj.time.constructor === Date) 9 | obj = JSON.parse(JSON.stringify(obj)) 10 | assert(obj.time.constructor === String) 11 | assert(obj.time === '2042-01-01T00:00:00.000Z') 12 | -------------------------------------------------------------------------------- /examples/flat.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const { parse } = require('@brillout/json-serializer/parse') 3 | const { stringify } = require('@brillout/json-serializer/stringify') 4 | 5 | let time = new Date('2042-01-01') 6 | 7 | // @brillout/json-serializer works on values directly 8 | assert(time.constructor === Date) 9 | time = parse(stringify(time)) 10 | assert(time.constructor === Date) 11 | assert(time.getTime() === new Date('2042-01-01').getTime()) 12 | -------------------------------------------------------------------------------- /examples/inspect.js: -------------------------------------------------------------------------------- 1 | const { stringify } = require('@brillout/json-serializer/stringify') 2 | 3 | const obj = { 4 | date: new Date(), 5 | undefined: undefined, 6 | collision: '!undefined', 7 | NaN: NaN, 8 | Infinity: Infinity, 9 | regexp: /^\d+$/g, 10 | } 11 | 12 | console.log(stringify(obj, undefined, 2)) 13 | // Prints: 14 | /* 15 | { 16 | "date": "!Date:2021-01-12T22:15:56.319Z", 17 | "undefined": "!undefined", 18 | "collision": "!!undefined" 19 | "NaN": "!NaN", 20 | "Infinity": "!Infinity", 21 | "regexp": "!RegExp:/^\\d+$/g" 22 | } 23 | */ 24 | -------------------------------------------------------------------------------- /examples/json-serializer.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const { parse } = require('@brillout/json-serializer/parse') 4 | const { stringify } = require('@brillout/json-serializer/stringify') 5 | 6 | const obj = { 7 | date: new Date(), 8 | undefined: undefined, 9 | NaN: NaN, 10 | Infinity: Infinity, 11 | regexp: /^\d+$/g, 12 | } 13 | 14 | // All of `obj` can be serialized with @brillout/json-serializer 15 | const obj2 = parse(stringify(obj)) 16 | assert(obj2.date.getTime() === obj.date.getTime()) 17 | assert(obj2.undefined === undefined && 'undefined' in obj2) 18 | assert(isNaN(obj2.NaN)) 19 | assert(obj2.Infinity === Infinity) 20 | assert(obj2.regexp.toString() === obj.regexp.toString()) 21 | 22 | // JSON cannot serialize any of `obj` 23 | const obj3 = JSON.parse(JSON.stringify(obj)) 24 | // JSON converts dates to strings 25 | assert(obj3.constructor !== Date) 26 | // JSON removes properties with a value of `undefined` 27 | assert(!('undefined' in obj3)) 28 | // JSON converts `NaN` to `null` 29 | assert(obj3.NaN === null) 30 | // JSON converts `Infinity` to `null` 31 | assert(obj3.Infinity === null) 32 | // JSON converts RegExp to an empty object 33 | assert(obj3.regexp.constructor === Object && Object.keys(obj3.regexp).length === 0) 34 | -------------------------------------------------------------------------------- /examples/simple.js: -------------------------------------------------------------------------------- 1 | // npm install @brillout/json-serializer 2 | const { parse } = require('@brillout/json-serializer/parse') 3 | const { stringify } = require('@brillout/json-serializer/stringify') 4 | 5 | const obj = { 6 | hello: 'from the future', 7 | time: new Date('2042-01-01'), 8 | } 9 | 10 | // Serialize with @brillout/json-serializer 11 | const obj_serialized = stringify(obj) 12 | 13 | // Deserialize a @brillout/json-serializer string 14 | const obj_deserialized = parse(obj_serialized) 15 | -------------------------------------------------------------------------------- /examples/test.js: -------------------------------------------------------------------------------- 1 | const util = require('util') 2 | const isEqual = require('lodash.isequal') 3 | const assert = require('assert') 4 | 5 | const { parse } = require('@brillout/json-serializer/parse') 6 | const { stringify } = require('@brillout/json-serializer/stringify') 7 | 8 | const original = { 9 | // types not supported by JSON 10 | date: new Date(), 11 | undefined: undefined, 12 | NaN: NaN, 13 | Infinity: Infinity, 14 | regexp: /^\d+.*(a|b)$/gi, 15 | 16 | // types supported by JSON 17 | sub: { 18 | obj: { 19 | null: null, 20 | false: false, 21 | true: true, 22 | arr: [1, 'two', undefined, null, { subi: [1] }], 23 | str: 'A string', 24 | n: 1337, 25 | }, 26 | }, 27 | } 28 | 29 | const serialized = stringify(original, { space: 2 }) 30 | const deserialized = parse(serialized) 31 | 32 | assert(isEqual(original, deserialized)) 33 | 34 | console.log('JSON serialized->deserialized.') 35 | console.log('(Note how we loose many values.)') 36 | console.log(JSON.parse(JSON.stringify(original))) 37 | console.log() 38 | 39 | console.log('@brillout/json-serializer serialized.') 40 | console.log(serialized) 41 | console.log() 42 | 43 | console.log('Original object.') 44 | logObj(original) 45 | console.log() 46 | 47 | console.log('@brillout/json-serializer serialized->deserialized.') 48 | console.log('(Note that all values are preserved and that this object is a clone of the original object.)') 49 | logObj(deserialized) 50 | 51 | function logObj(obj) { 52 | console.log(util.inspect(obj, { depth: Infinity, colors: true })) 53 | } 54 | -------------------------------------------------------------------------------- /index.mjs: -------------------------------------------------------------------------------- 1 | // This file is `.mjs` to workaround a Vite bug: 2 | // - Error originating from Vite: 3 | // ``` 4 | // @brillout/json-s doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix. 5 | // ``` 6 | // - Reproduction: https://github.com/brillout/sveltekit-telefunc-repro 7 | throw new Error( 8 | "Module `@brillout/json-serializer` doesn't exist anymore: load `@brillout/json-serializer/parse` and `@brillout/json-serializer/stringify` instead.", 9 | ) 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@brillout/json-serializer", 3 | "version": "0.5.15", 4 | "description": "Same as JSON but with added support for `Date`, `undefined`, `Map`, `Set`, and more.", 5 | "main": "./index.mjs", 6 | "exports": { 7 | ".": "./index.mjs", 8 | "./parse": { 9 | "node": "./dist/cjs/parse.js", 10 | "types": "./dist/esm/parse.d.ts", 11 | "default": "./dist/esm/parse.js" 12 | }, 13 | "./stringify": { 14 | "node": "./dist/cjs/stringify.js", 15 | "types": "./dist/esm/stringify.d.ts", 16 | "default": "./dist/esm/stringify.js" 17 | } 18 | }, 19 | "scripts": { 20 | "========= Dev": "", 21 | "dev": "pnpm run tsc:watch:cjs", 22 | "========= Build": "", 23 | "build": "rm -rf dist/ && pnpm run tsc:esm && pnpm run tsc:cjs", 24 | "tsc:esm": "tsc", 25 | "tsc:cjs": "tsc --project ./tsconfig.cjs.json", 26 | "tsc:watch:esm": "tsc --incremental --watch", 27 | "tsc:watch:cjs": "tsc --incremental --watch --project ./tsconfig.cjs.json", 28 | "========= Test": "", 29 | "test": "vitest", 30 | "========= Build readme.md": "", 31 | "docs": "mdocs", 32 | "========= Formatting": "", 33 | "format": "pnpm run format:biome", 34 | "format:prettier": "git ls-files | egrep '\\.(json|js|jsx|css|ts|tsx|vue|mjs|cjs)$' | grep --invert-match package.json | xargs pnpm exec prettier --write", 35 | "format:biome": "biome format --write .", 36 | "format:check": "biome format . || echo Fix formatting by running: $ pnpm -w run format", 37 | "========= Release": "", 38 | "release": "release-me patch", 39 | "========= Reset": "", 40 | "reset": "git clean -Xdf && pnpm install && pnpm run build" 41 | }, 42 | "devDependencies": { 43 | "@biomejs/biome": "^1.7.2", 44 | "@brillout/mdocs": "^0.1.30", 45 | "@brillout/release-me": "^0.3.8", 46 | "@types/node": "^20.5.6", 47 | "@types/react": "^18.2.21", 48 | "lodash.isequal": "^4.5.0", 49 | "prettier": "^3.2.5", 50 | "react": "^17.0.2", 51 | "typescript": "^5.2.2", 52 | "vitest": "^0.34.3" 53 | }, 54 | "// Use @vitest/snapshot PR https://github.com/vitest-dev/vitest/pull/3961": "", 55 | "pnpm": { 56 | "overrides": { 57 | "vitest>@vitest/snapshot": "npm:@brillout/vitest-snapshot@0.35.0-prerelease" 58 | } 59 | }, 60 | "files": [ 61 | "dist/", 62 | "*.d.ts", 63 | "*.mjs", 64 | "*.js" 65 | ], 66 | "repository": "github:brillout/json-serializer", 67 | "license": "MIT", 68 | "publishConfig": { 69 | "access": "public" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /parse.d.ts: -------------------------------------------------------------------------------- 1 | // Help TS's resolver until it supports `package.json#exports` 2 | export * from './dist/esm/parse' 3 | -------------------------------------------------------------------------------- /parse.js: -------------------------------------------------------------------------------- 1 | // Some tools don't support `package.json#exports`, such as: 2 | // - Nuxt v2 3 | // - Expo/Metro 4 | // - ESLint 5 | // prettier-ignore 6 | // biome-ignore format: 7 | 'use strict'; 8 | // prettier-ignore 9 | // biome-ignore format: 10 | exports.parse = require('./dist/cjs/parse.js').parse; 11 | exports.parseTransform = require('./dist/cjs/parse.js').parseTransform 12 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | overrides: 8 | vitest>@vitest/snapshot: npm:@brillout/vitest-snapshot@0.35.0-prerelease 9 | 10 | importers: 11 | 12 | .: 13 | devDependencies: 14 | '@biomejs/biome': 15 | specifier: ^1.7.2 16 | version: 1.7.2 17 | '@brillout/mdocs': 18 | specifier: ^0.1.30 19 | version: 0.1.30 20 | '@brillout/release-me': 21 | specifier: ^0.3.8 22 | version: 0.3.8 23 | '@types/node': 24 | specifier: ^20.5.6 25 | version: 20.5.6 26 | '@types/react': 27 | specifier: ^18.2.21 28 | version: 18.2.21 29 | lodash.isequal: 30 | specifier: ^4.5.0 31 | version: 4.5.0 32 | prettier: 33 | specifier: ^3.2.5 34 | version: 3.2.5 35 | react: 36 | specifier: ^17.0.2 37 | version: 17.0.2 38 | typescript: 39 | specifier: ^5.2.2 40 | version: 5.2.2 41 | vitest: 42 | specifier: ^0.34.3 43 | version: 0.34.3 44 | 45 | packages: 46 | 47 | '@babel/code-frame@7.22.10': 48 | resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} 49 | engines: {node: '>=6.9.0'} 50 | 51 | '@babel/helper-validator-identifier@7.22.5': 52 | resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} 53 | engines: {node: '>=6.9.0'} 54 | 55 | '@babel/highlight@7.22.10': 56 | resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} 57 | engines: {node: '>=6.9.0'} 58 | 59 | '@biomejs/biome@1.7.2': 60 | resolution: {integrity: sha512-6Skx9N47inLQzYi9RKgJ7PBnUnaHnMe/imqX43cOcJjZtfMnQLxEvfM2Eyo7gChkwrZlwc+VbA4huFRjw2fsYA==} 61 | engines: {node: '>=14.21.3'} 62 | hasBin: true 63 | 64 | '@biomejs/cli-darwin-arm64@1.7.2': 65 | resolution: {integrity: sha512-CrldIueHivWEWmeTkK8bTXajeX53F8i2Rrkkt8cPZyMtzkrwxf8Riq4a/jz3SQBHkxHFT4TqGbSTNMXe3X1ogA==} 66 | engines: {node: '>=14.21.3'} 67 | cpu: [arm64] 68 | os: [darwin] 69 | 70 | '@biomejs/cli-darwin-x64@1.7.2': 71 | resolution: {integrity: sha512-UELnLJuJOsTL9meArvn8BtiXDURyPil2Ej9me2uVpEvee8UQdqd/bssP5we400OWShlL1AAML4fn6d2WX5332g==} 72 | engines: {node: '>=14.21.3'} 73 | cpu: [x64] 74 | os: [darwin] 75 | 76 | '@biomejs/cli-linux-arm64-musl@1.7.2': 77 | resolution: {integrity: sha512-kKYZiem7Sj7wI0dpVxJlK7C+TFQwzO/ctufIGXGJAyEmUe9vEKSzV8CXpv+JIRiTWyqaZJ4K+eHz4SPdPCv05w==} 78 | engines: {node: '>=14.21.3'} 79 | cpu: [arm64] 80 | os: [linux] 81 | 82 | '@biomejs/cli-linux-arm64@1.7.2': 83 | resolution: {integrity: sha512-Z1CSGQE6fHz55gkiFHv9E8wEAaSUd7dHSRaxSCBa7utonHqpIeMbvj3Evm1w0WfGLFDtRXLV1fTfEdM0FMTOhA==} 84 | engines: {node: '>=14.21.3'} 85 | cpu: [arm64] 86 | os: [linux] 87 | 88 | '@biomejs/cli-linux-x64-musl@1.7.2': 89 | resolution: {integrity: sha512-x10LpGMepDrLS+h2TZ6/T7egpHjGKtiI4GuShNylmBQJWfTotbFf9eseHggrqJ4WZf9yrGoVYrtbxXftuB95sQ==} 90 | engines: {node: '>=14.21.3'} 91 | cpu: [x64] 92 | os: [linux] 93 | 94 | '@biomejs/cli-linux-x64@1.7.2': 95 | resolution: {integrity: sha512-vXXyox8/CQijBxAu0+r8FfSO7JlC4tob3PbaFda8gPJFRz2uFJw39HtxVUwbTV1EcU6wSPh4SiRu5sZfP1VHrQ==} 96 | engines: {node: '>=14.21.3'} 97 | cpu: [x64] 98 | os: [linux] 99 | 100 | '@biomejs/cli-win32-arm64@1.7.2': 101 | resolution: {integrity: sha512-kRXdlKzcU7INf6/ldu0nVmkOgt7bKqmyXRRCUqqaJfA32+9InTbkD8tGrHZEVYIWr+eTuKcg16qZVDsPSDFZ8g==} 102 | engines: {node: '>=14.21.3'} 103 | cpu: [arm64] 104 | os: [win32] 105 | 106 | '@biomejs/cli-win32-x64@1.7.2': 107 | resolution: {integrity: sha512-qHTtpAs+CNglAAuaTy09htoqUhrQyd3nd0aGTuLNqD10h1llMVi8WFZfoa+e5MuDSfYtMK6nW2Tbf6WgzzR1Qw==} 108 | engines: {node: '>=14.21.3'} 109 | cpu: [x64] 110 | os: [win32] 111 | 112 | '@brillout/find-package-files@0.1.1': 113 | resolution: {integrity: sha512-1gqcKR8GBikQ8IFcGYvxFMte8ZbYe4p6vD3mM1pFzk7zYEqT/NlHab7+2DvKUvZQcKIO9C7LvOLBzrt0aBiVSQ==} 114 | 115 | '@brillout/format-text@0.1.3': 116 | resolution: {integrity: sha512-79/JKUOr+POW3XAfRDDxoxCjGBeD5KVwkzBWhK7KPA66HCTwEqb7unqxfVGSJZ9MnL/NiMb0shhzRkydMC/YFg==} 117 | 118 | '@brillout/mdocs@0.1.30': 119 | resolution: {integrity: sha512-oP5cSb0xJaEO1T8ScjIrL/hVhFycUDHCzt0MNP7Ube8RMk2lvyV28TEmsAhTXvTWJaUY5ohrPrbrIvWG9slg0A==} 120 | hasBin: true 121 | 122 | '@brillout/picocolors@1.0.12': 123 | resolution: {integrity: sha512-2gowgbpAqEQz4U1D/dh3tU2fKcRm+yt724d8YTbCsVHxnLTHWP2J5RMO1iTWcoViX7rTmLvPkHHlYtEiKP4gLA==} 124 | 125 | '@brillout/reassert@0.1.1': 126 | resolution: {integrity: sha512-ZkEW9dZCQPpPmesRQdx4aacdR4SpJ5L8FbjuxZ06KXcryIVh37NbcnPzGAoeqOJxE7IVKXHyDN/cAAwlGkQv0w==} 127 | 128 | '@brillout/release-me@0.3.8': 129 | resolution: {integrity: sha512-feo4CLWpMT0LS5l/fI37vv9pbOOEste6/AO9qLT5WtupqDkgK9k6iBuZmzLlef4AthIA2BY20tXlX/VcFWKuSw==} 130 | hasBin: true 131 | 132 | '@brillout/vitest-snapshot@0.35.0-prerelease': 133 | resolution: {integrity: sha512-QTLTM1h0RV+mh203+i6vW8U5Nxp8wUhissc9bZs8pONkoXq2vx9APkxIawmT3GPKpsQJsnTZvJyp2RyZCbS0cw==} 134 | 135 | '@esbuild/android-arm64@0.18.20': 136 | resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} 137 | engines: {node: '>=12'} 138 | cpu: [arm64] 139 | os: [android] 140 | 141 | '@esbuild/android-arm@0.18.20': 142 | resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} 143 | engines: {node: '>=12'} 144 | cpu: [arm] 145 | os: [android] 146 | 147 | '@esbuild/android-x64@0.18.20': 148 | resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} 149 | engines: {node: '>=12'} 150 | cpu: [x64] 151 | os: [android] 152 | 153 | '@esbuild/darwin-arm64@0.18.20': 154 | resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} 155 | engines: {node: '>=12'} 156 | cpu: [arm64] 157 | os: [darwin] 158 | 159 | '@esbuild/darwin-x64@0.18.20': 160 | resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} 161 | engines: {node: '>=12'} 162 | cpu: [x64] 163 | os: [darwin] 164 | 165 | '@esbuild/freebsd-arm64@0.18.20': 166 | resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} 167 | engines: {node: '>=12'} 168 | cpu: [arm64] 169 | os: [freebsd] 170 | 171 | '@esbuild/freebsd-x64@0.18.20': 172 | resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} 173 | engines: {node: '>=12'} 174 | cpu: [x64] 175 | os: [freebsd] 176 | 177 | '@esbuild/linux-arm64@0.18.20': 178 | resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} 179 | engines: {node: '>=12'} 180 | cpu: [arm64] 181 | os: [linux] 182 | 183 | '@esbuild/linux-arm@0.18.20': 184 | resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} 185 | engines: {node: '>=12'} 186 | cpu: [arm] 187 | os: [linux] 188 | 189 | '@esbuild/linux-ia32@0.18.20': 190 | resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} 191 | engines: {node: '>=12'} 192 | cpu: [ia32] 193 | os: [linux] 194 | 195 | '@esbuild/linux-loong64@0.18.20': 196 | resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} 197 | engines: {node: '>=12'} 198 | cpu: [loong64] 199 | os: [linux] 200 | 201 | '@esbuild/linux-mips64el@0.18.20': 202 | resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} 203 | engines: {node: '>=12'} 204 | cpu: [mips64el] 205 | os: [linux] 206 | 207 | '@esbuild/linux-ppc64@0.18.20': 208 | resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} 209 | engines: {node: '>=12'} 210 | cpu: [ppc64] 211 | os: [linux] 212 | 213 | '@esbuild/linux-riscv64@0.18.20': 214 | resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} 215 | engines: {node: '>=12'} 216 | cpu: [riscv64] 217 | os: [linux] 218 | 219 | '@esbuild/linux-s390x@0.18.20': 220 | resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} 221 | engines: {node: '>=12'} 222 | cpu: [s390x] 223 | os: [linux] 224 | 225 | '@esbuild/linux-x64@0.18.20': 226 | resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} 227 | engines: {node: '>=12'} 228 | cpu: [x64] 229 | os: [linux] 230 | 231 | '@esbuild/netbsd-x64@0.18.20': 232 | resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} 233 | engines: {node: '>=12'} 234 | cpu: [x64] 235 | os: [netbsd] 236 | 237 | '@esbuild/openbsd-x64@0.18.20': 238 | resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} 239 | engines: {node: '>=12'} 240 | cpu: [x64] 241 | os: [openbsd] 242 | 243 | '@esbuild/sunos-x64@0.18.20': 244 | resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} 245 | engines: {node: '>=12'} 246 | cpu: [x64] 247 | os: [sunos] 248 | 249 | '@esbuild/win32-arm64@0.18.20': 250 | resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} 251 | engines: {node: '>=12'} 252 | cpu: [arm64] 253 | os: [win32] 254 | 255 | '@esbuild/win32-ia32@0.18.20': 256 | resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} 257 | engines: {node: '>=12'} 258 | cpu: [ia32] 259 | os: [win32] 260 | 261 | '@esbuild/win32-x64@0.18.20': 262 | resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} 263 | engines: {node: '>=12'} 264 | cpu: [x64] 265 | os: [win32] 266 | 267 | '@hutson/parse-repository-url@5.0.0': 268 | resolution: {integrity: sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==} 269 | engines: {node: '>=10.13.0'} 270 | 271 | '@jest/schemas@29.6.3': 272 | resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} 273 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 274 | 275 | '@jridgewell/sourcemap-codec@1.4.15': 276 | resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} 277 | 278 | '@sinclair/typebox@0.27.8': 279 | resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} 280 | 281 | '@types/chai-subset@1.3.3': 282 | resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} 283 | 284 | '@types/chai@4.3.5': 285 | resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} 286 | 287 | '@types/node@20.5.6': 288 | resolution: {integrity: sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==} 289 | 290 | '@types/normalize-package-data@2.4.1': 291 | resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} 292 | 293 | '@types/prop-types@15.7.5': 294 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 295 | 296 | '@types/react@18.2.21': 297 | resolution: {integrity: sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==} 298 | 299 | '@types/scheduler@0.16.3': 300 | resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} 301 | 302 | '@vitest/expect@0.34.3': 303 | resolution: {integrity: sha512-F8MTXZUYRBVsYL1uoIft1HHWhwDbSzwAU9Zgh8S6WFC3YgVb4AnFV2GXO3P5Em8FjEYaZtTnQYoNwwBrlOMXgg==} 304 | 305 | '@vitest/runner@0.34.3': 306 | resolution: {integrity: sha512-lYNq7N3vR57VMKMPLVvmJoiN4bqwzZ1euTW+XXYH5kzr3W/+xQG3b41xJn9ChJ3AhYOSoweu974S1V3qDcFESA==} 307 | 308 | '@vitest/spy@0.34.3': 309 | resolution: {integrity: sha512-N1V0RFQ6AI7CPgzBq9kzjRdPIgThC340DGjdKdPSE8r86aUSmeliTUgkTqLSgtEwWWsGfBQ+UetZWhK0BgJmkQ==} 310 | 311 | '@vitest/utils@0.34.3': 312 | resolution: {integrity: sha512-kiSnzLG6m/tiT0XEl4U2H8JDBjFtwVlaE8I3QfGiMFR0QvnRDfYfdP3YvTBWM/6iJDAyaPY6yVQiCTUc7ZzTHA==} 313 | 314 | JSONStream@1.3.5: 315 | resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} 316 | hasBin: true 317 | 318 | acorn-walk@8.2.0: 319 | resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} 320 | engines: {node: '>=0.4.0'} 321 | 322 | acorn@8.10.0: 323 | resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} 324 | engines: {node: '>=0.4.0'} 325 | hasBin: true 326 | 327 | add-stream@1.0.0: 328 | resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} 329 | 330 | ansi-regex@3.0.1: 331 | resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} 332 | engines: {node: '>=4'} 333 | 334 | ansi-styles@3.2.1: 335 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 336 | engines: {node: '>=4'} 337 | 338 | ansi-styles@5.2.0: 339 | resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} 340 | engines: {node: '>=10'} 341 | 342 | array-ify@1.0.0: 343 | resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} 344 | 345 | assertion-error@1.1.0: 346 | resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} 347 | 348 | balanced-match@1.0.2: 349 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 350 | 351 | brace-expansion@1.1.11: 352 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 353 | 354 | cac@6.7.14: 355 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 356 | engines: {node: '>=8'} 357 | 358 | chai@4.3.8: 359 | resolution: {integrity: sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==} 360 | engines: {node: '>=4'} 361 | 362 | chalk@2.4.2: 363 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 364 | engines: {node: '>=4'} 365 | 366 | check-error@1.0.2: 367 | resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} 368 | 369 | color-convert@1.9.3: 370 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 371 | 372 | color-name@1.1.3: 373 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 374 | 375 | commander@11.1.0: 376 | resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} 377 | engines: {node: '>=16'} 378 | 379 | compare-func@2.0.0: 380 | resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} 381 | 382 | concat-map@0.0.1: 383 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 384 | 385 | conventional-changelog-angular@7.0.0: 386 | resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} 387 | engines: {node: '>=16'} 388 | 389 | conventional-changelog-atom@4.0.0: 390 | resolution: {integrity: sha512-q2YtiN7rnT1TGwPTwjjBSIPIzDJCRE+XAUahWxnh+buKK99Kks4WLMHoexw38GXx9OUxAsrp44f9qXe5VEMYhw==} 391 | engines: {node: '>=16'} 392 | 393 | conventional-changelog-codemirror@4.0.0: 394 | resolution: {integrity: sha512-hQSojc/5imn1GJK3A75m9hEZZhc3urojA5gMpnar4JHmgLnuM3CUIARPpEk86glEKr3c54Po3WV/vCaO/U8g3Q==} 395 | engines: {node: '>=16'} 396 | 397 | conventional-changelog-conventionalcommits@7.0.2: 398 | resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} 399 | engines: {node: '>=16'} 400 | 401 | conventional-changelog-core@7.0.0: 402 | resolution: {integrity: sha512-UYgaB1F/COt7VFjlYKVE/9tTzfU3VUq47r6iWf6lM5T7TlOxr0thI63ojQueRLIpVbrtHK4Ffw+yQGduw2Bhdg==} 403 | engines: {node: '>=16'} 404 | 405 | conventional-changelog-ember@4.0.0: 406 | resolution: {integrity: sha512-D0IMhwcJUg1Y8FSry6XAplEJcljkHVlvAZddhhsdbL1rbsqRsMfGx/PIkPYq0ru5aDgn+OxhQ5N5yR7P9mfsvA==} 407 | engines: {node: '>=16'} 408 | 409 | conventional-changelog-eslint@5.0.0: 410 | resolution: {integrity: sha512-6JtLWqAQIeJLn/OzUlYmzd9fKeNSWmQVim9kql+v4GrZwLx807kAJl3IJVc3jTYfVKWLxhC3BGUxYiuVEcVjgA==} 411 | engines: {node: '>=16'} 412 | 413 | conventional-changelog-express@4.0.0: 414 | resolution: {integrity: sha512-yWyy5c7raP9v7aTvPAWzqrztACNO9+FEI1FSYh7UP7YT1AkWgv5UspUeB5v3Ibv4/o60zj2o9GF2tqKQ99lIsw==} 415 | engines: {node: '>=16'} 416 | 417 | conventional-changelog-jquery@5.0.0: 418 | resolution: {integrity: sha512-slLjlXLRNa/icMI3+uGLQbtrgEny3RgITeCxevJB+p05ExiTgHACP5p3XiMKzjBn80n+Rzr83XMYfRInEtCPPw==} 419 | engines: {node: '>=16'} 420 | 421 | conventional-changelog-jshint@4.0.0: 422 | resolution: {integrity: sha512-LyXq1bbl0yG0Ai1SbLxIk8ZxUOe3AjnlwE6sVRQmMgetBk+4gY9EO3d00zlEt8Y8gwsITytDnPORl8al7InTjg==} 423 | engines: {node: '>=16'} 424 | 425 | conventional-changelog-preset-loader@4.1.0: 426 | resolution: {integrity: sha512-HozQjJicZTuRhCRTq4rZbefaiCzRM2pr6u2NL3XhrmQm4RMnDXfESU6JKu/pnKwx5xtdkYfNCsbhN5exhiKGJA==} 427 | engines: {node: '>=16'} 428 | 429 | conventional-changelog-writer@7.0.1: 430 | resolution: {integrity: sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==} 431 | engines: {node: '>=16'} 432 | hasBin: true 433 | 434 | conventional-changelog@5.1.0: 435 | resolution: {integrity: sha512-aWyE/P39wGYRPllcCEZDxTVEmhyLzTc9XA6z6rVfkuCD2UBnhV/sgSOKbQrEG5z9mEZJjnopjgQooTKxEg8mAg==} 436 | engines: {node: '>=16'} 437 | 438 | conventional-commits-filter@4.0.0: 439 | resolution: {integrity: sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==} 440 | engines: {node: '>=16'} 441 | 442 | conventional-commits-parser@5.0.0: 443 | resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} 444 | engines: {node: '>=16'} 445 | hasBin: true 446 | 447 | cross-spawn@7.0.3: 448 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 449 | engines: {node: '>= 8'} 450 | 451 | csstype@3.1.2: 452 | resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} 453 | 454 | dargs@8.1.0: 455 | resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} 456 | engines: {node: '>=12'} 457 | 458 | debug@4.3.4: 459 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 460 | engines: {node: '>=6.0'} 461 | peerDependencies: 462 | supports-color: '*' 463 | peerDependenciesMeta: 464 | supports-color: 465 | optional: true 466 | 467 | deep-eql@4.1.3: 468 | resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} 469 | engines: {node: '>=6'} 470 | 471 | diff-sequences@29.6.3: 472 | resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} 473 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 474 | 475 | dot-prop@5.3.0: 476 | resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} 477 | engines: {node: '>=8'} 478 | 479 | error-ex@1.3.2: 480 | resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} 481 | 482 | esbuild@0.18.20: 483 | resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} 484 | engines: {node: '>=12'} 485 | hasBin: true 486 | 487 | escape-string-regexp@1.0.5: 488 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 489 | engines: {node: '>=0.8.0'} 490 | 491 | execa@5.1.1: 492 | resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} 493 | engines: {node: '>=10'} 494 | 495 | find-up@2.1.0: 496 | resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} 497 | engines: {node: '>=4'} 498 | 499 | find-up@6.3.0: 500 | resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} 501 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 502 | 503 | fs.realpath@1.0.0: 504 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 505 | 506 | fsevents@2.3.3: 507 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 508 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 509 | os: [darwin] 510 | 511 | function-bind@1.1.1: 512 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 513 | 514 | get-func-name@2.0.0: 515 | resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} 516 | 517 | get-stream@6.0.1: 518 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 519 | engines: {node: '>=10'} 520 | 521 | git-raw-commits@4.0.0: 522 | resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} 523 | engines: {node: '>=16'} 524 | hasBin: true 525 | 526 | git-semver-tags@7.0.1: 527 | resolution: {integrity: sha512-NY0ZHjJzyyNXHTDZmj+GG7PyuAKtMsyWSwh07CR2hOZFa+/yoTsXci/nF2obzL8UDhakFNkD9gNdt/Ed+cxh2Q==} 528 | engines: {node: '>=16'} 529 | hasBin: true 530 | 531 | glob-gitignore@1.0.14: 532 | resolution: {integrity: sha512-YuAEPqL58bOQDqDF2kMv009rIjSAtPs+WPzyGbwRWK+wD0UWQVRoP34Pz6yJ6ivco65C9tZnaIt0I3JCuQ8NZQ==} 533 | engines: {node: '>= 6'} 534 | 535 | glob@7.2.3: 536 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 537 | 538 | handlebars@4.7.8: 539 | resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} 540 | engines: {node: '>=0.4.7'} 541 | hasBin: true 542 | 543 | has-flag@3.0.0: 544 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 545 | engines: {node: '>=4'} 546 | 547 | has@1.0.3: 548 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 549 | engines: {node: '>= 0.4.0'} 550 | 551 | hosted-git-info@7.0.1: 552 | resolution: {integrity: sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==} 553 | engines: {node: ^16.14.0 || >=18.0.0} 554 | 555 | human-signals@2.1.0: 556 | resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} 557 | engines: {node: '>=10.17.0'} 558 | 559 | ignore@3.3.10: 560 | resolution: {integrity: sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==} 561 | 562 | ignore@5.2.4: 563 | resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} 564 | engines: {node: '>= 4'} 565 | 566 | inflight@1.0.6: 567 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 568 | 569 | inherits@2.0.4: 570 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 571 | 572 | is-arrayish@0.2.1: 573 | resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 574 | 575 | is-core-module@2.13.0: 576 | resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} 577 | 578 | is-fullwidth-code-point@2.0.0: 579 | resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} 580 | engines: {node: '>=4'} 581 | 582 | is-obj@2.0.0: 583 | resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} 584 | engines: {node: '>=8'} 585 | 586 | is-stream@2.0.1: 587 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} 588 | engines: {node: '>=8'} 589 | 590 | is-text-path@2.0.0: 591 | resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} 592 | engines: {node: '>=8'} 593 | 594 | isexe@2.0.0: 595 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 596 | 597 | js-tokens@4.0.0: 598 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 599 | 600 | json-parse-even-better-errors@3.0.1: 601 | resolution: {integrity: sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==} 602 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 603 | 604 | json-stringify-safe@5.0.1: 605 | resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} 606 | 607 | jsonc-parser@3.2.0: 608 | resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} 609 | 610 | jsonparse@1.3.1: 611 | resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} 612 | engines: {'0': node >= 0.2.0} 613 | 614 | lines-and-columns@2.0.4: 615 | resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} 616 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 617 | 618 | local-pkg@0.4.3: 619 | resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} 620 | engines: {node: '>=14'} 621 | 622 | locate-path@2.0.0: 623 | resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} 624 | engines: {node: '>=4'} 625 | 626 | locate-path@7.2.0: 627 | resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} 628 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 629 | 630 | lodash.difference@4.5.0: 631 | resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} 632 | 633 | lodash.escaperegexp@4.1.2: 634 | resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} 635 | 636 | lodash.isequal@4.5.0: 637 | resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} 638 | 639 | lodash.union@4.6.0: 640 | resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} 641 | 642 | loose-envify@1.4.0: 643 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 644 | hasBin: true 645 | 646 | loupe@2.3.6: 647 | resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} 648 | 649 | lru-cache@10.2.2: 650 | resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} 651 | engines: {node: 14 || >=16.14} 652 | 653 | lru-cache@6.0.0: 654 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 655 | engines: {node: '>=10'} 656 | 657 | magic-string@0.30.3: 658 | resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==} 659 | engines: {node: '>=12'} 660 | 661 | make-array@1.0.5: 662 | resolution: {integrity: sha512-sgK2SAzxT19rWU+qxKUcn6PAh/swiIiz2F8C2cZjLc1z4iwYIfdoihqFIDQ8BDzAGtWPYJ6Sr13K1j/DXynDLA==} 663 | engines: {node: '>=0.10.0'} 664 | 665 | meow@12.1.1: 666 | resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} 667 | engines: {node: '>=16.10'} 668 | 669 | merge-stream@2.0.0: 670 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 671 | 672 | mimic-fn@2.1.0: 673 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 674 | engines: {node: '>=6'} 675 | 676 | minimatch@3.1.2: 677 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 678 | 679 | minimist@1.2.8: 680 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 681 | 682 | mlly@1.4.1: 683 | resolution: {integrity: sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==} 684 | 685 | ms@2.1.2: 686 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 687 | 688 | nanoid@3.3.6: 689 | resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} 690 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 691 | hasBin: true 692 | 693 | neo-async@2.6.2: 694 | resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} 695 | 696 | normalize-package-data@6.0.0: 697 | resolution: {integrity: sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==} 698 | engines: {node: ^16.14.0 || >=18.0.0} 699 | 700 | npm-run-path@4.0.1: 701 | resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} 702 | engines: {node: '>=8'} 703 | 704 | object-assign@4.1.1: 705 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 706 | engines: {node: '>=0.10.0'} 707 | 708 | once@1.4.0: 709 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 710 | 711 | onetime@5.1.2: 712 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 713 | engines: {node: '>=6'} 714 | 715 | p-limit@1.3.0: 716 | resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} 717 | engines: {node: '>=4'} 718 | 719 | p-limit@4.0.0: 720 | resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} 721 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 722 | 723 | p-locate@2.0.0: 724 | resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} 725 | engines: {node: '>=4'} 726 | 727 | p-locate@6.0.0: 728 | resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} 729 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 730 | 731 | p-try@1.0.0: 732 | resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} 733 | engines: {node: '>=4'} 734 | 735 | parse-json@7.1.1: 736 | resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} 737 | engines: {node: '>=16'} 738 | 739 | path-exists@3.0.0: 740 | resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} 741 | engines: {node: '>=4'} 742 | 743 | path-exists@5.0.0: 744 | resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} 745 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 746 | 747 | path-is-absolute@1.0.1: 748 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 749 | engines: {node: '>=0.10.0'} 750 | 751 | path-key@3.1.1: 752 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 753 | engines: {node: '>=8'} 754 | 755 | pathe@1.1.1: 756 | resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} 757 | 758 | pathval@1.1.1: 759 | resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} 760 | 761 | picocolors@1.0.0: 762 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 763 | 764 | pkg-types@1.0.3: 765 | resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} 766 | 767 | postcss@8.4.29: 768 | resolution: {integrity: sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==} 769 | engines: {node: ^10 || ^12 || >=14} 770 | 771 | prettier@3.2.5: 772 | resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} 773 | engines: {node: '>=14'} 774 | hasBin: true 775 | 776 | pretty-format@29.6.3: 777 | resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==} 778 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 779 | 780 | react-is@18.2.0: 781 | resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} 782 | 783 | react@17.0.2: 784 | resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} 785 | engines: {node: '>=0.10.0'} 786 | 787 | read-pkg-up@10.1.0: 788 | resolution: {integrity: sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==} 789 | engines: {node: '>=16'} 790 | 791 | read-pkg@8.1.0: 792 | resolution: {integrity: sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==} 793 | engines: {node: '>=16'} 794 | 795 | reassert@1.1.21: 796 | resolution: {integrity: sha512-Ff2/AaIE5LDTrsEBUDKFb65klJki9xibTKi7loj9bGxBrQBb4BubgvJLEyKRlzrr4SFmg0QzfdcTojU9NHn0Zw==} 797 | 798 | rollup@3.28.1: 799 | resolution: {integrity: sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==} 800 | engines: {node: '>=14.18.0', npm: '>=8.0.0'} 801 | hasBin: true 802 | 803 | semver@7.5.4: 804 | resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} 805 | engines: {node: '>=10'} 806 | hasBin: true 807 | 808 | shebang-command@2.0.0: 809 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 810 | engines: {node: '>=8'} 811 | 812 | shebang-regex@3.0.0: 813 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 814 | engines: {node: '>=8'} 815 | 816 | siginfo@2.0.0: 817 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 818 | 819 | signal-exit@3.0.7: 820 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 821 | 822 | source-map-js@1.0.2: 823 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 824 | engines: {node: '>=0.10.0'} 825 | 826 | source-map@0.6.1: 827 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 828 | engines: {node: '>=0.10.0'} 829 | 830 | spdx-correct@3.2.0: 831 | resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} 832 | 833 | spdx-exceptions@2.3.0: 834 | resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} 835 | 836 | spdx-expression-parse@3.0.1: 837 | resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} 838 | 839 | spdx-license-ids@3.0.13: 840 | resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} 841 | 842 | split2@4.2.0: 843 | resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} 844 | engines: {node: '>= 10.x'} 845 | 846 | stackback@0.0.2: 847 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 848 | 849 | std-env@3.4.3: 850 | resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==} 851 | 852 | string-width@2.1.1: 853 | resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} 854 | engines: {node: '>=4'} 855 | 856 | strip-ansi@4.0.0: 857 | resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} 858 | engines: {node: '>=4'} 859 | 860 | strip-final-newline@2.0.0: 861 | resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} 862 | engines: {node: '>=6'} 863 | 864 | strip-literal@1.3.0: 865 | resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} 866 | 867 | supports-color@5.5.0: 868 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 869 | engines: {node: '>=4'} 870 | 871 | text-extensions@2.4.0: 872 | resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} 873 | engines: {node: '>=8'} 874 | 875 | through@2.3.8: 876 | resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} 877 | 878 | tinybench@2.5.0: 879 | resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} 880 | 881 | tinypool@0.7.0: 882 | resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} 883 | engines: {node: '>=14.0.0'} 884 | 885 | tinyspy@2.1.1: 886 | resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} 887 | engines: {node: '>=14.0.0'} 888 | 889 | type-detect@4.0.8: 890 | resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} 891 | engines: {node: '>=4'} 892 | 893 | type-fest@3.13.1: 894 | resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} 895 | engines: {node: '>=14.16'} 896 | 897 | type-fest@4.18.1: 898 | resolution: {integrity: sha512-qXhgeNsX15bM63h5aapNFcQid9jRF/l3ojDoDFmekDQEUufZ9U4ErVt6SjDxnHp48Ltrw616R8yNc3giJ3KvVQ==} 899 | engines: {node: '>=16'} 900 | 901 | typescript@5.2.2: 902 | resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} 903 | engines: {node: '>=14.17'} 904 | hasBin: true 905 | 906 | ufo@1.3.0: 907 | resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==} 908 | 909 | uglify-js@3.17.4: 910 | resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} 911 | engines: {node: '>=0.8.0'} 912 | hasBin: true 913 | 914 | util.inherits@1.0.3: 915 | resolution: {integrity: sha512-gMirHcfcq5D87nXDwbZqf5vl65S0mpMZBsHXJsXOO3Hc3G+JoQLwgaJa1h+PL7h3WhocnuLqoe8CuvMlztkyCA==} 916 | engines: {node: '>=4'} 917 | 918 | validate-npm-package-license@3.0.4: 919 | resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} 920 | 921 | vite-node@0.34.3: 922 | resolution: {integrity: sha512-+0TzJf1g0tYXj6tR2vEyiA42OPq68QkRZCu/ERSo2PtsDJfBpDyEfuKbRvLmZqi/CgC7SCBtyC+WjTGNMRIaig==} 923 | engines: {node: '>=v14.18.0'} 924 | hasBin: true 925 | 926 | vite@4.4.9: 927 | resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} 928 | engines: {node: ^14.18.0 || >=16.0.0} 929 | hasBin: true 930 | peerDependencies: 931 | '@types/node': '>= 14' 932 | less: '*' 933 | lightningcss: ^1.21.0 934 | sass: '*' 935 | stylus: '*' 936 | sugarss: '*' 937 | terser: ^5.4.0 938 | peerDependenciesMeta: 939 | '@types/node': 940 | optional: true 941 | less: 942 | optional: true 943 | lightningcss: 944 | optional: true 945 | sass: 946 | optional: true 947 | stylus: 948 | optional: true 949 | sugarss: 950 | optional: true 951 | terser: 952 | optional: true 953 | 954 | vitest@0.34.3: 955 | resolution: {integrity: sha512-7+VA5Iw4S3USYk+qwPxHl8plCMhA5rtfwMjgoQXMT7rO5ldWcdsdo3U1QD289JgglGK4WeOzgoLTsGFu6VISyQ==} 956 | engines: {node: '>=v14.18.0'} 957 | hasBin: true 958 | peerDependencies: 959 | '@edge-runtime/vm': '*' 960 | '@vitest/browser': '*' 961 | '@vitest/ui': '*' 962 | happy-dom: '*' 963 | jsdom: '*' 964 | playwright: '*' 965 | safaridriver: '*' 966 | webdriverio: '*' 967 | peerDependenciesMeta: 968 | '@edge-runtime/vm': 969 | optional: true 970 | '@vitest/browser': 971 | optional: true 972 | '@vitest/ui': 973 | optional: true 974 | happy-dom: 975 | optional: true 976 | jsdom: 977 | optional: true 978 | playwright: 979 | optional: true 980 | safaridriver: 981 | optional: true 982 | webdriverio: 983 | optional: true 984 | 985 | which@2.0.2: 986 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 987 | engines: {node: '>= 8'} 988 | hasBin: true 989 | 990 | why-is-node-running@2.2.2: 991 | resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} 992 | engines: {node: '>=8'} 993 | hasBin: true 994 | 995 | wordwrap@1.0.0: 996 | resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} 997 | 998 | wrappy@1.0.2: 999 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1000 | 1001 | yallist@4.0.0: 1002 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 1003 | 1004 | yocto-queue@1.0.0: 1005 | resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} 1006 | engines: {node: '>=12.20'} 1007 | 1008 | snapshots: 1009 | 1010 | '@babel/code-frame@7.22.10': 1011 | dependencies: 1012 | '@babel/highlight': 7.22.10 1013 | chalk: 2.4.2 1014 | 1015 | '@babel/helper-validator-identifier@7.22.5': {} 1016 | 1017 | '@babel/highlight@7.22.10': 1018 | dependencies: 1019 | '@babel/helper-validator-identifier': 7.22.5 1020 | chalk: 2.4.2 1021 | js-tokens: 4.0.0 1022 | 1023 | '@biomejs/biome@1.7.2': 1024 | optionalDependencies: 1025 | '@biomejs/cli-darwin-arm64': 1.7.2 1026 | '@biomejs/cli-darwin-x64': 1.7.2 1027 | '@biomejs/cli-linux-arm64': 1.7.2 1028 | '@biomejs/cli-linux-arm64-musl': 1.7.2 1029 | '@biomejs/cli-linux-x64': 1.7.2 1030 | '@biomejs/cli-linux-x64-musl': 1.7.2 1031 | '@biomejs/cli-win32-arm64': 1.7.2 1032 | '@biomejs/cli-win32-x64': 1.7.2 1033 | 1034 | '@biomejs/cli-darwin-arm64@1.7.2': 1035 | optional: true 1036 | 1037 | '@biomejs/cli-darwin-x64@1.7.2': 1038 | optional: true 1039 | 1040 | '@biomejs/cli-linux-arm64-musl@1.7.2': 1041 | optional: true 1042 | 1043 | '@biomejs/cli-linux-arm64@1.7.2': 1044 | optional: true 1045 | 1046 | '@biomejs/cli-linux-x64-musl@1.7.2': 1047 | optional: true 1048 | 1049 | '@biomejs/cli-linux-x64@1.7.2': 1050 | optional: true 1051 | 1052 | '@biomejs/cli-win32-arm64@1.7.2': 1053 | optional: true 1054 | 1055 | '@biomejs/cli-win32-x64@1.7.2': 1056 | optional: true 1057 | 1058 | '@brillout/find-package-files@0.1.1': 1059 | dependencies: 1060 | find-up: 2.1.0 1061 | glob-gitignore: 1.0.14 1062 | ignore: 3.3.10 1063 | reassert: 1.1.21 1064 | 1065 | '@brillout/format-text@0.1.3': 1066 | dependencies: 1067 | reassert: 1.1.21 1068 | string-width: 2.1.1 1069 | 1070 | '@brillout/mdocs@0.1.30': 1071 | dependencies: 1072 | '@brillout/find-package-files': 0.1.1 1073 | '@brillout/reassert': 0.1.1 1074 | find-up: 2.1.0 1075 | lodash.escaperegexp: 4.1.2 1076 | 1077 | '@brillout/picocolors@1.0.12': {} 1078 | 1079 | '@brillout/reassert@0.1.1': 1080 | dependencies: 1081 | '@brillout/format-text': 0.1.3 1082 | 1083 | '@brillout/release-me@0.3.8': 1084 | dependencies: 1085 | '@brillout/picocolors': 1.0.12 1086 | commander: 11.1.0 1087 | conventional-changelog: 5.1.0 1088 | execa: 5.1.1 1089 | semver: 7.5.4 1090 | 1091 | '@brillout/vitest-snapshot@0.35.0-prerelease': 1092 | dependencies: 1093 | magic-string: 0.30.3 1094 | pathe: 1.1.1 1095 | pretty-format: 29.6.3 1096 | 1097 | '@esbuild/android-arm64@0.18.20': 1098 | optional: true 1099 | 1100 | '@esbuild/android-arm@0.18.20': 1101 | optional: true 1102 | 1103 | '@esbuild/android-x64@0.18.20': 1104 | optional: true 1105 | 1106 | '@esbuild/darwin-arm64@0.18.20': 1107 | optional: true 1108 | 1109 | '@esbuild/darwin-x64@0.18.20': 1110 | optional: true 1111 | 1112 | '@esbuild/freebsd-arm64@0.18.20': 1113 | optional: true 1114 | 1115 | '@esbuild/freebsd-x64@0.18.20': 1116 | optional: true 1117 | 1118 | '@esbuild/linux-arm64@0.18.20': 1119 | optional: true 1120 | 1121 | '@esbuild/linux-arm@0.18.20': 1122 | optional: true 1123 | 1124 | '@esbuild/linux-ia32@0.18.20': 1125 | optional: true 1126 | 1127 | '@esbuild/linux-loong64@0.18.20': 1128 | optional: true 1129 | 1130 | '@esbuild/linux-mips64el@0.18.20': 1131 | optional: true 1132 | 1133 | '@esbuild/linux-ppc64@0.18.20': 1134 | optional: true 1135 | 1136 | '@esbuild/linux-riscv64@0.18.20': 1137 | optional: true 1138 | 1139 | '@esbuild/linux-s390x@0.18.20': 1140 | optional: true 1141 | 1142 | '@esbuild/linux-x64@0.18.20': 1143 | optional: true 1144 | 1145 | '@esbuild/netbsd-x64@0.18.20': 1146 | optional: true 1147 | 1148 | '@esbuild/openbsd-x64@0.18.20': 1149 | optional: true 1150 | 1151 | '@esbuild/sunos-x64@0.18.20': 1152 | optional: true 1153 | 1154 | '@esbuild/win32-arm64@0.18.20': 1155 | optional: true 1156 | 1157 | '@esbuild/win32-ia32@0.18.20': 1158 | optional: true 1159 | 1160 | '@esbuild/win32-x64@0.18.20': 1161 | optional: true 1162 | 1163 | '@hutson/parse-repository-url@5.0.0': {} 1164 | 1165 | '@jest/schemas@29.6.3': 1166 | dependencies: 1167 | '@sinclair/typebox': 0.27.8 1168 | 1169 | '@jridgewell/sourcemap-codec@1.4.15': {} 1170 | 1171 | '@sinclair/typebox@0.27.8': {} 1172 | 1173 | '@types/chai-subset@1.3.3': 1174 | dependencies: 1175 | '@types/chai': 4.3.5 1176 | 1177 | '@types/chai@4.3.5': {} 1178 | 1179 | '@types/node@20.5.6': {} 1180 | 1181 | '@types/normalize-package-data@2.4.1': {} 1182 | 1183 | '@types/prop-types@15.7.5': {} 1184 | 1185 | '@types/react@18.2.21': 1186 | dependencies: 1187 | '@types/prop-types': 15.7.5 1188 | '@types/scheduler': 0.16.3 1189 | csstype: 3.1.2 1190 | 1191 | '@types/scheduler@0.16.3': {} 1192 | 1193 | '@vitest/expect@0.34.3': 1194 | dependencies: 1195 | '@vitest/spy': 0.34.3 1196 | '@vitest/utils': 0.34.3 1197 | chai: 4.3.8 1198 | 1199 | '@vitest/runner@0.34.3': 1200 | dependencies: 1201 | '@vitest/utils': 0.34.3 1202 | p-limit: 4.0.0 1203 | pathe: 1.1.1 1204 | 1205 | '@vitest/spy@0.34.3': 1206 | dependencies: 1207 | tinyspy: 2.1.1 1208 | 1209 | '@vitest/utils@0.34.3': 1210 | dependencies: 1211 | diff-sequences: 29.6.3 1212 | loupe: 2.3.6 1213 | pretty-format: 29.6.3 1214 | 1215 | JSONStream@1.3.5: 1216 | dependencies: 1217 | jsonparse: 1.3.1 1218 | through: 2.3.8 1219 | 1220 | acorn-walk@8.2.0: {} 1221 | 1222 | acorn@8.10.0: {} 1223 | 1224 | add-stream@1.0.0: {} 1225 | 1226 | ansi-regex@3.0.1: {} 1227 | 1228 | ansi-styles@3.2.1: 1229 | dependencies: 1230 | color-convert: 1.9.3 1231 | 1232 | ansi-styles@5.2.0: {} 1233 | 1234 | array-ify@1.0.0: {} 1235 | 1236 | assertion-error@1.1.0: {} 1237 | 1238 | balanced-match@1.0.2: {} 1239 | 1240 | brace-expansion@1.1.11: 1241 | dependencies: 1242 | balanced-match: 1.0.2 1243 | concat-map: 0.0.1 1244 | 1245 | cac@6.7.14: {} 1246 | 1247 | chai@4.3.8: 1248 | dependencies: 1249 | assertion-error: 1.1.0 1250 | check-error: 1.0.2 1251 | deep-eql: 4.1.3 1252 | get-func-name: 2.0.0 1253 | loupe: 2.3.6 1254 | pathval: 1.1.1 1255 | type-detect: 4.0.8 1256 | 1257 | chalk@2.4.2: 1258 | dependencies: 1259 | ansi-styles: 3.2.1 1260 | escape-string-regexp: 1.0.5 1261 | supports-color: 5.5.0 1262 | 1263 | check-error@1.0.2: {} 1264 | 1265 | color-convert@1.9.3: 1266 | dependencies: 1267 | color-name: 1.1.3 1268 | 1269 | color-name@1.1.3: {} 1270 | 1271 | commander@11.1.0: {} 1272 | 1273 | compare-func@2.0.0: 1274 | dependencies: 1275 | array-ify: 1.0.0 1276 | dot-prop: 5.3.0 1277 | 1278 | concat-map@0.0.1: {} 1279 | 1280 | conventional-changelog-angular@7.0.0: 1281 | dependencies: 1282 | compare-func: 2.0.0 1283 | 1284 | conventional-changelog-atom@4.0.0: {} 1285 | 1286 | conventional-changelog-codemirror@4.0.0: {} 1287 | 1288 | conventional-changelog-conventionalcommits@7.0.2: 1289 | dependencies: 1290 | compare-func: 2.0.0 1291 | 1292 | conventional-changelog-core@7.0.0: 1293 | dependencies: 1294 | '@hutson/parse-repository-url': 5.0.0 1295 | add-stream: 1.0.0 1296 | conventional-changelog-writer: 7.0.1 1297 | conventional-commits-parser: 5.0.0 1298 | git-raw-commits: 4.0.0 1299 | git-semver-tags: 7.0.1 1300 | hosted-git-info: 7.0.1 1301 | normalize-package-data: 6.0.0 1302 | read-pkg: 8.1.0 1303 | read-pkg-up: 10.1.0 1304 | 1305 | conventional-changelog-ember@4.0.0: {} 1306 | 1307 | conventional-changelog-eslint@5.0.0: {} 1308 | 1309 | conventional-changelog-express@4.0.0: {} 1310 | 1311 | conventional-changelog-jquery@5.0.0: {} 1312 | 1313 | conventional-changelog-jshint@4.0.0: 1314 | dependencies: 1315 | compare-func: 2.0.0 1316 | 1317 | conventional-changelog-preset-loader@4.1.0: {} 1318 | 1319 | conventional-changelog-writer@7.0.1: 1320 | dependencies: 1321 | conventional-commits-filter: 4.0.0 1322 | handlebars: 4.7.8 1323 | json-stringify-safe: 5.0.1 1324 | meow: 12.1.1 1325 | semver: 7.5.4 1326 | split2: 4.2.0 1327 | 1328 | conventional-changelog@5.1.0: 1329 | dependencies: 1330 | conventional-changelog-angular: 7.0.0 1331 | conventional-changelog-atom: 4.0.0 1332 | conventional-changelog-codemirror: 4.0.0 1333 | conventional-changelog-conventionalcommits: 7.0.2 1334 | conventional-changelog-core: 7.0.0 1335 | conventional-changelog-ember: 4.0.0 1336 | conventional-changelog-eslint: 5.0.0 1337 | conventional-changelog-express: 4.0.0 1338 | conventional-changelog-jquery: 5.0.0 1339 | conventional-changelog-jshint: 4.0.0 1340 | conventional-changelog-preset-loader: 4.1.0 1341 | 1342 | conventional-commits-filter@4.0.0: {} 1343 | 1344 | conventional-commits-parser@5.0.0: 1345 | dependencies: 1346 | JSONStream: 1.3.5 1347 | is-text-path: 2.0.0 1348 | meow: 12.1.1 1349 | split2: 4.2.0 1350 | 1351 | cross-spawn@7.0.3: 1352 | dependencies: 1353 | path-key: 3.1.1 1354 | shebang-command: 2.0.0 1355 | which: 2.0.2 1356 | 1357 | csstype@3.1.2: {} 1358 | 1359 | dargs@8.1.0: {} 1360 | 1361 | debug@4.3.4: 1362 | dependencies: 1363 | ms: 2.1.2 1364 | 1365 | deep-eql@4.1.3: 1366 | dependencies: 1367 | type-detect: 4.0.8 1368 | 1369 | diff-sequences@29.6.3: {} 1370 | 1371 | dot-prop@5.3.0: 1372 | dependencies: 1373 | is-obj: 2.0.0 1374 | 1375 | error-ex@1.3.2: 1376 | dependencies: 1377 | is-arrayish: 0.2.1 1378 | 1379 | esbuild@0.18.20: 1380 | optionalDependencies: 1381 | '@esbuild/android-arm': 0.18.20 1382 | '@esbuild/android-arm64': 0.18.20 1383 | '@esbuild/android-x64': 0.18.20 1384 | '@esbuild/darwin-arm64': 0.18.20 1385 | '@esbuild/darwin-x64': 0.18.20 1386 | '@esbuild/freebsd-arm64': 0.18.20 1387 | '@esbuild/freebsd-x64': 0.18.20 1388 | '@esbuild/linux-arm': 0.18.20 1389 | '@esbuild/linux-arm64': 0.18.20 1390 | '@esbuild/linux-ia32': 0.18.20 1391 | '@esbuild/linux-loong64': 0.18.20 1392 | '@esbuild/linux-mips64el': 0.18.20 1393 | '@esbuild/linux-ppc64': 0.18.20 1394 | '@esbuild/linux-riscv64': 0.18.20 1395 | '@esbuild/linux-s390x': 0.18.20 1396 | '@esbuild/linux-x64': 0.18.20 1397 | '@esbuild/netbsd-x64': 0.18.20 1398 | '@esbuild/openbsd-x64': 0.18.20 1399 | '@esbuild/sunos-x64': 0.18.20 1400 | '@esbuild/win32-arm64': 0.18.20 1401 | '@esbuild/win32-ia32': 0.18.20 1402 | '@esbuild/win32-x64': 0.18.20 1403 | 1404 | escape-string-regexp@1.0.5: {} 1405 | 1406 | execa@5.1.1: 1407 | dependencies: 1408 | cross-spawn: 7.0.3 1409 | get-stream: 6.0.1 1410 | human-signals: 2.1.0 1411 | is-stream: 2.0.1 1412 | merge-stream: 2.0.0 1413 | npm-run-path: 4.0.1 1414 | onetime: 5.1.2 1415 | signal-exit: 3.0.7 1416 | strip-final-newline: 2.0.0 1417 | 1418 | find-up@2.1.0: 1419 | dependencies: 1420 | locate-path: 2.0.0 1421 | 1422 | find-up@6.3.0: 1423 | dependencies: 1424 | locate-path: 7.2.0 1425 | path-exists: 5.0.0 1426 | 1427 | fs.realpath@1.0.0: {} 1428 | 1429 | fsevents@2.3.3: 1430 | optional: true 1431 | 1432 | function-bind@1.1.1: {} 1433 | 1434 | get-func-name@2.0.0: {} 1435 | 1436 | get-stream@6.0.1: {} 1437 | 1438 | git-raw-commits@4.0.0: 1439 | dependencies: 1440 | dargs: 8.1.0 1441 | meow: 12.1.1 1442 | split2: 4.2.0 1443 | 1444 | git-semver-tags@7.0.1: 1445 | dependencies: 1446 | meow: 12.1.1 1447 | semver: 7.5.4 1448 | 1449 | glob-gitignore@1.0.14: 1450 | dependencies: 1451 | glob: 7.2.3 1452 | ignore: 5.2.4 1453 | lodash.difference: 4.5.0 1454 | lodash.union: 4.6.0 1455 | make-array: 1.0.5 1456 | util.inherits: 1.0.3 1457 | 1458 | glob@7.2.3: 1459 | dependencies: 1460 | fs.realpath: 1.0.0 1461 | inflight: 1.0.6 1462 | inherits: 2.0.4 1463 | minimatch: 3.1.2 1464 | once: 1.4.0 1465 | path-is-absolute: 1.0.1 1466 | 1467 | handlebars@4.7.8: 1468 | dependencies: 1469 | minimist: 1.2.8 1470 | neo-async: 2.6.2 1471 | source-map: 0.6.1 1472 | wordwrap: 1.0.0 1473 | optionalDependencies: 1474 | uglify-js: 3.17.4 1475 | 1476 | has-flag@3.0.0: {} 1477 | 1478 | has@1.0.3: 1479 | dependencies: 1480 | function-bind: 1.1.1 1481 | 1482 | hosted-git-info@7.0.1: 1483 | dependencies: 1484 | lru-cache: 10.2.2 1485 | 1486 | human-signals@2.1.0: {} 1487 | 1488 | ignore@3.3.10: {} 1489 | 1490 | ignore@5.2.4: {} 1491 | 1492 | inflight@1.0.6: 1493 | dependencies: 1494 | once: 1.4.0 1495 | wrappy: 1.0.2 1496 | 1497 | inherits@2.0.4: {} 1498 | 1499 | is-arrayish@0.2.1: {} 1500 | 1501 | is-core-module@2.13.0: 1502 | dependencies: 1503 | has: 1.0.3 1504 | 1505 | is-fullwidth-code-point@2.0.0: {} 1506 | 1507 | is-obj@2.0.0: {} 1508 | 1509 | is-stream@2.0.1: {} 1510 | 1511 | is-text-path@2.0.0: 1512 | dependencies: 1513 | text-extensions: 2.4.0 1514 | 1515 | isexe@2.0.0: {} 1516 | 1517 | js-tokens@4.0.0: {} 1518 | 1519 | json-parse-even-better-errors@3.0.1: {} 1520 | 1521 | json-stringify-safe@5.0.1: {} 1522 | 1523 | jsonc-parser@3.2.0: {} 1524 | 1525 | jsonparse@1.3.1: {} 1526 | 1527 | lines-and-columns@2.0.4: {} 1528 | 1529 | local-pkg@0.4.3: {} 1530 | 1531 | locate-path@2.0.0: 1532 | dependencies: 1533 | p-locate: 2.0.0 1534 | path-exists: 3.0.0 1535 | 1536 | locate-path@7.2.0: 1537 | dependencies: 1538 | p-locate: 6.0.0 1539 | 1540 | lodash.difference@4.5.0: {} 1541 | 1542 | lodash.escaperegexp@4.1.2: {} 1543 | 1544 | lodash.isequal@4.5.0: {} 1545 | 1546 | lodash.union@4.6.0: {} 1547 | 1548 | loose-envify@1.4.0: 1549 | dependencies: 1550 | js-tokens: 4.0.0 1551 | 1552 | loupe@2.3.6: 1553 | dependencies: 1554 | get-func-name: 2.0.0 1555 | 1556 | lru-cache@10.2.2: {} 1557 | 1558 | lru-cache@6.0.0: 1559 | dependencies: 1560 | yallist: 4.0.0 1561 | 1562 | magic-string@0.30.3: 1563 | dependencies: 1564 | '@jridgewell/sourcemap-codec': 1.4.15 1565 | 1566 | make-array@1.0.5: {} 1567 | 1568 | meow@12.1.1: {} 1569 | 1570 | merge-stream@2.0.0: {} 1571 | 1572 | mimic-fn@2.1.0: {} 1573 | 1574 | minimatch@3.1.2: 1575 | dependencies: 1576 | brace-expansion: 1.1.11 1577 | 1578 | minimist@1.2.8: {} 1579 | 1580 | mlly@1.4.1: 1581 | dependencies: 1582 | acorn: 8.10.0 1583 | pathe: 1.1.1 1584 | pkg-types: 1.0.3 1585 | ufo: 1.3.0 1586 | 1587 | ms@2.1.2: {} 1588 | 1589 | nanoid@3.3.6: {} 1590 | 1591 | neo-async@2.6.2: {} 1592 | 1593 | normalize-package-data@6.0.0: 1594 | dependencies: 1595 | hosted-git-info: 7.0.1 1596 | is-core-module: 2.13.0 1597 | semver: 7.5.4 1598 | validate-npm-package-license: 3.0.4 1599 | 1600 | npm-run-path@4.0.1: 1601 | dependencies: 1602 | path-key: 3.1.1 1603 | 1604 | object-assign@4.1.1: {} 1605 | 1606 | once@1.4.0: 1607 | dependencies: 1608 | wrappy: 1.0.2 1609 | 1610 | onetime@5.1.2: 1611 | dependencies: 1612 | mimic-fn: 2.1.0 1613 | 1614 | p-limit@1.3.0: 1615 | dependencies: 1616 | p-try: 1.0.0 1617 | 1618 | p-limit@4.0.0: 1619 | dependencies: 1620 | yocto-queue: 1.0.0 1621 | 1622 | p-locate@2.0.0: 1623 | dependencies: 1624 | p-limit: 1.3.0 1625 | 1626 | p-locate@6.0.0: 1627 | dependencies: 1628 | p-limit: 4.0.0 1629 | 1630 | p-try@1.0.0: {} 1631 | 1632 | parse-json@7.1.1: 1633 | dependencies: 1634 | '@babel/code-frame': 7.22.10 1635 | error-ex: 1.3.2 1636 | json-parse-even-better-errors: 3.0.1 1637 | lines-and-columns: 2.0.4 1638 | type-fest: 3.13.1 1639 | 1640 | path-exists@3.0.0: {} 1641 | 1642 | path-exists@5.0.0: {} 1643 | 1644 | path-is-absolute@1.0.1: {} 1645 | 1646 | path-key@3.1.1: {} 1647 | 1648 | pathe@1.1.1: {} 1649 | 1650 | pathval@1.1.1: {} 1651 | 1652 | picocolors@1.0.0: {} 1653 | 1654 | pkg-types@1.0.3: 1655 | dependencies: 1656 | jsonc-parser: 3.2.0 1657 | mlly: 1.4.1 1658 | pathe: 1.1.1 1659 | 1660 | postcss@8.4.29: 1661 | dependencies: 1662 | nanoid: 3.3.6 1663 | picocolors: 1.0.0 1664 | source-map-js: 1.0.2 1665 | 1666 | prettier@3.2.5: {} 1667 | 1668 | pretty-format@29.6.3: 1669 | dependencies: 1670 | '@jest/schemas': 29.6.3 1671 | ansi-styles: 5.2.0 1672 | react-is: 18.2.0 1673 | 1674 | react-is@18.2.0: {} 1675 | 1676 | react@17.0.2: 1677 | dependencies: 1678 | loose-envify: 1.4.0 1679 | object-assign: 4.1.1 1680 | 1681 | read-pkg-up@10.1.0: 1682 | dependencies: 1683 | find-up: 6.3.0 1684 | read-pkg: 8.1.0 1685 | type-fest: 4.18.1 1686 | 1687 | read-pkg@8.1.0: 1688 | dependencies: 1689 | '@types/normalize-package-data': 2.4.1 1690 | normalize-package-data: 6.0.0 1691 | parse-json: 7.1.1 1692 | type-fest: 4.18.1 1693 | 1694 | reassert@1.1.21: 1695 | dependencies: 1696 | '@brillout/format-text': 0.1.3 1697 | 1698 | rollup@3.28.1: 1699 | optionalDependencies: 1700 | fsevents: 2.3.3 1701 | 1702 | semver@7.5.4: 1703 | dependencies: 1704 | lru-cache: 6.0.0 1705 | 1706 | shebang-command@2.0.0: 1707 | dependencies: 1708 | shebang-regex: 3.0.0 1709 | 1710 | shebang-regex@3.0.0: {} 1711 | 1712 | siginfo@2.0.0: {} 1713 | 1714 | signal-exit@3.0.7: {} 1715 | 1716 | source-map-js@1.0.2: {} 1717 | 1718 | source-map@0.6.1: {} 1719 | 1720 | spdx-correct@3.2.0: 1721 | dependencies: 1722 | spdx-expression-parse: 3.0.1 1723 | spdx-license-ids: 3.0.13 1724 | 1725 | spdx-exceptions@2.3.0: {} 1726 | 1727 | spdx-expression-parse@3.0.1: 1728 | dependencies: 1729 | spdx-exceptions: 2.3.0 1730 | spdx-license-ids: 3.0.13 1731 | 1732 | spdx-license-ids@3.0.13: {} 1733 | 1734 | split2@4.2.0: {} 1735 | 1736 | stackback@0.0.2: {} 1737 | 1738 | std-env@3.4.3: {} 1739 | 1740 | string-width@2.1.1: 1741 | dependencies: 1742 | is-fullwidth-code-point: 2.0.0 1743 | strip-ansi: 4.0.0 1744 | 1745 | strip-ansi@4.0.0: 1746 | dependencies: 1747 | ansi-regex: 3.0.1 1748 | 1749 | strip-final-newline@2.0.0: {} 1750 | 1751 | strip-literal@1.3.0: 1752 | dependencies: 1753 | acorn: 8.10.0 1754 | 1755 | supports-color@5.5.0: 1756 | dependencies: 1757 | has-flag: 3.0.0 1758 | 1759 | text-extensions@2.4.0: {} 1760 | 1761 | through@2.3.8: {} 1762 | 1763 | tinybench@2.5.0: {} 1764 | 1765 | tinypool@0.7.0: {} 1766 | 1767 | tinyspy@2.1.1: {} 1768 | 1769 | type-detect@4.0.8: {} 1770 | 1771 | type-fest@3.13.1: {} 1772 | 1773 | type-fest@4.18.1: {} 1774 | 1775 | typescript@5.2.2: {} 1776 | 1777 | ufo@1.3.0: {} 1778 | 1779 | uglify-js@3.17.4: 1780 | optional: true 1781 | 1782 | util.inherits@1.0.3: {} 1783 | 1784 | validate-npm-package-license@3.0.4: 1785 | dependencies: 1786 | spdx-correct: 3.2.0 1787 | spdx-expression-parse: 3.0.1 1788 | 1789 | vite-node@0.34.3(@types/node@20.5.6): 1790 | dependencies: 1791 | cac: 6.7.14 1792 | debug: 4.3.4 1793 | mlly: 1.4.1 1794 | pathe: 1.1.1 1795 | picocolors: 1.0.0 1796 | vite: 4.4.9(@types/node@20.5.6) 1797 | transitivePeerDependencies: 1798 | - '@types/node' 1799 | - less 1800 | - lightningcss 1801 | - sass 1802 | - stylus 1803 | - sugarss 1804 | - supports-color 1805 | - terser 1806 | 1807 | vite@4.4.9(@types/node@20.5.6): 1808 | dependencies: 1809 | esbuild: 0.18.20 1810 | postcss: 8.4.29 1811 | rollup: 3.28.1 1812 | optionalDependencies: 1813 | '@types/node': 20.5.6 1814 | fsevents: 2.3.3 1815 | 1816 | vitest@0.34.3: 1817 | dependencies: 1818 | '@types/chai': 4.3.5 1819 | '@types/chai-subset': 1.3.3 1820 | '@types/node': 20.5.6 1821 | '@vitest/expect': 0.34.3 1822 | '@vitest/runner': 0.34.3 1823 | '@vitest/snapshot': '@brillout/vitest-snapshot@0.35.0-prerelease' 1824 | '@vitest/spy': 0.34.3 1825 | '@vitest/utils': 0.34.3 1826 | acorn: 8.10.0 1827 | acorn-walk: 8.2.0 1828 | cac: 6.7.14 1829 | chai: 4.3.8 1830 | debug: 4.3.4 1831 | local-pkg: 0.4.3 1832 | magic-string: 0.30.3 1833 | pathe: 1.1.1 1834 | picocolors: 1.0.0 1835 | std-env: 3.4.3 1836 | strip-literal: 1.3.0 1837 | tinybench: 2.5.0 1838 | tinypool: 0.7.0 1839 | vite: 4.4.9(@types/node@20.5.6) 1840 | vite-node: 0.34.3(@types/node@20.5.6) 1841 | why-is-node-running: 2.2.2 1842 | transitivePeerDependencies: 1843 | - less 1844 | - lightningcss 1845 | - sass 1846 | - stylus 1847 | - sugarss 1848 | - supports-color 1849 | - terser 1850 | 1851 | which@2.0.2: 1852 | dependencies: 1853 | isexe: 2.0.0 1854 | 1855 | why-is-node-running@2.2.2: 1856 | dependencies: 1857 | siginfo: 2.0.0 1858 | stackback: 0.0.2 1859 | 1860 | wordwrap@1.0.0: {} 1861 | 1862 | wrappy@1.0.2: {} 1863 | 1864 | yallist@4.0.0: {} 1865 | 1866 | yocto-queue@1.0.0: {} 1867 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 78 | # `@brillout/json-serializer` 79 | 80 | Same as JSON but with added support for: 81 | - `Date` 82 | - `undefined` 83 | - `Set` 84 | - `Map` 85 | - `BigInt` 86 | - `RegExp` 87 | - `NaN` 88 | - `Infinity` 89 | 90 | JSON is a good serializer for JavaScript values but 91 | is lacking some JavaScript types such as `Date`: 92 | 93 | ~~~js 94 | const assert = require('assert') 95 | 96 | let obj = { 97 | time: new Date('2042-01-01') 98 | } 99 | 100 | // JSON converts dates to strings 101 | assert(obj.time.constructor === Date) 102 | obj = JSON.parse(JSON.stringify(obj)) 103 | assert(obj.time.constructor === String) 104 | assert(obj.time === '2042-01-01T00:00:00.000Z') 105 | ~~~ 106 | 107 | Whereas with `@brillout/json-serializer`: 108 | 109 | ~~~js 110 | const assert = require('assert') 111 | const { parse } = require('@brillout/json-serializer/parse') 112 | const { stringify } = require('@brillout/json-serializer/stringify') 113 | 114 | let obj = { 115 | time: new Date('2042-01-01') 116 | } 117 | 118 | // `@brillout/json-serializer` preserves Date 119 | assert(obj.time.constructor === Date) 120 | obj = parse(stringify(obj)) 121 | assert(obj.time.constructor === Date) 122 | assert(obj.time.getTime() === new Date('2042-01-01').getTime()) 123 | ~~~ 124 | 125 |
126 | 127 | #### Contents 128 | 129 | - [Usage](#usage) 130 | - [Full Example](#full-example) 131 | - [How it Works](#how-it-works) 132 | 133 | 134 |
135 | 136 | ### Usage 137 | 138 | ~~~js 139 | // npm install @brillout/json-serializer 140 | const { parse } = require('@brillout/json-serializer/parse') 141 | const { stringify } = require('@brillout/json-serializer/stringify') 142 | 143 | const obj = { 144 | hello: 'from the future', 145 | time: new Date('2042-01-01') 146 | } 147 | 148 | // Serialize with @brillout/json-serializer 149 | const obj_serialized = stringify(obj) 150 | 151 | // Deserialize a @brillout/json-serializer string 152 | const obj_deserialized = parse(obj_serialized) 153 | ~~~ 154 | 155 |
156 | 157 | ### Full Example 158 | 159 | Example exposing all differences between JSON and `@brillout/json-serializer`. 160 | 161 | ~~~js 162 | // /examples/json-serializer.js 163 | 164 | const assert = require('assert') 165 | 166 | const { parse } = require('@brillout/json-serializer/parse') 167 | const { stringify } = require('@brillout/json-serializer/stringify') 168 | 169 | const obj = { 170 | date: new Date(), 171 | undefined: undefined, 172 | NaN: NaN, 173 | Infinity: Infinity, 174 | regexp: /^\d+$/g 175 | } 176 | 177 | // All of `obj` can be serialized with @brillout/json-serializer 178 | const obj2 = parse(stringify(obj)) 179 | assert(obj2.date.getTime() === obj.date.getTime()) 180 | assert(obj2.undefined === undefined && 'undefined' in obj2) 181 | assert(isNaN(obj2.NaN)) 182 | assert(obj2.Infinity === Infinity) 183 | assert(obj2.regexp.toString() === obj.regexp.toString()) 184 | 185 | // JSON cannot serialize any of `obj` 186 | const obj3 = JSON.parse(JSON.stringify(obj)) 187 | // JSON converts dates to strings 188 | assert(obj3.constructor !== Date) 189 | // JSON removes properties with a value of `undefined` 190 | assert(!('undefined' in obj3)) 191 | // JSON converts `NaN` to `null` 192 | assert(obj3.NaN === null) 193 | // JSON converts `Infinity` to `null` 194 | assert(obj3.Infinity === null) 195 | // JSON converts RegExp to an empty object 196 | assert(obj3.regexp.constructor === Object && Object.keys(obj3.regexp).length === 0) 197 | ~~~ 198 | 199 | To run the example: 200 | 201 | ~~~shell 202 | $ git clone git@github.com:brillout/json-serializer 203 | $ cd json-serializer 204 | $ npm install 205 | $ npm run self-link 206 | $ node ./examples/json-serializer.js 207 | ~~~ 208 | 209 | The `npm run self-link` is required to be able to self `require('@brillout/json-serializer')`. 210 | 211 |
212 | 213 | ### How it Works 214 | 215 | Let's see how `@brillout/json-serializer` serializes an object: 216 | 217 | ~~~js 218 | // /examples/inspect.js 219 | 220 | const { stringify } = require('@brillout/json-serializer/stringify') 221 | 222 | const obj = { 223 | date: new Date(), 224 | undefined: undefined, 225 | collision: '!undefined', 226 | NaN: NaN, 227 | Infinity: Infinity, 228 | regexp: /^\d+$/g 229 | } 230 | 231 | console.log(stringify(obj, undefined, 2)) 232 | // Prints: 233 | /* 234 | { 235 | "date": "!Date:2021-01-12T22:15:56.319Z", 236 | "undefined": "!undefined", 237 | "collision": "!!undefined" 238 | "NaN": "!NaN", 239 | "Infinity": "!Infinity", 240 | "regexp": "!RegExp:/^\\d+$/g" 241 | } 242 | */ 243 | ~~~ 244 | 245 | `@brillout/json-serializer` is based on JSON while using prefixed strings for unsupported types. 246 | 247 | `@brillout/json-serializer` uses the native `JSON.parse` and `JSON.stringify` functions while modifying the serialization of unsupported types. 248 | 249 | 326 | -------------------------------------------------------------------------------- /readme.template.md: -------------------------------------------------------------------------------- 1 | # `@brillout/json-serializer` 2 | 3 | Same as JSON but with added support for: 4 | - `Date` 5 | - `undefined` 6 | - `Set` 7 | - `Map` 8 | - `BigInt` 9 | - `RegExp` 10 | - `NaN` 11 | - `Infinity` 12 | 13 | JSON is a good serializer for JavaScript values but 14 | is lacking some JavaScript types such as `Date`: 15 | 16 | ~~~js 17 | !INLINE /examples/date_json.js --hide-source-path 18 | ~~~ 19 | 20 | Whereas with `@brillout/json-serializer`: 21 | 22 | ~~~js 23 | !INLINE /examples/date_json-serializer.js --hide-source-path 24 | ~~~ 25 | 26 |
27 | 28 | #### Contents 29 | 30 | - [Usage](#usage) 31 | - [Full Example](#full-example) 32 | - [How it Works](#how-it-works) 33 | 34 | 35 |
36 | 37 | ### Usage 38 | 39 | ~~~js 40 | !INLINE /examples/simple.js --hide-source-path 41 | ~~~ 42 | 43 |
44 | 45 | ### Full Example 46 | 47 | Example exposing all differences between JSON and `@brillout/json-serializer`. 48 | 49 | ~~~js 50 | !INLINE /examples/json-serializer.js 51 | ~~~ 52 | 53 | To run the example: 54 | 55 | ~~~shell 56 | $ git clone git@github.com:brillout/json-serializer 57 | $ cd json-serializer 58 | $ npm install 59 | $ npm run self-link 60 | $ node ./examples/json-serializer.js 61 | ~~~ 62 | 63 | The `npm run self-link` is required to be able to self `require('@brillout/json-serializer')`. 64 | 65 |
66 | 67 | ### How it Works 68 | 69 | Let's see how `@brillout/json-serializer` serializes an object: 70 | 71 | ~~~js 72 | !INLINE /examples/inspect.js 73 | ~~~ 74 | 75 | `@brillout/json-serializer` is based on JSON while using prefixed strings for unsupported types. 76 | 77 | `@brillout/json-serializer` uses the native `JSON.parse` and `JSON.stringify` functions while modifying the serialization of unsupported types. 78 | -------------------------------------------------------------------------------- /src/parse.ts: -------------------------------------------------------------------------------- 1 | export { parse } 2 | // Used by Vike: https://github.com/vikejs/vike/blob/b4ba6b70e6bdc2e1f460c0d2e4c3faae5d0a733c/vike/shared/page-configs/serialize/parseConfigValuesSerialized.ts#L13 3 | export { parseTransform } 4 | 5 | import { types } from './types' 6 | 7 | function parse(str: string): unknown { 8 | // We don't use the reviver option in `JSON.parse(str, reviver)` because it doesn't support `undefined` values 9 | const value = JSON.parse(str) 10 | return parseTransform(value) 11 | } 12 | 13 | function parseTransform(value: unknown): unknown { 14 | if (typeof value === 'string') { 15 | return reviver(value) 16 | } 17 | if ( 18 | // Also matches arrays 19 | typeof value === 'object' && 20 | value !== null 21 | ) { 22 | Object.entries(value).forEach(([key, val]: [string, unknown]) => { 23 | ;(value as Record)[key] = parseTransform(val) 24 | }) 25 | } 26 | return value 27 | } 28 | 29 | function reviver(value: string) { 30 | for (const { match, deserialize } of types) { 31 | if (match(value)) { 32 | return deserialize(value, parse) 33 | } 34 | } 35 | return value 36 | } 37 | -------------------------------------------------------------------------------- /src/stringify.ts: -------------------------------------------------------------------------------- 1 | export { stringify } 2 | export { isJsonSerializerError } 3 | 4 | import { types } from './types' 5 | import { isReactElement } from './utils/isReactElement' 6 | import { isCallable } from './utils/isCallable' 7 | import { isObject } from './utils/isObject' 8 | import { replacerWithPath, type Iterable, type Path } from './utils/replacerWithPath' 9 | 10 | function stringify( 11 | value: unknown, 12 | { 13 | forbidReactElements, 14 | space, 15 | valueName, 16 | sortObjectKeys, 17 | // Used by Vike: https://github.com/vikejs/vike/blob/b4ba6b70e6bdc2e1f460c0d2e4c3faae5d0a733c/vike/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.ts#L78 18 | replacer: replacerUserProvided, 19 | }: { 20 | forbidReactElements?: boolean 21 | space?: number 22 | valueName?: string 23 | sortObjectKeys?: boolean 24 | replacer?: (this: Iterable, key: string, value: unknown) => void | { replacement: unknown } 25 | } = {}, 26 | ): string { 27 | // The only error `JSON.stringify()` can throw is `TypeError "cyclic object value"`. 28 | // - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#exceptions 29 | // - This means we have total of 3 possible errors while serializing: 30 | // - Cyclic references 31 | // - Functions 32 | // - React elements 33 | const serializer = (val: unknown) => JSON.stringify(val, replacerWithPath(replacer), space) 34 | 35 | return serializer(value) 36 | 37 | function replacer(this: Iterable, key: string, value: unknown, path: Path) { 38 | { 39 | const ret = replacerUserProvided?.call(this, key, value) 40 | if (ret) return ret.replacement 41 | } 42 | 43 | if (forbidReactElements && isReactElement(value)) { 44 | throw genErr({ 45 | value, 46 | valueType: 'React element', 47 | path, 48 | rootValueName: valueName, 49 | }) 50 | } 51 | 52 | if (isCallable(value)) { 53 | const functionName = value.name 54 | throw genErr({ 55 | value, 56 | valueType: 'function', 57 | path, 58 | rootValueName: valueName, 59 | problematicValueName: path.length === 0 ? functionName : undefined, 60 | }) 61 | } 62 | 63 | const valueOriginal = this[key] 64 | for (const { is, serialize } of types.slice().reverse()) { 65 | if (is(valueOriginal) as any) { 66 | //@ts-ignore 67 | return serialize(valueOriginal, serializer) 68 | } 69 | } 70 | 71 | if (sortObjectKeys && isObject(value)) { 72 | const copy: Record = {} 73 | Object.keys(value) 74 | .sort() 75 | .forEach((key) => { 76 | copy[key] = (value as Record)[key] 77 | }) 78 | value = copy 79 | } 80 | 81 | return value 82 | } 83 | } 84 | 85 | function genErr({ 86 | value, 87 | valueType, 88 | path, 89 | rootValueName, 90 | problematicValueName, 91 | }: { 92 | value: unknown 93 | valueType: ValueType 94 | path: Path 95 | rootValueName?: string 96 | problematicValueName?: string 97 | }) { 98 | const subjectName = getSubjectName({ path, rootValueName, problematicValueName }) 99 | const messageCore = `cannot serialize ${subjectName} because it's a ${valueType}` as const 100 | const err = new Error(`[@brillout/json-serializer](https://github.com/brillout/json-serializer) ${messageCore}.`) 101 | const pathString = getPathString(path, true) 102 | const errAddendum: ErrAddendum & { [stamp]: true } = { 103 | [stamp]: true, 104 | messageCore, 105 | value, 106 | path, 107 | pathString, 108 | subjectName, 109 | } 110 | Object.assign(err, errAddendum) 111 | return err 112 | } 113 | type ErrAddendum = { 114 | messageCore: 115 | | `cannot serialize ${string} because it's a function` 116 | | `cannot serialize ${string} because it's a React element` 117 | value: unknown 118 | path: Path 119 | pathString: string 120 | subjectName: string 121 | } 122 | const stamp = '_isJsonSerializerError' 123 | function isJsonSerializerError(thing: unknown): thing is Error & ErrAddendum { 124 | return isObject(thing) && thing[stamp] === true 125 | } 126 | type ValueType = 'React element' | 'function' 127 | function getSubjectName({ 128 | path, 129 | rootValueName, 130 | problematicValueName, 131 | }: { 132 | path: Path 133 | rootValueName?: string 134 | problematicValueName?: string 135 | }) { 136 | const pathString = getPathString(path, !rootValueName) 137 | let subjectName: string 138 | if (!pathString) { 139 | subjectName = rootValueName || problematicValueName || 'value' 140 | } else { 141 | if (problematicValueName) { 142 | subjectName = problematicValueName + ' at ' 143 | } else { 144 | subjectName = '' 145 | } 146 | subjectName = subjectName + (rootValueName || '') + pathString 147 | } 148 | return subjectName 149 | } 150 | 151 | function getPathString(path: Path, canBeFirstKey: boolean): string { 152 | const pathString = path 153 | .map((key, i) => { 154 | if (typeof key === 'number') { 155 | return `[${key}]` 156 | } 157 | if (i === 0 && canBeFirstKey && isKeyDotNotationCompatible(key)) { 158 | return key 159 | } 160 | return getPropAccessNotation(key) 161 | }) 162 | .join('') 163 | return pathString 164 | } 165 | function getPropAccessNotation(key: unknown): `.${string}` | `[${string}]` { 166 | return typeof key === 'string' && isKeyDotNotationCompatible(key) ? `.${key}` : `[${JSON.stringify(key)}]` 167 | } 168 | function isKeyDotNotationCompatible(key: string): boolean { 169 | return /^[a-z0-9\$_]+$/i.test(key) 170 | } 171 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export { types } 2 | 3 | const types: readonly Type[] = [ 4 | ts({ 5 | is: (val) => val === undefined, 6 | match: (str) => str === '!undefined', 7 | serialize: () => '!undefined', 8 | deserialize: (): undefined => undefined, 9 | }), 10 | ts({ 11 | is: (val) => val === Infinity, 12 | match: (str) => str === '!Infinity', 13 | serialize: () => '!Infinity', 14 | deserialize: (): typeof Infinity => Infinity, 15 | }), 16 | ts({ 17 | is: (val) => val === -Infinity, 18 | match: (str) => str === '!-Infinity', 19 | serialize: () => '!-Infinity', 20 | deserialize: (): number => -Infinity, 21 | }), 22 | ts({ 23 | is: (val) => typeof val === 'number' && isNaN(val), 24 | match: (str) => str === '!NaN', 25 | serialize: () => '!NaN', 26 | deserialize: () => NaN, 27 | }), 28 | ts({ 29 | is: (val) => val instanceof Date, 30 | match: (str) => str.startsWith('!Date:'), 31 | serialize: (val: Date) => '!Date:' + val.toISOString(), 32 | deserialize: (str) => new Date(str.slice('!Date:'.length)), 33 | }), 34 | ts({ 35 | is: (val) => typeof val === 'bigint', 36 | match: (str) => str.startsWith('!BigInt:'), 37 | serialize: (val: BigInt) => '!BigInt:' + val.toString(), 38 | deserialize: (str) => { 39 | if (typeof BigInt === 'undefined') { 40 | throw new Error('Your JavaScript environement does not support BigInt. Consider adding a polyfill.') 41 | } 42 | return BigInt(str.slice('!BigInt:'.length)) 43 | }, 44 | }), 45 | ts({ 46 | is: (val) => val instanceof RegExp, 47 | match: (str) => str.startsWith('!RegExp:'), 48 | serialize: (val: RegExp) => '!RegExp:' + val.toString(), 49 | deserialize: (str) => { 50 | str = str.slice('!RegExp:'.length) 51 | // const args: string[] = str.match(/\/(.*?)\/([gimy])?$/)! 52 | const args: string[] = str.match(/\/(.*)\/(.*)?/)! 53 | const pattern: string = args[1]! 54 | const flags: string = args[2]! 55 | return new RegExp(pattern, flags) 56 | }, 57 | }), 58 | ts({ 59 | is: (val) => val instanceof Map, 60 | match: (str) => str.startsWith('!Map:'), 61 | serialize: (val: Map, serializer: (val: [unknown, unknown][]) => string) => 62 | '!Map:' + serializer(Array.from(val.entries())), 63 | deserialize: (str, deserializer) => new Map(deserializer(str.slice('!Map:'.length))), 64 | }), 65 | ts({ 66 | is: (val) => val instanceof Set, 67 | match: (str) => str.startsWith('!Set:'), 68 | serialize: (val: Set, serializer: (val: unknown[]) => string) => 69 | '!Set:' + serializer(Array.from(val.values())), 70 | deserialize: (str, deserializer) => new Set(deserializer(str.slice('!Set:'.length))), 71 | }), 72 | // Avoid collisions with the special strings defined above 73 | ts({ 74 | is: (val) => typeof val === 'string' && val.startsWith('!'), 75 | match: (str) => str.startsWith('!'), 76 | serialize: (val: string) => '!' + val, 77 | deserialize: (str) => str.slice(1), 78 | }), 79 | ] as const 80 | 81 | type Type = { 82 | is: (val: unknown) => asserts val is ValueType 83 | match: (str: string) => boolean 84 | serialize: (val: ValueType, serializer: (val: IntermediateType) => string) => string 85 | deserialize: (str: string, deserializer: (str: string) => IntermediateType) => ValueType 86 | } 87 | 88 | // Type check 89 | function ts(t: Type) { 90 | return t 91 | } 92 | -------------------------------------------------------------------------------- /src/utils/isCallable.ts: -------------------------------------------------------------------------------- 1 | export function isCallable unknown>(thing: T | unknown): thing is T { 2 | return thing instanceof Function || typeof thing === 'function' 3 | } 4 | -------------------------------------------------------------------------------- /src/utils/isKeyDotNotationCompatible.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brillout/json-serializer/8bd28acac5c03c784bb71ddfd3b1933545e18a05/src/utils/isKeyDotNotationCompatible.ts -------------------------------------------------------------------------------- /src/utils/isObject.ts: -------------------------------------------------------------------------------- 1 | export { isObject } 2 | 3 | type Object = Record 4 | 5 | function isObject(value: unknown): value is Object { 6 | if (typeof value !== 'object' || value === null) { 7 | return false 8 | } 9 | if (Array.isArray(value)) { 10 | return false 11 | } 12 | return true 13 | } 14 | -------------------------------------------------------------------------------- /src/utils/isReactElement.ts: -------------------------------------------------------------------------------- 1 | export function isReactElement(value: unknown) { 2 | return ( 3 | typeof value === 'object' && 4 | value !== null && 5 | String((value as Record)['$$typeof']) === 'Symbol(react.element)' 6 | ) 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/replacerWithPath.ts: -------------------------------------------------------------------------------- 1 | export { replacerWithPath } 2 | export type { Iterable } 3 | export type { Path } 4 | 5 | // https://stackoverflow.com/questions/61681176/json-stringify-replacer-how-to-get-full-path/63957172#63957172 6 | 7 | type Path = (string | number)[] 8 | type Iterable = Record 9 | type Replacer = (this: Iterable, key: string, value: unknown, path: Path) => unknown 10 | function replacerWithPath(replacer: Replacer) { 11 | const pathMap = new WeakMap() 12 | return function (this: Iterable, key: string, value: unknown) { 13 | const pathPrevious = pathMap.get(this) ?? [] 14 | const path = [...pathPrevious] 15 | if (key !== '') { 16 | const pathEntry = !Array.isArray(this) ? key : parseInt(key, 10) 17 | path.push(pathEntry) 18 | } 19 | if (isIterable(value)) pathMap.set(value, path) 20 | return replacer.call(this, key, value, path) 21 | } 22 | } 23 | function isIterable(value: unknown): value is Iterable { 24 | return value === Object(value) 25 | } 26 | -------------------------------------------------------------------------------- /stringify.d.ts: -------------------------------------------------------------------------------- 1 | // Help TS's resolver until it supports `package.json#exports` 2 | export * from './dist/esm/stringify' 3 | -------------------------------------------------------------------------------- /stringify.js: -------------------------------------------------------------------------------- 1 | // Some tools don't support `package.json#exports`, such as: 2 | // - Nuxt v2 3 | // - Expo/Metro 4 | // - ESLint 5 | // prettier-ignore 6 | // biome-ignore format: 7 | 'use strict'; 8 | // prettier-ignore 9 | // biome-ignore format: 10 | exports.stringify = require('./dist/cjs/stringify.js').stringify; 11 | -------------------------------------------------------------------------------- /test/error-handling.spec.js: -------------------------------------------------------------------------------- 1 | import { stringify } from '../src/stringify' 2 | import { expect, describe, it, beforeAll } from 'vitest' 3 | import assert from 'assert' 4 | import React from 'react' 5 | 6 | // Prettify inline snapshots 7 | beforeAll(() => { 8 | const test = (val) => typeof val === 'string' 9 | expect.addSnapshotSerializer({ 10 | serialize(val) { 11 | assert(test(val)) 12 | return val 13 | }, 14 | test, 15 | }) 16 | }) 17 | 18 | describe('error handling', () => { 19 | it('error serializing function', () => { 20 | { 21 | let err 22 | try { 23 | console.log(stringify(function helloFn() {})) 24 | } catch (_err) { 25 | err = _err 26 | } 27 | expect(err.message).toMatchInlineSnapshot( 28 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize helloFn because it's a function.`, 29 | ) 30 | } 31 | 32 | { 33 | let err 34 | try { 35 | console.log(stringify(() => {})) 36 | } catch (_err) { 37 | err = _err 38 | } 39 | expect(err.message).toMatchInlineSnapshot( 40 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize value because it's a function.`, 41 | ) 42 | } 43 | }) 44 | it('error serializing React element', () => { 45 | const reactElement = React.createElement('div') 46 | { 47 | let err 48 | try { 49 | console.log(stringify(reactElement, { forbidReactElements: true })) 50 | } catch (_err) { 51 | err = _err 52 | } 53 | expect(err.message).toMatchInlineSnapshot( 54 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize value because it's a React element.`, 55 | ) 56 | } 57 | }) 58 | it('error path', () => { 59 | { 60 | let err 61 | try { 62 | console.log(stringify({ prop: React.createElement(React.Fragment) }, { forbidReactElements: true })) 63 | } catch (_err) { 64 | err = _err 65 | } 66 | expect(err.message).toMatchInlineSnapshot( 67 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize prop because it's a React element.`, 68 | ) 69 | } 70 | 71 | { 72 | let err 73 | try { 74 | console.log(stringify({ foo() {} }, { forbidReactElements: true })) 75 | } catch (_err) { 76 | err = _err 77 | } 78 | expect(err.message).toMatchInlineSnapshot( 79 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize foo because it's a function.`, 80 | ) 81 | } 82 | 83 | { 84 | let err 85 | try { 86 | console.log(stringify({ foo: () => {} }, { forbidReactElements: true })) 87 | } catch (_err) { 88 | err = _err 89 | } 90 | expect(err.message).toMatchInlineSnapshot( 91 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize foo because it's a function.`, 92 | ) 93 | } 94 | 95 | { 96 | let err 97 | try { 98 | console.log( 99 | stringify({ some: { nested: { prop: React.createElement(React.Fragment) } } }, { forbidReactElements: true }), 100 | ) 101 | } catch (_err) { 102 | err = _err 103 | } 104 | expect(err.message).toMatchInlineSnapshot( 105 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize some.nested.prop because it's a React element.`, 106 | ) 107 | } 108 | 109 | { 110 | let err 111 | try { 112 | console.log(stringify({ some: { nested: { prop: () => {} } } })) 113 | //console.log(stringify({someProp: function helloFn() {}})) 114 | } catch (_err) { 115 | err = _err 116 | } 117 | expect(err.message).toMatchInlineSnapshot( 118 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize some.nested.prop because it's a function.`, 119 | ) 120 | } 121 | 122 | { 123 | let err 124 | try { 125 | console.log(stringify({ someProp: function helloFn() {} })) 126 | } catch (_err) { 127 | err = _err 128 | } 129 | expect(err.message).toMatchInlineSnapshot( 130 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize someProp because it's a function.`, 131 | ) 132 | } 133 | 134 | { 135 | let err 136 | try { 137 | console.log( 138 | stringify( 139 | { 140 | title: { 141 | env: 'server-and-client', 142 | }, 143 | onBeforeRenderIsomorph: { 144 | env: 'config-only', 145 | effect() {}, 146 | }, 147 | }, 148 | { valueName: 'config["meta"]' }, 149 | ), 150 | ) 151 | } catch (_err) { 152 | err = _err 153 | } 154 | expect(err.message).toMatchInlineSnapshot( 155 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize config["meta"].onBeforeRenderIsomorph.effect because it's a function.`, 156 | ) 157 | } 158 | 159 | { 160 | let err 161 | try { 162 | console.log( 163 | stringify({ 164 | passToClient: ['pageProps', 'title', 'someAsyncProps'], 165 | clientRouting: true, 166 | hydrationCanBeAborted: true, 167 | meta: { 168 | title: { 169 | env: 'server-and-client', 170 | }, 171 | onBeforeRenderIsomorph: { 172 | env: 'config-only', 173 | effect() {}, 174 | }, 175 | }, 176 | }), 177 | ) 178 | } catch (_err) { 179 | err = _err 180 | } 181 | expect(err.message).toMatchInlineSnapshot( 182 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize meta.onBeforeRenderIsomorph.effect because it's a function.`, 183 | ) 184 | } 185 | 186 | { 187 | let err 188 | try { 189 | console.log(stringify(['ii', { ['a.b']: { C: { ['s s']: { [0]: { ['a)']: [{ f0$_() {} }] } } } } }])) 190 | } catch (_err) { 191 | err = _err 192 | } 193 | expect(err.message).toMatchInlineSnapshot( 194 | `[@brillout/json-serializer](https://github.com/brillout/json-serializer) cannot serialize [1]["a.b"].C["s s"].0["a)"][0].f0$_ because it's a function.`, 195 | ) 196 | } 197 | }) 198 | }) 199 | -------------------------------------------------------------------------------- /test/misc.spec.js: -------------------------------------------------------------------------------- 1 | import { parse } from '../src/parse' 2 | import { stringify } from '../src/stringify' 3 | import { describe, it } from 'vitest' 4 | import assert from 'assert' 5 | 6 | describe('escaping', () => { 7 | it('avoids collision with character `!`', () => { 8 | ;['!undefined', '!Date:2021-01-12T21:22:42.143Z', '!NaN', '!Infinity', `!RegExp:/^\d+$/g`].forEach((val) => { 9 | assert(stringify(val) === `"!${val}"`) 10 | assert(parse(stringify(val)) === val) 11 | assert(parse(stringify({ val })).val === val) 12 | assert(parse(stringify({ val: { val } })).val.val === val) 13 | }) 14 | }) 15 | }) 16 | 17 | describe('sortObjectKeys option', () => { 18 | it('works', () => { 19 | // Basic test 20 | { 21 | const obj = { 22 | b: 2, 23 | a: 1, 24 | } 25 | { 26 | const keys = Object.keys(obj) 27 | assert(keys[0] === 'b') 28 | } 29 | { 30 | const copy = parse(stringify(obj)) 31 | const keys = Object.keys(copy) 32 | assert(keys[0] === 'b') 33 | } 34 | { 35 | const copy = parse(stringify(obj, { sortObjectKeys: true })) 36 | const keys = Object.keys(copy) 37 | assert(keys[0] === 'a') 38 | } 39 | } 40 | 41 | // Nested test 42 | { 43 | const obj = { 44 | a: { 45 | d: 2, 46 | c: 3, 47 | }, 48 | } 49 | { 50 | const keys = Object.keys(obj.a) 51 | assert(keys[0] === 'd') 52 | } 53 | { 54 | const copy = parse(stringify(obj)) 55 | const keys = Object.keys(copy.a) 56 | assert(keys[0] === 'd') 57 | } 58 | { 59 | const copy = parse(stringify(obj, { sortObjectKeys: true })) 60 | const keys = Object.keys(copy.a) 61 | assert(keys[0] === 'c') 62 | } 63 | } 64 | }) 65 | }) 66 | -------------------------------------------------------------------------------- /test/serialize.spec.js: -------------------------------------------------------------------------------- 1 | import { parse } from '../src/parse' 2 | import { stringify } from '../src/stringify' 3 | import { describe, it } from 'vitest' 4 | import assert from 'assert' 5 | 6 | describe('serialize', () => { 7 | it('undefined', () => { 8 | assert(parse(stringify(undefined)) === undefined) 9 | assert(parse(stringify({ prop: undefined })).prop === undefined) 10 | assert('prop' in parse(stringify({ prop: undefined }))) 11 | }) 12 | it('Date', () => { 13 | const now = new Date() 14 | assert(parse(stringify(now)).getTime() === now.getTime()) 15 | assert(parse(stringify({ now })).now.getTime() === now.getTime()) 16 | }) 17 | it('NaN', () => { 18 | assert(isNaN(parse(stringify(NaN)))) 19 | assert(isNaN(parse(stringify({ is: { nan: NaN } })).is.nan)) 20 | }) 21 | it('Infinity', () => { 22 | assert(parse(stringify(Infinity)) === Infinity) 23 | assert(parse(stringify({ sideProp: 42, is: { inf: Infinity } })).is.inf === Infinity) 24 | }) 25 | it('Negative Infinity', () => { 26 | assert(parse(stringify(-Infinity)) === -Infinity) 27 | assert(parse(stringify({ sideProp: 42, is: { inf: -Infinity } })).is.inf === -Infinity) 28 | }) 29 | it('RegExp', () => { 30 | const regex = /^\d+$/ 31 | const regex_copy = parse(stringify(regex)) 32 | assert(regex.test('42') === true) 33 | assert(regex_copy.test('42') === true) 34 | assert(regex.test('a') === false) 35 | assert(regex_copy.test('a') === false) 36 | }) 37 | it('Set', () => { 38 | const s1 = new Set([42, '7', 42]) 39 | const s2 = parse(stringify(s1)) 40 | const s1_values = Array.from(s1.values()) 41 | const s2_values = Array.from(s2.values()) 42 | assert(s1_values[0] === s2_values[0]) 43 | assert(s1_values[1] === s2_values[1]) 44 | assert(s1_values.length === s2_values.length) 45 | assert(s1.has(42) === true) 46 | assert(s2.has(42) === true) 47 | assert(s1.has('7') === true) 48 | assert(s2.has('7') === true) 49 | }) 50 | it('Map', () => { 51 | const m1 = new Map([[{ a: undefined }, [null, undefined, 42]]]) 52 | const m2 = parse(stringify(m1)) 53 | const m1_entries = Array.from(m1.entries()) 54 | const m2_entries = Array.from(m2.entries()) 55 | assert(m1_entries[0][0].a === undefined) 56 | assert(m2_entries[0][0].a === undefined) 57 | assert(m1_entries[0][1][2] === 42) 58 | assert(m2_entries[0][1][2] === 42) 59 | assert(m1_entries.length === m2_entries.length) 60 | }) 61 | it('BigInt', () => { 62 | assert(parse(stringify(BigInt('42'))) === BigInt('42')) 63 | }) 64 | }) 65 | -------------------------------------------------------------------------------- /test/user-defined-replacer.spec.ts: -------------------------------------------------------------------------------- 1 | import { stringify } from '../src/stringify' 2 | import { expect, describe, it } from 'vitest' 3 | 4 | describe('user-defined replacer', () => { 5 | it('works', () => { 6 | expect( 7 | stringify( 8 | { icon: 'import:/assets/logo.svg:default', title: 'Hello' }, 9 | { 10 | replacer(_key, value) { 11 | if (typeof value === 'string' && value.startsWith('import:')) { 12 | return { replacement: 'import42' } 13 | } 14 | }, 15 | }, 16 | ), 17 | ).toBe('{"icon":"import42","title":"Hello"}') 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist/cjs/", 5 | "target": "ES2017", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Output 4 | "target": "ES2020", 5 | "module": "ES2020", 6 | "moduleResolution": "Node", 7 | "outDir": "dist/esm/", 8 | // User-code 9 | "strict": true, 10 | // Source Maps 11 | "declaration": true, 12 | "rootDir": "./src/" 13 | }, 14 | "include": ["./src/**/*"] 15 | } 16 | --------------------------------------------------------------------------------