├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bun.lock ├── package.json ├── src ├── config │ ├── getConfig.ts │ ├── parseSelector.ts │ └── types.ts ├── index.ts ├── parser │ ├── extractValue.ts │ ├── getArrayValue.ts │ ├── getElement.ts │ ├── getRawConfig.ts │ ├── getSchemaValue.ts │ ├── getSimpleValue.ts │ ├── getValue.ts │ ├── methods │ │ ├── boolean.ts │ │ ├── email.ts │ │ ├── float.ts │ │ ├── index.ts │ │ ├── length.ts │ │ ├── lowercase.ts │ │ ├── number.ts │ │ ├── uppercase.ts │ │ └── url.ts │ ├── parse.ts │ ├── regex │ │ ├── constant.ts │ │ └── execRegex.ts │ ├── transformValue.ts │ ├── types.ts │ └── value.ts └── utils │ └── omit.ts ├── tests ├── execRegex.spec.ts ├── getArrayValue.spec.ts ├── getConfig.spec.ts ├── getElement.spec.ts ├── getSchemaValue.spec.ts ├── getSimpleValue.spec.ts ├── getValue.spec.ts ├── parse.spec.ts ├── parseSelector.spec.ts ├── transformValue.spec.ts └── utils.spec.ts ├── tsconfig.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | build/ -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["@typescript-eslint", "prettier"], 5 | "extends": [ 6 | "eslint:recommended", 7 | "plugin:@typescript-eslint/eslint-recommended", 8 | "plugin:@typescript-eslint/recommended", 9 | "prettier" 10 | ], 11 | "rules": { 12 | "no-console": 1, // Means warning 13 | "prettier/prettier": 2, // Means error 14 | "@typescript-eslint/no-explicit-any": 0, 15 | "@typescript-eslint/explicit-module-boundary-types": "off" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout Repository 11 | uses: actions/checkout@v3 12 | 13 | - name: Setup Bun 14 | uses: oven-sh/setup-bun@v1 15 | with: 16 | bun-version: latest 17 | 18 | - name: Install dependencies 19 | run: bun install 20 | 21 | - name: Run tests 22 | run: bun test 23 | 24 | - name: Build 25 | run: bun run build 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | node_modules/ 3 | .DS_Store 4 | coverage/ -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | .github/ 3 | .prettierrc 4 | .eslintrc 5 | .eslintignore 6 | tsconfig.json 7 | src/ 8 | CHANGELOG.md 9 | jest.config.js 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "none", 4 | "singleQuote": true, 5 | "printWidth": 80 6 | } 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | v1.0.0 2 | 3 | #### Breaking changes 4 | - Bump cheerio version to `1.0.0`. 5 | 6 | Since cheerio `1.0.0` no longer exports `Element`, it needs to be imported from `domhandler` directly. 7 | 8 | Before: 9 | ```ts 10 | import { type Cheerio, type CheerioAPI, type Element } from 'cheerio'; 11 | ``` 12 | 13 | After: 14 | ```ts 15 | import { type Cheerio, type CheerioAPI } from 'cheerio'; 16 | import { type Element } from 'domhandler'; 17 | ``` 18 | 19 | v0.23.0 20 | 21 | #### Enhancements 22 | 23 | - DX Improved. 24 | - Optimized performance. 25 | 26 | #### Maintenance 27 | 28 | - Updated code quality. 29 | - Updated tests. 30 | - Fixed types. 31 | - Fixed coverage script. 32 | 33 | v0.22.0 34 | 35 | - DX Improved. 36 | - CheerioOptions and Fragment Mode support added. 37 | 38 | ```ts 39 | parse(data, config, options?: CheerioOptions, isDocument?: boolean) 40 | ``` 41 | 42 | v0.21.0 43 | 44 | - Dependencies updated. 45 | - Naming improved. 46 | - Micro optimizations performed. 47 | 48 | v0.20.0 49 | 50 | - Code refactor 51 | - `TypeScript` upgrade to `v5.3.3` 52 | 53 | v0.19.0 54 | 55 | - The `fill` property now accepts falsy values other than `undefined`. 56 | 57 | ```ts 58 | { 59 | fill: null | false | ''; 60 | } 61 | ``` 62 | 63 | v0.18.0 64 | 65 | - Add `element` parameter to `transform` 66 | 67 | v0.17.0 68 | 69 | - Add `arrayTransform` support. 70 | 71 | v0.16.0 72 | 73 | - Add `CheerioAPI` as second parameter to `SchemaGenerator` 74 | 75 | ```ts 76 | schema: (el: Cheerio, $: CheerioAPI) => {}; 77 | ``` 78 | 79 | v0.15.0 80 | 81 | - Remove unused `validateConfig` feature. 82 | - Update dependencies. 83 | - Update npmignore file. 84 | 85 | v0.14.0 86 | 87 | - Add multiple attribute support. 88 | 89 | v0.13.0 90 | 91 | - Rename `ignore-kids` option as `ignore-children`. 92 | 93 | v0.12.4 94 | 95 | - **Fix:** Empty selectors handled. 96 | 97 | v0.12.3 98 | 99 | - Make `selector` property optional and accept `Selector[]` as `Config` 100 | 101 | v0.12.2 102 | 103 | - Schema props are set to `null` when selectors do not return a match. 104 | 105 | v0.12.1 106 | 107 | - Added basic schema extract test. 108 | 109 | v0.12.0: 110 | 111 | - Rename `size` method with `length`. 112 | 113 | v0.11.0: 114 | 115 | - The `InputConfig` removed. 116 | - The `Config` `interface` converted to a `type` and replaced the `InputConfig`. 117 | - `Selector` can only be `string` (was `string | string[]`) 118 | - `transform` function takes `Value` as argument, instead of `any`. 119 | - `ConfigFunction` renamed to `SchemaGenerator`. 120 | - `RawConfig.schema`'s type is set to `SchemaGenerator | Schema`. 121 | - `getSelector` renamed to `parseSelector`. 122 | 123 | v0.9.1: 124 | 125 | - Ignored `null` values returned from `cheerio.html()`. 126 | 127 | v0.9.0: 128 | 129 | - Added `ignoreIntersectingElements?: 'ignore-kids' | 'ignore-parents';` to `RawConfig`. 130 | - Converted `RawConfig` and `Config` classes to `interface`. 131 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Muninn is an open-source project committed to providing a welcoming and inclusive environment for all contributors, regardless of their background, identity, or beliefs. As a community, we value respect, collaboration, and diversity. We expect all participants to adhere to the following Code of Conduct when interacting with others in the Muninn community. 4 | 5 | ### Respect and Courtesy 6 | 7 | Treat all individuals with respect and kindness. Use inclusive language and avoid derogatory or offensive remarks or behavior. 8 | 9 | ### Open-mindedness 10 | 11 | Be open to feedback and differing perspectives. Listen actively and considerately to others' opinions, even if you do not agree with them. 12 | 13 | ### Collaborative Spirit 14 | 15 | Work collaboratively with others, both within and outside of the Muninn community. Encourage and support each other in our shared goals. 16 | 17 | ### Inclusivity 18 | 19 | We welcome and encourage contributions from individuals of all backgrounds and identities. Discrimination or harassment of any kind will not be tolerated. 20 | 21 | ### Professionalism 22 | 23 | Conduct yourself professionally in all interactions related to the Muninn project. Avoid conflicts of interest and maintain confidentiality where appropriate. 24 | 25 | ### Responsibility 26 | 27 | Take responsibility for your actions and words. If you make a mistake, own up to it and work to correct it. If you see others violating this Code of Conduct, speak up and report it to the Muninn team. 28 | 29 | We believe that the Muninn community can only thrive if we all work together to create an environment that is welcoming and inclusive. By adhering to this Code of Conduct, we can foster a positive and productive community where all individuals can contribute and feel valued. 30 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Muninn 2 | 3 | Welcome! We're thrilled that you're interested in contributing to Muninn. This document outlines the contribution guidelines and explains how to set up your development environment to get started. 4 | 5 | ## Getting Started 6 | 7 | To contribute to Muninn, you'll need to follow these steps: 8 | 9 | - Fork the repository 10 | - Clone your forked repository locally 11 | - Install dependencies 12 | - Create a new branch for your contribution 13 | - Make your changes 14 | - Test your changes 15 | - Push your changes to your forked repository 16 | - Submit a pull request to the main repository 17 | 18 | ## Code of Conduct 19 | 20 | We have a [Code of Conduct](./CODE_OF_CONDUCT.md) in place to ensure that everyone in our community feels welcome and respected. By participating in this project, you agree to abide by its terms. 21 | 22 | ## Issues 23 | 24 | If you've found a bug or have an idea for a new feature, please open an issue in our issue tracker. Before opening a new issue, please search the existing issues to see if someone else has already reported the same problem or requested the same feature. When opening a new issue, please provide as much detail as possible so that we can better understand and address your concern. 25 | 26 | ## Pull Requests 27 | 28 | We welcome pull requests from everyone. When submitting a pull request, please: 29 | 30 | - Create a new branch for your changes 31 | - Use clear and concise commit messages 32 | - Provide a detailed description of your changes 33 | - Ensure that your code passes all tests 34 | - Rebase your branch on the latest commit of the main repository 35 | 36 | ## License 37 | 38 | By contributing to Muninn, you agree that your contributions will be licensed under the [MIT](./LICENSE) license. 39 | 40 | ## Conclusion 41 | 42 | Thank you for your interest in contributing to Muninn. We appreciate your help in making our project better. If you have any questions or concerns, please do not hesitate to contact us. 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2021 wope.com 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Muninn 2 | 3 | [![npm](https://img.shields.io/npm/v/muninn?color=%234fc921)](https://www.npmjs.com/package/muninn) 4 | [![Build Status](https://github.com/teamseodo/muninn/workflows/build/badge.svg?color=%234fc921)](https://github.com/teamseodo/muninn/actions) 5 | [![License](https://img.shields.io/badge/License-MIT-green.svg?color=%234fc921)](https://opensource.org/licenses/MIT) 6 | 7 | Muninn is a fast and flexible HTML parsing tool that simplifies the process of extracting data from HTMLs. It allows you to create a configuration file, making it easy to keep parser settings up to date even when selectors change. With its easy-to-learn syntax and the power of the [cheerio](https://github.com/cheeriojs/cheerio) library for parsing, Muninn is a versatile solution for various parsing needs. 8 | 9 | ### Features 10 | 11 | - Fast and efficient HTML parsing 12 | - Easy-to-learn syntax for creating parser configurations 13 | - Flexibility to handle changing selectors 14 | - Powered by the popular [cheerio](https://github.com/cheeriojs/cheerio) library 15 | 16 |
17 | 18 | ### [Documentation](https://seodo.gitbook.io/muninn/) - [Changelog](/CHANGELOG.md) 19 | 20 |
21 | 22 | ## Sample 23 | 24 | ```js 25 | import { parse } from 'muninn'; 26 | 27 | const config = { 28 | schema: { 29 | title: '#productTitle', 30 | price: '#priceblock_ourprice', 31 | rating: { 32 | selector: '#acrPopover span | float', 33 | regex: /\d+\.?\d?/ 34 | }, 35 | features: { 36 | selector: '#productOverview_feature_div tr.a-spacing-small | array', 37 | schema: { 38 | name: 'td:nth-child(1)', 39 | value: 'td:nth-child(2)' 40 | } 41 | } 42 | } 43 | }; 44 | 45 | // The `data` is an HTML Content of type string. 46 | // https://www.amazon.com/AMD-Ryzen-3700X-16-Thread-Processor/dp/B07SXMZLPK/ 47 | const data = '...'; 48 | 49 | const result = parse(data, config); 50 | ``` 51 | 52 | ### Output 53 | 54 | ```js 55 | { 56 | "title": "AMD Ryzen 7 3700X 8-Core, 16-Thread Unlocked Desktop Processor with Wraith Prism LED Cooler", 57 | "price": "$308.99", 58 | "rating": 4.9, 59 | "features": [ 60 | { 61 | "name": "Brand", 62 | "value": "AMD" 63 | }, 64 | { 65 | "name": "CPU Model", 66 | "value": "AMD Ryzen 7" 67 | }, 68 | { 69 | "name": "CPU Speed", 70 | "value": "4.4 GHz" 71 | }, 72 | { 73 | "name": "CPU Socket", 74 | "value": "Socket AM4" 75 | }, 76 | { 77 | "name": "Processor Count", 78 | "value": "8" 79 | } 80 | ] 81 | } 82 | ``` 83 | 84 | ## License 85 | 86 | Distributed under the MIT License. See LICENSE for more information. 87 | -------------------------------------------------------------------------------- /bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1, 3 | "workspaces": { 4 | "": { 5 | "name": "muninn", 6 | "dependencies": { 7 | "cheerio": "1.0.0-rc.12", 8 | }, 9 | "devDependencies": { 10 | "@types/bun": "^1.0.8", 11 | "@types/node": "^20.10.5", 12 | "@typescript-eslint/eslint-plugin": "^7.0.2", 13 | "@typescript-eslint/parser": "^7.0.2", 14 | "eslint": "^8.56.0", 15 | "eslint-config-prettier": "^9.1.0", 16 | "eslint-plugin-prettier": "^5.1.2", 17 | "prettier": "^3.1.1", 18 | "ts-node": "^10.9.2", 19 | "typescript": "^5.3.3", 20 | }, 21 | }, 22 | }, 23 | "packages": { 24 | "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], 25 | 26 | "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA=="], 27 | 28 | "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], 29 | 30 | "@eslint/eslintrc": ["@eslint/eslintrc@2.1.4", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ=="], 31 | 32 | "@eslint/js": ["@eslint/js@8.57.1", "", {}, "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="], 33 | 34 | "@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.13.0", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw=="], 35 | 36 | "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], 37 | 38 | "@humanwhocodes/object-schema": ["@humanwhocodes/object-schema@2.0.3", "", {}, "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA=="], 39 | 40 | "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], 41 | 42 | "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], 43 | 44 | "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], 45 | 46 | "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], 47 | 48 | "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], 49 | 50 | "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], 51 | 52 | "@pkgr/core": ["@pkgr/core@0.1.1", "", {}, "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA=="], 53 | 54 | "@tsconfig/node10": ["@tsconfig/node10@1.0.11", "", {}, "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="], 55 | 56 | "@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="], 57 | 58 | "@tsconfig/node14": ["@tsconfig/node14@1.0.3", "", {}, "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="], 59 | 60 | "@tsconfig/node16": ["@tsconfig/node16@1.0.4", "", {}, "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="], 61 | 62 | "@types/bun": ["@types/bun@1.2.2", "", { "dependencies": { "bun-types": "1.2.2" } }, "sha512-tr74gdku+AEDN5ergNiBnplr7hpDp3V1h7fqI2GcR/rsUaM39jpSeKH0TFibRvU0KwniRx5POgaYnaXbk0hU+w=="], 63 | 64 | "@types/node": ["@types/node@20.17.17", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-/WndGO4kIfMicEQLTi/mDANUu/iVUhT7KboZPdEqqHQ4aTS+3qT3U5gIqWDFV+XouorjfgGqvKILJeHhuQgFYg=="], 65 | 66 | "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="], 67 | 68 | "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@7.18.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/type-utils": "7.18.0", "@typescript-eslint/utils": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "peerDependencies": { "@typescript-eslint/parser": "^7.0.0", "eslint": "^8.56.0" } }, "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw=="], 69 | 70 | "@typescript-eslint/parser": ["@typescript-eslint/parser@7.18.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", "@typescript-eslint/typescript-estree": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg=="], 71 | 72 | "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0" } }, "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA=="], 73 | 74 | "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@7.18.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "7.18.0", "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA=="], 75 | 76 | "@typescript-eslint/types": ["@typescript-eslint/types@7.18.0", "", {}, "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ=="], 77 | 78 | "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" } }, "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA=="], 79 | 80 | "@typescript-eslint/utils": ["@typescript-eslint/utils@7.18.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", "@typescript-eslint/typescript-estree": "7.18.0" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw=="], 81 | 82 | "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" } }, "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg=="], 83 | 84 | "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], 85 | 86 | "acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], 87 | 88 | "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], 89 | 90 | "acorn-walk": ["acorn-walk@8.3.4", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="], 91 | 92 | "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], 93 | 94 | "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 95 | 96 | "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], 97 | 98 | "arg": ["arg@4.1.3", "", {}, "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="], 99 | 100 | "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], 101 | 102 | "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], 103 | 104 | "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 105 | 106 | "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], 107 | 108 | "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], 109 | 110 | "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], 111 | 112 | "bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="], 113 | 114 | "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], 115 | 116 | "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], 117 | 118 | "cheerio": ["cheerio@1.0.0-rc.12", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "htmlparser2": "^8.0.1", "parse5": "^7.0.0", "parse5-htmlparser2-tree-adapter": "^7.0.0" } }, "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q=="], 119 | 120 | "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], 121 | 122 | "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], 123 | 124 | "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], 125 | 126 | "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], 127 | 128 | "create-require": ["create-require@1.1.1", "", {}, "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="], 129 | 130 | "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], 131 | 132 | "css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="], 133 | 134 | "css-what": ["css-what@6.1.0", "", {}, "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="], 135 | 136 | "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], 137 | 138 | "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], 139 | 140 | "diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="], 141 | 142 | "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], 143 | 144 | "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="], 145 | 146 | "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], 147 | 148 | "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], 149 | 150 | "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], 151 | 152 | "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], 153 | 154 | "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], 155 | 156 | "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], 157 | 158 | "eslint": ["eslint@8.57.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.57.1", "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA=="], 159 | 160 | "eslint-config-prettier": ["eslint-config-prettier@9.1.0", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw=="], 161 | 162 | "eslint-plugin-prettier": ["eslint-plugin-prettier@5.2.3", "", { "dependencies": { "prettier-linter-helpers": "^1.0.0", "synckit": "^0.9.1" }, "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", "eslint-config-prettier": "*", "prettier": ">=3.0.0" }, "optionalPeers": ["@types/eslint", "eslint-config-prettier"] }, "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw=="], 163 | 164 | "eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="], 165 | 166 | "eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], 167 | 168 | "espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], 169 | 170 | "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], 171 | 172 | "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], 173 | 174 | "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], 175 | 176 | "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], 177 | 178 | "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 179 | 180 | "fast-diff": ["fast-diff@1.3.0", "", {}, "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="], 181 | 182 | "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], 183 | 184 | "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], 185 | 186 | "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], 187 | 188 | "fastq": ["fastq@1.19.0", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA=="], 189 | 190 | "file-entry-cache": ["file-entry-cache@6.0.1", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="], 191 | 192 | "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 193 | 194 | "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], 195 | 196 | "flat-cache": ["flat-cache@3.2.0", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw=="], 197 | 198 | "flatted": ["flatted@3.3.2", "", {}, "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA=="], 199 | 200 | "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], 201 | 202 | "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], 203 | 204 | "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], 205 | 206 | "globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], 207 | 208 | "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], 209 | 210 | "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], 211 | 212 | "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], 213 | 214 | "htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="], 215 | 216 | "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], 217 | 218 | "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], 219 | 220 | "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], 221 | 222 | "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], 223 | 224 | "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], 225 | 226 | "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], 227 | 228 | "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], 229 | 230 | "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], 231 | 232 | "is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="], 233 | 234 | "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 235 | 236 | "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], 237 | 238 | "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], 239 | 240 | "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], 241 | 242 | "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], 243 | 244 | "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], 245 | 246 | "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], 247 | 248 | "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], 249 | 250 | "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], 251 | 252 | "make-error": ["make-error@1.3.6", "", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="], 253 | 254 | "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], 255 | 256 | "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], 257 | 258 | "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], 259 | 260 | "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], 261 | 262 | "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 263 | 264 | "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], 265 | 266 | "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], 267 | 268 | "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], 269 | 270 | "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], 271 | 272 | "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], 273 | 274 | "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], 275 | 276 | "parse5": ["parse5@7.2.1", "", { "dependencies": { "entities": "^4.5.0" } }, "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ=="], 277 | 278 | "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="], 279 | 280 | "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], 281 | 282 | "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], 283 | 284 | "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], 285 | 286 | "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], 287 | 288 | "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 289 | 290 | "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], 291 | 292 | "prettier": ["prettier@3.4.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ=="], 293 | 294 | "prettier-linter-helpers": ["prettier-linter-helpers@1.0.0", "", { "dependencies": { "fast-diff": "^1.1.2" } }, "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w=="], 295 | 296 | "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], 297 | 298 | "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], 299 | 300 | "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], 301 | 302 | "reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="], 303 | 304 | "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], 305 | 306 | "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], 307 | 308 | "semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], 309 | 310 | "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], 311 | 312 | "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], 313 | 314 | "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], 315 | 316 | "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], 317 | 318 | "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], 319 | 320 | "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], 321 | 322 | "synckit": ["synckit@0.9.2", "", { "dependencies": { "@pkgr/core": "^0.1.0", "tslib": "^2.6.2" } }, "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw=="], 323 | 324 | "text-table": ["text-table@0.2.0", "", {}, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], 325 | 326 | "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 327 | 328 | "ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="], 329 | 330 | "ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="], 331 | 332 | "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], 333 | 334 | "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], 335 | 336 | "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="], 337 | 338 | "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="], 339 | 340 | "undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], 341 | 342 | "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], 343 | 344 | "v8-compile-cache-lib": ["v8-compile-cache-lib@3.0.1", "", {}, "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="], 345 | 346 | "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], 347 | 348 | "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], 349 | 350 | "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], 351 | 352 | "yn": ["yn@3.1.1", "", {}, "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="], 353 | 354 | "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], 355 | 356 | "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 357 | 358 | "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 359 | 360 | "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 361 | } 362 | } 363 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "muninn", 3 | "version": "1.0.0", 4 | "description": "It parses the html and collects the requested data as desired.", 5 | "main": "build/index.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "test": "bun test", 9 | "lint": "eslint . --ext .ts", 10 | "prettier-format": "prettier --config .prettierrc 'src/**/*.ts' --write" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/wopehq/muninn.git" 15 | }, 16 | "keywords": [ 17 | "htmlparser", 18 | "selector", 19 | "scraper", 20 | "parser", 21 | "cheerio", 22 | "html" 23 | ], 24 | "author": "wopehq ", 25 | "license": "MIT", 26 | "dependencies": { 27 | "cheerio": "^1.0.0" 28 | }, 29 | "devDependencies": { 30 | "@types/bun": "^1.0.8", 31 | "@types/node": "^20.10.5", 32 | "@typescript-eslint/eslint-plugin": "^7.0.2", 33 | "@typescript-eslint/parser": "^7.0.2", 34 | "eslint": "^8.56.0", 35 | "eslint-config-prettier": "^9.1.0", 36 | "eslint-plugin-prettier": "^5.1.2", 37 | "prettier": "^3.1.1", 38 | "ts-node": "^10.9.2", 39 | "typescript": "^5.3.3" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/config/getConfig.ts: -------------------------------------------------------------------------------- 1 | import parseSelector from './parseSelector'; 2 | import { type ElementPassArg } from '../parser/types'; 3 | import { type Config, type RawConfig } from './types'; 4 | 5 | function getConfig( 6 | { $, el }: ElementPassArg, 7 | config?: string 8 | ): ReturnType; 9 | function getConfig( 10 | { $, el }: ElementPassArg, 11 | config?: string[] 12 | ): ReturnType[]; 13 | function getConfig( 14 | { $, el }: ElementPassArg, 15 | config?: RawConfig 16 | ): RawConfig; 17 | function getConfig( 18 | { $, el }: ElementPassArg, 19 | config?: Config 20 | ): Config | Config[] { 21 | if (!config) { 22 | return { selector: '' }; 23 | } 24 | 25 | if (Array.isArray(config)) { 26 | return config.map((conf: string | RawConfig) => { 27 | if (typeof conf === 'string') { 28 | return parseSelector(conf); 29 | } 30 | 31 | return getConfig({ $, el }, conf); 32 | }); 33 | } 34 | 35 | if (typeof config === 'function') { 36 | const schema = config($ && el ? $(el) : null, $); 37 | 38 | config = { 39 | selector: '', 40 | schema 41 | }; 42 | } 43 | 44 | if (typeof config === 'string') { 45 | config = parseSelector(config); 46 | } else if (config?.selector) { 47 | config = { 48 | ...config, 49 | ...parseSelector(config.selector) 50 | }; 51 | } 52 | 53 | return config; 54 | } 55 | 56 | export default getConfig; 57 | -------------------------------------------------------------------------------- /src/config/parseSelector.ts: -------------------------------------------------------------------------------- 1 | import { type Selector, type RawConfig, type Method } from './types'; 2 | 3 | function parseSelector( 4 | selector: Selector 5 | ): RawConfig { 6 | const config: RawConfig = { selector: '' }; 7 | 8 | let $selector: string, methods: string[], attr: string | string[]; 9 | 10 | if (typeof selector !== 'string') { 11 | return selector; 12 | } 13 | 14 | if (selector.includes('|')) { 15 | [$selector, ...methods] = selector.split('|').map((key) => key.trim()); 16 | 17 | if (methods.length > 0) { 18 | const validMethods = [ 19 | 'boolean', 20 | 'float', 21 | 'number', 22 | 'length', 23 | 'lowercase', 24 | 'uppercase', 25 | 'email', 26 | 'url' 27 | ]; 28 | 29 | const acceptedMethods = methods.filter((method: string) => 30 | validMethods.includes(method) 31 | ) as Method[]; 32 | 33 | const type = methods.includes('array') ? 'array' : config.type; 34 | const html = methods.includes('html') ? true : config.html; 35 | const exist = methods.includes('exist') ? true : config.exist; 36 | 37 | let trim = config.trim; 38 | 39 | if (methods.includes('trim')) { 40 | trim = true; 41 | } else if (methods.includes('non-trim')) { 42 | trim = false; 43 | } 44 | 45 | if (type) config.type = type; 46 | if (html) config.html = html; 47 | if (exist) config.exist = exist; 48 | if (typeof trim === 'boolean') config.trim = trim; 49 | 50 | if (acceptedMethods.length > 0) { 51 | config.methods = acceptedMethods; 52 | } 53 | } 54 | } 55 | 56 | if ($selector === undefined) { 57 | $selector = selector; 58 | } 59 | 60 | if ($selector.includes('@')) { 61 | [$selector, attr] = $selector.split('@').map((key) => key.trim()); 62 | const attrs = attr.split(',').map((key) => key.trim()); 63 | attr = attrs.length > 1 ? attrs : attr; 64 | } 65 | 66 | if ($selector) 67 | config.selector = Array.isArray($selector) 68 | ? $selector.join(', ') 69 | : $selector; 70 | 71 | if (attr) config.attr = attr; 72 | 73 | return config; 74 | } 75 | 76 | export default parseSelector; 77 | -------------------------------------------------------------------------------- /src/config/types.ts: -------------------------------------------------------------------------------- 1 | import { type Cheerio, type CheerioAPI } from 'cheerio'; 2 | import { type Element } from 'domhandler'; 3 | import { type Value } from '../parser/value'; 4 | 5 | export type Selector = string; 6 | 7 | export type PreDefinedRegex = 'email' | 'url'; 8 | export type RegexObject = { pattern: string; flags?: string }; 9 | export type RegexConfig = PreDefinedRegex | RegexObject | RegExp; 10 | 11 | export type TransformFunction = ( 12 | value: Value, 13 | element?: Cheerio 14 | ) => Value; 15 | export type ConditionFunction = ($: CheerioAPI | Cheerio) => boolean; 16 | export interface Schema { 17 | [key: string]: Config; 18 | } 19 | export type SchemaGenerator = ( 20 | el: Cheerio, 21 | $: CheerioAPI 22 | ) => Schema; 23 | export type ElementFilterFunction = ( 24 | index: number, 25 | element: Cheerio | Element, 26 | $: CheerioAPI 27 | ) => boolean; 28 | 29 | export type Method = 30 | | 'boolean' 31 | | 'number' 32 | | 'float' 33 | | 'length' 34 | | 'lowercase' 35 | | 'uppercase' 36 | | 'email' 37 | | 'url'; 38 | 39 | export type Types = 'number' | 'float' | 'boolean' | 'array'; 40 | 41 | export interface RawConfig { 42 | selector?: Selector; 43 | html?: boolean; 44 | attr?: string | string[]; 45 | type?: Types; 46 | trim?: boolean; 47 | exist?: boolean; 48 | rootScope?: boolean; 49 | elementFilter?: ElementFilterFunction; 50 | initial?: Initial; 51 | fill?: any; 52 | methods?: Method[]; 53 | regex?: RegexConfig; 54 | transform?: TransformFunction; 55 | arrayTransform?: TransformFunction; 56 | condition?: ConditionFunction; 57 | schema?: SchemaGenerator | Schema; 58 | ignoreIntersectingElements?: 'ignore-children' | 'ignore-parents'; 59 | ignoreExistenceChecks?: boolean; 60 | } 61 | 62 | export type Config = 63 | | SchemaGenerator 64 | | RawConfig 65 | | RawConfig[] 66 | | Selector 67 | | Selector[]; 68 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import parse from './parser/parse'; 2 | import { type Schema } from './config/types'; 3 | 4 | export { parse, type Schema }; 5 | -------------------------------------------------------------------------------- /src/parser/extractValue.ts: -------------------------------------------------------------------------------- 1 | import { type RawConfig } from '../config/types'; 2 | import { type ElementPassArg } from './types'; 3 | 4 | function extractValue( 5 | { $, el }: ElementPassArg, 6 | config: RawConfig 7 | ) { 8 | const element = $(el); 9 | 10 | const { html, attr } = config; 11 | 12 | if (html) return element.html(); 13 | 14 | if (Array.isArray(attr)) { 15 | return attr.reduce((acc, arg) => { 16 | acc[arg] = element.attr(arg); 17 | return acc; 18 | }, {}); 19 | } 20 | 21 | if (attr === '$all') return element.attr(); 22 | if (attr) return element.attr(attr); 23 | 24 | return element.text(); 25 | } 26 | 27 | export default extractValue; 28 | -------------------------------------------------------------------------------- /src/parser/getArrayValue.ts: -------------------------------------------------------------------------------- 1 | import { type Cheerio, type CheerioAPI } from 'cheerio'; 2 | import { type Element } from 'domhandler'; 3 | import { type RawConfig } from '../config/types'; 4 | import { type ElementPassArg } from './types'; 5 | import getValue from './getValue'; 6 | import { omit } from '../utils/omit'; 7 | 8 | function getArrayValue( 9 | { $, el: element }: ElementPassArg, 10 | config: RawConfig 11 | ): any[] { 12 | const values = []; 13 | let elems: Cheerio | Cheerio[] = $(element); 14 | 15 | if (config?.elementFilter) { 16 | elems = elems.filter((index, el) => config.elementFilter(index, el, $)); 17 | } 18 | 19 | if (config?.ignoreIntersectingElements) { 20 | elems = ignoreIntersectingElements( 21 | $, 22 | elems, 23 | config.ignoreIntersectingElements 24 | ); 25 | } 26 | 27 | $(elems).each((index, el) => { 28 | const rest = omit(config, ['selector', 'type']); 29 | const value = getValue({ $, el: $(el) }, { selector: '', ...rest }); 30 | 31 | values.push(value); 32 | }); 33 | 34 | return values; 35 | } 36 | 37 | function ignoreIntersectingElements( 38 | $: CheerioAPI, 39 | elems: Cheerio, 40 | ignoreStyle: RawConfig['ignoreIntersectingElements'] 41 | ) { 42 | const reducer = makeUniqueElemsReducer($, ignoreStyle); 43 | const uniqElems = elems.toArray().reduce(reducer, []); 44 | 45 | return $(uniqElems); 46 | } 47 | 48 | function makeUniqueElemsReducer( 49 | $: CheerioAPI, 50 | ignoreStyle: RawConfig['ignoreIntersectingElements'] 51 | ) { 52 | return (acc: Element[], current: Element) => { 53 | const $current = $(current); 54 | let insertCurrIdx = acc.length; 55 | 56 | acc = acc.filter((elem, i) => { 57 | const currentWraps = elemWraps($current, $(elem)); 58 | const elemWrapsCurrent = elemWraps($(elem), $current); 59 | 60 | if (ignoreStyle === 'ignore-children') { 61 | if (currentWraps) { 62 | insertCurrIdx = i; 63 | return false; 64 | } 65 | 66 | if (elemWrapsCurrent) { 67 | // do not insert current to the acc 68 | insertCurrIdx = -1; 69 | // keep elem 70 | return true; 71 | } 72 | } else if (ignoreStyle === 'ignore-parents') { 73 | if (currentWraps) { 74 | // do not insert current to the acc 75 | insertCurrIdx = -1; 76 | // keep elem 77 | return true; 78 | } 79 | 80 | if (elemWrapsCurrent) { 81 | insertCurrIdx = i; 82 | // replace this element with the $current 83 | return false; 84 | } 85 | } 86 | 87 | return true; 88 | }); 89 | 90 | if (insertCurrIdx !== -1) { 91 | const insertIdx = Math.min(insertCurrIdx, acc.length); 92 | acc.splice(insertIdx, 0, $current.get(0)); 93 | } 94 | 95 | return acc; 96 | }; 97 | } 98 | 99 | function elemWraps(first: Cheerio, second: Cheerio) { 100 | return first.has(second).length > 0; 101 | } 102 | 103 | export default getArrayValue; 104 | -------------------------------------------------------------------------------- /src/parser/getElement.ts: -------------------------------------------------------------------------------- 1 | import { type Cheerio } from 'cheerio'; 2 | import { type Element } from 'domhandler'; 3 | import { type ElementPassArg } from './types'; 4 | import { type RawConfig } from '../config/types'; 5 | 6 | function getElement( 7 | { $, el }: ElementPassArg, 8 | config: RawConfig 9 | ): Cheerio { 10 | if (!config) return $(el); 11 | 12 | const { selector, rootScope, type } = config; 13 | let element; 14 | 15 | if (!selector) { 16 | element = $(el || 'html'); 17 | } else if (rootScope) { 18 | element = $(selector); 19 | } else if (el) { 20 | element = $(el).find(selector); 21 | } else { 22 | element = $(selector); 23 | } 24 | 25 | return type !== 'array' ? element.first() : element; 26 | } 27 | 28 | export default getElement; 29 | -------------------------------------------------------------------------------- /src/parser/getRawConfig.ts: -------------------------------------------------------------------------------- 1 | import parseSelector from '../config/parseSelector'; 2 | import { type Config, type RawConfig } from '../config/types'; 3 | 4 | export function getRawConfig( 5 | config: Config 6 | ): RawConfig | RawConfig[] { 7 | if (typeof config === 'string') { 8 | return parseSelector(config); 9 | } 10 | 11 | if (typeof config === 'function') { 12 | return { 13 | selector: '', 14 | schema: config 15 | }; 16 | } 17 | 18 | if (Array.isArray(config)) { 19 | return config.map(getRawConfig) as RawConfig[]; 20 | } 21 | 22 | if (config.selector !== '') { 23 | return { 24 | ...config, 25 | ...parseSelector(config.selector) 26 | }; 27 | } 28 | 29 | return config; 30 | } 31 | -------------------------------------------------------------------------------- /src/parser/getSchemaValue.ts: -------------------------------------------------------------------------------- 1 | import getConfig from '../config/getConfig'; 2 | import { Schema, SchemaGenerator } from '../config/types'; 3 | import { getRawConfig } from './getRawConfig'; 4 | import getValue from './getValue'; 5 | import { ElementPassArg } from './types'; 6 | 7 | function getSchemaValue( 8 | { $, el }: ElementPassArg, 9 | config: Schema 10 | ): Record['schema'], unknown> { 11 | return Object.keys(config).reduce((values, key) => { 12 | const conf = config[key]; 13 | const rawConfig = getRawConfig(conf); 14 | 15 | if (Array.isArray(rawConfig)) { 16 | for (const rconf of rawConfig) { 17 | const currentRawConfig = getConfig({ $, el }, rconf); 18 | 19 | const value = getValue({ $, el }, currentRawConfig); 20 | 21 | if (value !== null && value !== undefined) { 22 | values[key] = value; 23 | break; 24 | } 25 | } 26 | 27 | if (!Object.prototype.hasOwnProperty.call(values, key)) { 28 | values[key] = null; 29 | } 30 | 31 | return values; 32 | } 33 | 34 | const currentRawConfig = getConfig({ $, el }, rawConfig); 35 | 36 | values[key] = getValue({ $, el }, currentRawConfig); 37 | 38 | return values; 39 | }, {}); 40 | } 41 | 42 | export default getSchemaValue; 43 | -------------------------------------------------------------------------------- /src/parser/getSimpleValue.ts: -------------------------------------------------------------------------------- 1 | import { type RawConfig } from '../config/types'; 2 | import { type ElementPassArg } from './types'; 3 | import { type Value } from './value'; 4 | import parseSelector from '../config/parseSelector'; 5 | import transformValue from './transformValue'; 6 | import extractValue from './extractValue'; 7 | 8 | function getSimpleValue( 9 | { $, el }: ElementPassArg, 10 | config: RawConfig 11 | ): Value { 12 | if (typeof config === 'string') { 13 | config = parseSelector(config); 14 | } 15 | 16 | const { initial } = config; 17 | const element = $(el); 18 | 19 | let value: string | Record | Initial = extractValue( 20 | { $, el }, 21 | config 22 | ); 23 | 24 | if (initial && !value) { 25 | value = initial; 26 | } 27 | 28 | const isEmptyStringInitial = typeof initial === 'string' && initial === ''; 29 | 30 | if ( 31 | value === null || 32 | value === undefined || 33 | (value === '' && !isEmptyStringInitial) 34 | ) { 35 | return null; 36 | } 37 | 38 | return transformValue(value, config, element); 39 | } 40 | 41 | export default getSimpleValue; 42 | -------------------------------------------------------------------------------- /src/parser/getValue.ts: -------------------------------------------------------------------------------- 1 | import { type ElementPassArg } from './types'; 2 | import { type RawConfig } from '../config/types'; 3 | 4 | import getElement from './getElement'; 5 | import getSimpleValue from './getSimpleValue'; 6 | import getSchemaValue from './getSchemaValue'; 7 | import getArrayValue from './getArrayValue'; 8 | 9 | function getValue( 10 | { $, el }: ElementPassArg, 11 | config: RawConfig | RawConfig[] 12 | ) { 13 | if (!config) return null; 14 | 15 | if (Array.isArray(config)) { 16 | for (const conf of config) { 17 | const value = getValue({ $, el }, conf); 18 | 19 | if (value !== null) { 20 | return value; 21 | } 22 | } 23 | 24 | return null; 25 | } 26 | 27 | const element = getElement({ $, el }, config); 28 | const { type, condition, exist, fill, ...rest } = config; 29 | const { schema } = rest; 30 | const elemExists = element.length > 0; 31 | 32 | if (exist) return elemExists; 33 | 34 | if (condition && !condition($(el))) { 35 | return rest.initial ?? null; 36 | } 37 | 38 | if (typeof fill !== 'undefined') { 39 | if (typeof fill === 'function') { 40 | return fill(); 41 | } 42 | 43 | return fill; 44 | } 45 | 46 | const isIgnoreExistenceChecks = config.ignoreExistenceChecks === true; 47 | 48 | if (!elemExists && !isIgnoreExistenceChecks) { 49 | return rest.initial ?? null; 50 | } 51 | 52 | if (type === 'array') { 53 | if (config.methods?.includes('length')) { 54 | return $(element).length; 55 | } 56 | 57 | const arrayValue = getArrayValue({ $, el: element }, rest); 58 | 59 | if (config.arrayTransform) { 60 | return config.arrayTransform(arrayValue, element); 61 | } 62 | 63 | return arrayValue; 64 | } else if (schema) { 65 | let currentSchema = schema; 66 | 67 | if (typeof currentSchema === 'function') { 68 | currentSchema = currentSchema($ && el ? $(el) : null, $); 69 | } 70 | 71 | return getSchemaValue({ $, el: element }, currentSchema); 72 | } else { 73 | return getSimpleValue({ $, el: element }, rest); 74 | } 75 | } 76 | 77 | export default getValue; 78 | -------------------------------------------------------------------------------- /src/parser/methods/boolean.ts: -------------------------------------------------------------------------------- 1 | const boolean = (val: any) => Boolean(val); 2 | 3 | export default boolean; 4 | -------------------------------------------------------------------------------- /src/parser/methods/email.ts: -------------------------------------------------------------------------------- 1 | import execRegex from '../regex/execRegex'; 2 | 3 | const email = (val: any) => execRegex(val, 'email'); 4 | 5 | export default email; 6 | -------------------------------------------------------------------------------- /src/parser/methods/float.ts: -------------------------------------------------------------------------------- 1 | const float = (val: string) => parseFloat(val); 2 | 3 | export default float; 4 | -------------------------------------------------------------------------------- /src/parser/methods/index.ts: -------------------------------------------------------------------------------- 1 | import float from './float'; 2 | import number from './number'; 3 | import boolean from './boolean'; 4 | import email from './email'; 5 | import url from './url'; 6 | import lowercase from './lowercase'; 7 | import uppercase from './uppercase'; 8 | import length from './length'; 9 | 10 | const methods = { 11 | float, 12 | number, 13 | boolean, 14 | email, 15 | url, 16 | lowercase, 17 | uppercase, 18 | length 19 | }; 20 | 21 | export default methods; 22 | -------------------------------------------------------------------------------- /src/parser/methods/length.ts: -------------------------------------------------------------------------------- 1 | const length = (val: any) => val?.length || 0; 2 | 3 | export default length; 4 | -------------------------------------------------------------------------------- /src/parser/methods/lowercase.ts: -------------------------------------------------------------------------------- 1 | const lowercase = (val: string) => val.toLowerCase(); 2 | 3 | export default lowercase; 4 | -------------------------------------------------------------------------------- /src/parser/methods/number.ts: -------------------------------------------------------------------------------- 1 | const number = (val: string) => parseInt(val); 2 | 3 | export default number; 4 | -------------------------------------------------------------------------------- /src/parser/methods/uppercase.ts: -------------------------------------------------------------------------------- 1 | const uppercase = (val: string) => val.toUpperCase(); 2 | 3 | export default uppercase; 4 | -------------------------------------------------------------------------------- /src/parser/methods/url.ts: -------------------------------------------------------------------------------- 1 | import execRegex from '../regex/execRegex'; 2 | 3 | const url = (val: any) => execRegex(val, 'url'); 4 | 5 | export default url; 6 | -------------------------------------------------------------------------------- /src/parser/parse.ts: -------------------------------------------------------------------------------- 1 | import { load, CheerioAPI, CheerioOptions } from 'cheerio'; 2 | import { Config } from '../config/types'; 3 | import { getRawConfig } from './getRawConfig'; 4 | import getValue from './getValue'; 5 | 6 | /** 7 | * Create a JSON output using the provided schema and markup. 8 | * 9 | * Note that similar to web browser contexts, this operation may introduce 10 | * ``, ``, and `` elements; set `isDocument` to `false` to 11 | * switch to fragment mode and disable this. 12 | * 13 | * @param content - Markup to be loaded or a cheerio instance. 14 | * @param config - Your parse config including your schema 15 | * @param options - Cheerio options for the created instance. 16 | * @param isDocument - Allows cheerio parser to be switched to fragment mode. 17 | * @returns Your JSON output parsed according to your schema. 18 | * @see {@link https://wopehq.gitbook.io/muninn} for additional usage information. 19 | */ 20 | function parse( 21 | data: string | CheerioAPI, 22 | config: Config, 23 | options?: CheerioOptions, 24 | isDocument?: boolean 25 | ): Record { 26 | let $; 27 | 28 | if (typeof data === 'string') { 29 | $ = load(data, options, isDocument); 30 | } else if (typeof data === 'function') { 31 | $ = data; 32 | } 33 | 34 | const rawConfig = getRawConfig(config); 35 | 36 | if (Array.isArray(rawConfig)) { 37 | for (const conf of rawConfig) { 38 | const value = getValue({ $, el: $ }, conf); 39 | 40 | if (value !== null) return value; 41 | } 42 | 43 | return null; 44 | } 45 | 46 | return getValue({ $ }, rawConfig); 47 | } 48 | 49 | export default parse; 50 | -------------------------------------------------------------------------------- /src/parser/regex/constant.ts: -------------------------------------------------------------------------------- 1 | const REGEXES = { 2 | url: /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w_]+@)?[A-Za-z0-9._-]+(?::[0-9]+)?|(?:www\.|[-;:&=+$,\w_]+@)[A-Za-z0-9._-]+)((?:\/[^"\s<>{}|\\^`]+)*\/?(?:\?[^"\s<>{}|\\^`]+)?(?:#[^"\s<>{}|\\^`]+)?))/, 3 | email: 4 | /(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})/i 5 | }; 6 | 7 | export default REGEXES; 8 | -------------------------------------------------------------------------------- /src/parser/regex/execRegex.ts: -------------------------------------------------------------------------------- 1 | import REGEXES from './constant'; 2 | 3 | type RegexObj = { 4 | pattern: string; 5 | flags?: string; 6 | }; 7 | 8 | type Regex = 'url' | 'email' | RegExp | RegexObj; 9 | 10 | function execRegex(value: string, regex: Regex): string { 11 | if (!value || typeof value !== 'string') return; 12 | 13 | const isPreDefinedRegex = typeof regex === 'string'; 14 | const isRegexObject = regex instanceof RegExp; 15 | 16 | let _regex: RegExp; 17 | 18 | if (isPreDefinedRegex) { 19 | if (REGEXES[regex]) { 20 | _regex = REGEXES[regex]; 21 | } 22 | } else if (!isRegexObject) { 23 | const { pattern, flags } = regex; 24 | _regex = new RegExp(pattern, flags); 25 | } else { 26 | _regex = regex; 27 | } 28 | 29 | return value.match(_regex)?.[0] || null; 30 | } 31 | 32 | export default execRegex; 33 | -------------------------------------------------------------------------------- /src/parser/transformValue.ts: -------------------------------------------------------------------------------- 1 | import { type Cheerio } from 'cheerio'; 2 | import { type Element } from 'domhandler'; 3 | import { type RawConfig } from '../config/types'; 4 | import Methods from './methods'; 5 | import execRegex from './regex/execRegex'; 6 | 7 | function transformValue( 8 | value: any, 9 | config: RawConfig, 10 | element: Cheerio 11 | ) { 12 | const { trim, regex, type, methods = [], transform } = config; 13 | 14 | if (typeof value === 'string' && trim !== false) { 15 | if (regex) { 16 | value = execRegex(value, regex); 17 | } 18 | 19 | if (value) value = value.trim(); 20 | } 21 | 22 | if (type && type !== 'array') { 23 | methods.push(type); 24 | } 25 | 26 | methods.forEach((name) => { 27 | if (Methods[name]) { 28 | value = Methods[name](value); 29 | } 30 | }); 31 | 32 | if (typeof transform === 'function') { 33 | value = transform(value, element); 34 | } 35 | 36 | return value; 37 | } 38 | 39 | export default transformValue; 40 | -------------------------------------------------------------------------------- /src/parser/types.ts: -------------------------------------------------------------------------------- 1 | import { Cheerio, CheerioAPI } from 'cheerio'; 2 | import { type Element } from 'domhandler'; 3 | 4 | export type ElementPassArg = { 5 | $?: CheerioAPI; 6 | el?: Cheerio | string | Element; 7 | }; 8 | -------------------------------------------------------------------------------- /src/parser/value.ts: -------------------------------------------------------------------------------- 1 | export type Value = 2 | | string 3 | | Record 4 | | Initial; 5 | -------------------------------------------------------------------------------- /src/utils/omit.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a new object by omitting specified keys from the input object. 3 | * 4 | * @template T - The type of the input object. 5 | * @template K - The type of the keys to be omitted. 6 | * @param {T} obj - The input object. 7 | * @param {K[]} keys - The keys to be omitted from the input object. 8 | * @returns {Omit} - A new object with the specified keys omitted. 9 | */ 10 | export function omit( 11 | obj: T, 12 | keys: K[] 13 | ): Omit { 14 | const result = { ...obj }; 15 | keys.forEach((key) => { 16 | delete result[key]; 17 | }); 18 | return result; 19 | } 20 | -------------------------------------------------------------------------------- /tests/execRegex.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import execRegex from '../src/parser/regex/execRegex'; 3 | 4 | describe('execRegex Tests', () => { 5 | it('Case 1: Pre-defined Regex - url', () => { 6 | const value = 'test https://google.com/ '; 7 | const result = execRegex(value, 'url'); 8 | expect('https://google.com/').toEqual(result); 9 | }); 10 | 11 | it('Case 1.1: Pre-defined Regex - url', () => { 12 | const value = 'test https://google.com/images test '; 13 | const result = execRegex(value, 'url'); 14 | expect('https://google.com/images').toEqual(result); 15 | }); 16 | 17 | it('Case 1.2: Pre-defined Regex - url', () => { 18 | const value = 'test https://google.com/images?q=sunset test '; 19 | const result = execRegex(value, 'url'); 20 | expect('https://google.com/images?q=sunset').toEqual(result); 21 | }); 22 | 23 | it('Case 2: Pre-defined Regex - email', () => { 24 | const value = 'test test@email.com '; 25 | const result = execRegex(value, 'email'); 26 | expect('test@email.com').toEqual(result); 27 | }); 28 | 29 | it('Case 3: As Object', () => { 30 | const value = 'test 26'; 31 | const result = execRegex(value, { pattern: '\\d+' }); 32 | expect('26').toEqual(result); 33 | }); 34 | 35 | it('Case 4: As Regex Object ', () => { 36 | const value = 'test 26'; 37 | const result = execRegex(value, /\d+/); 38 | expect('26').toEqual(result); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /tests/getArrayValue.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import { load } from 'cheerio'; 3 | import getArrayValue from '../src/parser/getArrayValue'; 4 | 5 | const SAMPLE_HTML = ` 6 |
7 |
First Child
Second Child
8 | 9 |
10 | Third Child 11 |
12 |
13 | `; 14 | 15 | const $ = load(SAMPLE_HTML); 16 | 17 | describe('getArrayValue', () => { 18 | it('withoutIgnore', () => { 19 | const result = getArrayValue({ $, el: '#root div' }, { selector: '' }); 20 | const expected = [ 21 | 'First Child Second Child', 22 | 'Second Child', 23 | 'Third Child' 24 | ]; 25 | 26 | expect(result).toEqual(expected); 27 | }); 28 | 29 | it('withIgnoreChildren', () => { 30 | const result = getArrayValue( 31 | { $, el: '#root div' }, 32 | { selector: '', ignoreIntersectingElements: 'ignore-children' } 33 | ); 34 | const expected = ['First Child Second Child', 'Third Child']; 35 | 36 | expect(result).toEqual(expected); 37 | }); 38 | 39 | it('withIgnoreParents', () => { 40 | const result = getArrayValue( 41 | { $, el: '#root div' }, 42 | { selector: '', ignoreIntersectingElements: 'ignore-parents' } 43 | ); 44 | const expected = ['Second Child', 'Third Child']; 45 | 46 | expect(result).toEqual(expected); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /tests/getConfig.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | 3 | import getConfig from '../src/config/getConfig'; 4 | import { type RawConfig } from '../src/config/types'; 5 | 6 | describe('getConfig Tests', () => { 7 | it('should return empty selector and "href" attribute when given a string config with "@ attr"', () => { 8 | const config: RawConfig = { selector: '@ href' }; 9 | const value = getConfig({}, config); 10 | const expected = { selector: '', attr: 'href' }; 11 | 12 | expect(value).toEqual(expected); 13 | }); 14 | 15 | it('should return the same selector when given a string config without "@ attr"', () => { 16 | const config: RawConfig = { selector: 'a.link' }; 17 | const value = getConfig({}, config); 18 | expect({ selector: 'a.link' }).toEqual(value); 19 | }); 20 | 21 | it('should return the selector and "href" attribute when given a string config with "selector @ attr"', () => { 22 | const config: RawConfig = { selector: 'a.link @ href' }; 23 | const value = getConfig({}, config); 24 | expect({ selector: 'a.link', attr: 'href' }).toEqual(value); 25 | }); 26 | 27 | it('should return the same selector when given an array config with multiple selectors', () => { 28 | const config: RawConfig = { selector: 'a.link, b.link' }; 29 | const value = getConfig({}, config); 30 | expect({ selector: 'a.link, b.link' }).toEqual(value); 31 | }); 32 | 33 | it('should return the selector and attribute when given an object config with "selector" and "attr"', () => { 34 | const config: RawConfig = { selector: 'a.link', attr: 'href' }; 35 | const value = getConfig({}, config); 36 | expect({ selector: 'a.link', attr: 'href' }).toEqual(value); 37 | }); 38 | 39 | it('should return the selector and attribute when given an object config with "selector @ attr"', () => { 40 | const config: RawConfig = { selector: 'a.link @ href' }; 41 | const value = getConfig({}, config); 42 | expect({ selector: 'a.link', attr: 'href' }).toEqual(value); 43 | }); 44 | 45 | it('should return the selector, attribute, and methods when given an object config with "selector @ attr | method"', () => { 46 | const config: RawConfig = { selector: 'a.link @ href | url' }; 47 | const value = getConfig({}, config); 48 | expect({ 49 | selector: 'a.link', 50 | attr: 'href', 51 | methods: ['url'] 52 | }).toEqual(value); 53 | }); 54 | 55 | it('should return the selector, attribute, and type when given an object config with "selector @ attr | array"', () => { 56 | const config: RawConfig = { selector: 'a.link @ href | array' }; 57 | const value = getConfig({}, config); 58 | expect({ 59 | selector: 'a.link', 60 | attr: 'href', 61 | type: 'array' 62 | }).toEqual(value); 63 | }); 64 | 65 | it('should return the selector, attribute, and html flag when given an object config with "selector @ attr | html"', () => { 66 | const config: RawConfig = { selector: 'a.link @ href | html' }; 67 | const value = getConfig({}, config); 68 | expect({ 69 | selector: 'a.link', 70 | attr: 'href', 71 | html: true 72 | }).toEqual(value); 73 | }); 74 | 75 | it('should return the selector, attribute, and html flag when given an object config as a function', () => { 76 | const config: RawConfig = { 77 | selector: 'a.link @ href | html' 78 | }; 79 | const value = getConfig({}, config); 80 | const expected = { 81 | selector: 'a.link', 82 | attr: 'href', 83 | html: true 84 | }; 85 | 86 | expect(value).toEqual(expected); 87 | }); 88 | 89 | it('should return the selector and exist flag when given an object config as a function', () => { 90 | const config: RawConfig = { selector: 'a.link | exist' }; 91 | const value = getConfig({}, config); 92 | expect({ 93 | selector: 'a.link', 94 | exist: true 95 | }).toEqual(value); 96 | }); 97 | 98 | it('should return the parsed selectors when given an array of string selectors', () => { 99 | const selectors = ['a.link', 'b.link']; 100 | const result = getConfig({}, selectors); 101 | const expected = [{ selector: 'a.link' }, { selector: 'b.link' }]; 102 | expect(result).toEqual(expected); 103 | }); 104 | }); 105 | -------------------------------------------------------------------------------- /tests/getElement.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import { load } from 'cheerio'; 3 | import { Config } from '../src/config/types'; 4 | import getElement from '../src/parser/getElement'; 5 | 6 | const BLOCK_HTML = ` 7 |
8 |
First Child
9 |
Second Child
10 |
Third Child
11 |
Content
12 |
13 |
632
14 |
Year 2021
15 |
https://example.com/ > example > test
16 | Test Url 17 |
18 | `; 19 | 20 | const SAMPLE_HTML = ` 21 | 22 |
23 |
Unblock
24 | ${BLOCK_HTML.repeat(4)} 25 |
26 | 27 | `; 28 | 29 | const $ = load(SAMPLE_HTML); 30 | 31 | describe('getElement Tests', () => { 32 | it('Case 1: { selector } without `element`', () => { 33 | const config: Config = { selector: '.first-child' }; 34 | const element = getElement({ $ }, config); 35 | expect('first-child').toEqual(element.attr('class') as string); 36 | }); 37 | 38 | it('Case 2: { selector }', () => { 39 | const el = '.blocks'; 40 | const config: Config = { selector: '.first-child' }; 41 | const element = getElement({ $, el }, config); 42 | expect('first-child').toEqual(element.attr('class') as string); 43 | expect(1).toEqual(element.length); 44 | }); 45 | 46 | it('Case 3: { selector type: array }', () => { 47 | const el = $('.parent').first(); 48 | const config: Config = { selector: 'div', type: 'array' }; 49 | const element = getElement({ $, el }, config); 50 | expect(8).toEqual(element.length); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /tests/getSchemaValue.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import { Cheerio, Element, load } from 'cheerio'; 3 | import { Schema } from '../src/config/types'; 4 | import getSchemaValue from '../src/parser/getSchemaValue'; 5 | 6 | const sample = ` 7 |
8 |
sample
9 | example.com 10 |
11 | `; 12 | 13 | describe('getSchemaValue', () => { 14 | it('ExtractBasicSchema', () => { 15 | const schema: Schema = { 16 | link: { 17 | selector: 'a', 18 | schema: { title: '', url: '@ href' } 19 | } 20 | }; 21 | const $ = load(sample); 22 | const el = $('#root') as Cheerio; 23 | const result = getSchemaValue({ $, el }, schema); 24 | const expected = { 25 | link: { title: 'example.com', url: 'https://example.com' } 26 | }; 27 | 28 | expect(result).toStrictEqual(expected); 29 | }); 30 | 31 | it('SchemaValueConfigUnion', () => { 32 | const schema: Schema = { 33 | val: [ 34 | { 35 | selector: '#fake-selector' 36 | }, 37 | { 38 | selector: '.text' 39 | } 40 | ] 41 | }; 42 | const $ = load(sample); 43 | const el = $('#root') as Cheerio; 44 | const result = getSchemaValue({ $, el }, schema); 45 | const expected = { val: 'sample' }; 46 | 47 | expect(result).toStrictEqual(expected); 48 | }); 49 | 50 | it('SchemaValueNotFound', () => { 51 | const schema: Schema = { 52 | val: [ 53 | { 54 | selector: '#fake-selector' 55 | }, 56 | { 57 | selector: '#fake-selector-2' 58 | } 59 | ] 60 | }; 61 | const $ = load(sample); 62 | const el = $('#root') as Cheerio; 63 | const result = getSchemaValue({ $, el }, schema); 64 | const expected = { val: null }; 65 | 66 | expect(result).toStrictEqual(expected); 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /tests/getSimpleValue.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import { load } from 'cheerio'; 3 | import getSimpleValue from '../src/parser/getSimpleValue'; 4 | 5 | const SAMPLE_HTML = ` 6 |
7 | `; 8 | 9 | describe('getSimpleValue', () => { 10 | it('ignoreNull', () => { 11 | const $ = load(SAMPLE_HTML); 12 | const el = $('#root'); 13 | const config = { 14 | html: true, 15 | selector: '#non-existent' 16 | }; 17 | const value = getSimpleValue({ $, el }, config); 18 | 19 | expect(value).toEqual(null); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /tests/getValue.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import { load } from 'cheerio'; 3 | import { type Config, type RawConfig } from '../src/config/types'; 4 | import parseSelector from '../src/config/parseSelector'; 5 | import getValue from '../src/parser/getValue'; 6 | 7 | const BLOCK_HTML = ` 8 |
9 |
First Child
10 |
Second Child
11 |
Third Child
12 |
Content
13 |
14 |
632
15 |
Year 2021
16 |
Trim Content
17 |
Test
18 |
https://example.com/ > example > test
19 | Test Url 20 |
21 | `; 22 | 23 | const SAMPLE_HTML = ` 24 | 25 |
26 |
Unblock
27 | ${BLOCK_HTML.repeat(4)} 28 |
29 | 30 | `; 31 | 32 | const $ = load(SAMPLE_HTML); 33 | 34 | describe('getValue Tests', () => { 35 | it('Case 1: { selector }', () => { 36 | const config: RawConfig = { selector: '.first-child' }; 37 | const value = getValue({ $ }, config); 38 | expect('First Child').toEqual(value); 39 | }); 40 | 41 | it('Case 2: { [selector, selector] }', () => { 42 | const el = '.parent'; 43 | const config: RawConfig = { selector: '.first-child, .second-child' }; 44 | const value = getValue({ $, el }, config); 45 | expect('First Child').toEqual(value); 46 | }); 47 | 48 | it('Case 3: { [selector, selector], array }', () => { 49 | const el = $('.parent').first(); 50 | const config: RawConfig = { 51 | selector: '.first-child, .second-child', 52 | type: 'array' 53 | }; 54 | const value = getValue({ $, el }, config); 55 | expect(['First Child', 'Second Child']).toEqual(value); 56 | }); 57 | 58 | it('Case 4: { selector, schema }', () => { 59 | const el = $('.blocks').first(); 60 | const config: RawConfig = { 61 | selector: '.parent', 62 | schema: { 63 | firstChild: '.first-child', 64 | secondChild: '.second-child' 65 | } 66 | }; 67 | const value = getValue({ $, el }, config); 68 | 69 | expect({ 70 | firstChild: 'First Child', 71 | secondChild: 'Second Child' 72 | }).toEqual(value); 73 | }); 74 | 75 | it('Case 5: { selector, schema, array }', () => { 76 | const el = $('.blocks'); 77 | const config: RawConfig = { 78 | selector: '.parent', 79 | type: 'array', 80 | schema: { 81 | firstChild: '.first-child', 82 | secondChild: '.second-child' 83 | } 84 | }; 85 | const value = getValue({ $, el }, config); 86 | expect([ 87 | { 88 | firstChild: 'First Child', 89 | secondChild: 'Second Child' 90 | }, 91 | { 92 | firstChild: 'First Child', 93 | secondChild: 'Second Child' 94 | }, 95 | { 96 | firstChild: 'First Child', 97 | secondChild: 'Second Child' 98 | }, 99 | { 100 | firstChild: 'First Child', 101 | secondChild: 'Second Child' 102 | } 103 | ]).toEqual(value); 104 | }); 105 | 106 | it('Case 6: { selector, schema: { selector: schema } }', () => { 107 | const config: RawConfig = { 108 | selector: '.blocks', 109 | schema: { 110 | parent: { 111 | selector: '.parent', 112 | type: 'array', 113 | schema: { 114 | firstChild: '.first-child', 115 | secondChild: '.second-child' 116 | } 117 | } 118 | } 119 | }; 120 | const value = getValue({ $ }, config); 121 | expect({ 122 | parent: [ 123 | { 124 | firstChild: 'First Child', 125 | secondChild: 'Second Child' 126 | }, 127 | { 128 | firstChild: 'First Child', 129 | secondChild: 'Second Child' 130 | }, 131 | { 132 | firstChild: 'First Child', 133 | secondChild: 'Second Child' 134 | }, 135 | { 136 | firstChild: 'First Child', 137 | secondChild: 'Second Child' 138 | } 139 | ] 140 | }).toEqual(value); 141 | }); 142 | 143 | it('Case 7: { selector, trim }', () => { 144 | const config = { selector: '.trim-child' }; 145 | const value = getValue({ $ }, config); 146 | expect('Trim Content').toEqual(value); 147 | }); 148 | 149 | it('Case 8: { selector, trim: false }', () => { 150 | const config = { selector: '.trim-child', trim: false }; 151 | const value = getValue({ $ }, config); 152 | expect(' Trim Content ').toEqual(value); 153 | }); 154 | 155 | it('Case 9: { selector, attr }', () => { 156 | const config = { selector: '.link', attr: 'href' }; 157 | const value = getValue({ $ }, config); 158 | expect('https://example.com/').toEqual(value); 159 | }); 160 | 161 | it('Case 9.1: { selector, mulitple attrs }', () => { 162 | const config = { selector: '.link', attr: ['href', 'rel'] }; 163 | const value = getValue({ $ }, config); 164 | expect({ href: 'https://example.com/', rel: 'noreferrer' }).toEqual(value); 165 | }); 166 | 167 | it('Case 9.2: { selector, all attrs }', () => { 168 | const config = { selector: '.link', attr: '$all' }; 169 | const value = getValue({ $ }, config); 170 | expect({ 171 | href: 'https://example.com/', 172 | rel: 'noreferrer', 173 | class: 'link' 174 | }).toEqual(value); 175 | }); 176 | 177 | it('Case 10: { selector, html }', () => { 178 | const config = { selector: '.html-child', html: true }; 179 | const value = getValue({ $ }, config); 180 | expect('
Test
').toEqual(value); 181 | }); 182 | 183 | it('Case 11: { selector, transform }', () => { 184 | const config: RawConfig = { 185 | selector: '.parent', 186 | type: 'array', 187 | schema: { 188 | link: { 189 | selector: 'a.link', 190 | attr: 'href', 191 | transform: (val) => 'Link: ' + val 192 | } 193 | } 194 | }; 195 | const value = getValue({ $ }, config); 196 | expect([ 197 | { link: 'Link: https://example.com/' }, 198 | { link: 'Link: https://example.com/' }, 199 | { link: 'Link: https://example.com/' }, 200 | { link: 'Link: https://example.com/' } 201 | ]).toEqual(value); 202 | }); 203 | 204 | it('Case 12: { selector, initial }', () => { 205 | const config = { 206 | selector: 'b.href', 207 | initial: 'link not found' 208 | }; 209 | const value = getValue({ $ }, config); 210 | expect('link not found').toEqual(value); 211 | }); 212 | 213 | it('Case 13: { selector, fill }', () => { 214 | const config = { 215 | selector: 'a.href', 216 | fill: 'link censored' 217 | }; 218 | const value = getValue({ $ }, config); 219 | expect('link censored').toEqual(value); 220 | }); 221 | 222 | it('Case 13: { selector, fill }', () => { 223 | const config = { 224 | selector: 'a.href', 225 | fill: null 226 | }; 227 | const value = getValue({ $ }, config); 228 | expect(null).toEqual(value); 229 | }); 230 | 231 | it('Case 13: { selector, fill }', () => { 232 | const config = { 233 | selector: 'a.href', 234 | fill: undefined 235 | }; 236 | const value = getValue({ $ }, config); 237 | expect(null).toEqual(value); 238 | }); 239 | 240 | it('Case 13: { selector, fill }', () => { 241 | const config = { 242 | selector: 'a.href', 243 | fill: false 244 | }; 245 | const value = getValue({ $ }, config); 246 | expect(false).toEqual(value); 247 | }); 248 | 249 | it('Case 13: { selector, fill() }', () => { 250 | const config: RawConfig = { 251 | selector: 'a.href', 252 | fill: () => 'link censored' 253 | }; 254 | const value = getValue({ $ }, config); 255 | 256 | expect('link censored').toEqual(value); 257 | }); 258 | 259 | it('Case 13: { selector, fill }', () => { 260 | const config: RawConfig = { 261 | selector: '.parent', 262 | type: 'array', 263 | schema: { 264 | link: { 265 | selector: 'a.link', 266 | fill: 'link censored' 267 | } 268 | } 269 | }; 270 | const value = getValue({ $ }, config); 271 | expect([ 272 | { link: 'link censored' }, 273 | { link: 'link censored' }, 274 | { link: 'link censored' }, 275 | { link: 'link censored' } 276 | ]).toEqual(value); 277 | }); 278 | 279 | it('Case 14: { selector, regex }', () => { 280 | const el = $('.parent'); 281 | const selector = { 282 | selector: '.regex-test-child', 283 | regex: { pattern: '\\d+', flags: 'g' } 284 | }; 285 | const value = getValue({ $, el }, selector); 286 | expect('2021').toEqual(value); 287 | }); 288 | 289 | it('Case 15: { selector, regex/url }', () => { 290 | const el = $('.parent'); 291 | const selector: RawConfig = { 292 | selector: '.regex-template-test-child', 293 | regex: 'url' 294 | }; 295 | const value = getValue({ $, el }, selector); 296 | expect('https://example.com/').toEqual(value); 297 | }); 298 | 299 | it('Case 16: { selector, exist }', () => { 300 | const el = $('.parent'); 301 | const selector = '.empty-child | exist'; 302 | const value = getValue({ $, el }, parseSelector(selector)); 303 | 304 | expect(true).toEqual(value); 305 | }); 306 | 307 | it('Case 17: { selector, non-exist }', () => { 308 | const el = $('.parent'); 309 | const selector = '.non-exist-child'; 310 | const value = getValue({ $, el }, { selector, exist: true }); 311 | 312 | expect(value).toEqual(false); 313 | }); 314 | 315 | it('Case 18: { [selector, selector], array with elementFilter }', () => { 316 | const el = $('.parent').first(); 317 | const config: RawConfig = { 318 | selector: '.first-child, .second-child', 319 | type: 'array', 320 | elementFilter: (index, el, $) => { 321 | return $(el).hasClass('first-child'); 322 | } 323 | }; 324 | const value = getValue({ $, el }, config); 325 | 326 | expect(value).toEqual(['First Child']); 327 | }); 328 | }); 329 | 330 | describe('ignoreExistenceChecks', () => { 331 | const el = $('.parent'); 332 | 333 | it('ReturnNull', () => { 334 | const config: RawConfig = { 335 | selector: '.non-existent', 336 | ignoreExistenceChecks: false, 337 | schema: { 338 | selector: '.non-existent' 339 | } 340 | }; 341 | const value = getValue({ $, el }, config); 342 | 343 | expect(null).toEqual(value); 344 | }); 345 | 346 | it('ReturEmptyObject', () => { 347 | const config: RawConfig = { 348 | selector: '.non-existent', 349 | ignoreExistenceChecks: true, 350 | schema: {} 351 | }; 352 | const value = getValue({ $, el }, config); 353 | 354 | expect({}).toEqual(value); 355 | }); 356 | 357 | it('ReturObjectWithNullValues', () => { 358 | const config: RawConfig = { 359 | selector: '.non-existent', 360 | ignoreExistenceChecks: true, 361 | schema: { 362 | willBeNull: '#fake-selector' 363 | } 364 | }; 365 | const value = getValue({ $, el }, config); 366 | const expected = { 367 | willBeNull: null 368 | }; 369 | 370 | expect(value).toEqual(expected); 371 | }); 372 | }); 373 | 374 | describe('MultipleSchemas', () => { 375 | it('GetContentsOfTheFirstMatchingSelector', () => { 376 | const conf: Config = [ 377 | { selector: '#non-existent' }, 378 | { selector: '.first-child' } 379 | ]; 380 | const el = $('.parent:first'); 381 | const val = getValue({ $, el }, conf); 382 | const expected = $('.first-child:first').text(); 383 | 384 | expect(val).toEqual(expected); 385 | }); 386 | }); 387 | 388 | describe('LengthUtils', () => { 389 | it('OnStringValue', () => { 390 | const conf: Config = { 391 | selector: '.first-child:first', 392 | methods: ['length'] 393 | }; 394 | const el = $('.parent'); 395 | const val = getValue({ $, el }, conf); 396 | const expected = $('.first-child:first').text().length; 397 | 398 | expect(val).toEqual(expected); 399 | }); 400 | 401 | it('OnArrayValue', () => { 402 | const conf: Config = { 403 | selector: '.first-child', 404 | type: 'array', 405 | methods: ['length'] 406 | }; 407 | const el = $('.parent'); 408 | const val = getValue({ $, el }, conf); 409 | const expected = $('.first-child').length; 410 | 411 | expect(val).toEqual(expected); 412 | }); 413 | 414 | it('ArrayTransform', () => { 415 | const config: RawConfig = { 416 | selector: 'a', 417 | attr: 'href', 418 | type: 'array', 419 | arrayTransform: (value) => (value as string[]).join('-') 420 | }; 421 | const value = getValue({ $ }, config); 422 | expect( 423 | 'https://example.com/-https://example.com/-https://example.com/-https://example.com/' 424 | ).toEqual(value); 425 | }); 426 | }); 427 | -------------------------------------------------------------------------------- /tests/parse.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import parse from '../src/parser/parse'; 3 | import { type RawConfig } from '../src/config/types'; 4 | 5 | const BLOCK_HTML = ` 6 |
7 |
First Child
8 |
Second Child
9 |
Third Child
10 |
Content
11 |
12 |
632
13 |
Year 2021
14 |
Trim Content
15 |
Test
16 |
https://example.com/ > example > test
17 | Test Url 18 |
19 | `; 20 | 21 | const SAMPLE_HTML = ` 22 | 23 |
24 |
25 | ${` 26 |
27 |

Unblock

28 |

Description

29 |
30 | `.repeat(2)} 31 |
32 | ${BLOCK_HTML.repeat(4)} 33 |
34 | 35 | `; 36 | 37 | describe('parse Tests', () => { 38 | it('Case 1: { selector }', () => { 39 | const data = SAMPLE_HTML; 40 | const config: RawConfig = { selector: '.first-child' }; 41 | const value = parse(data, config); 42 | expect('First Child').toEqual(value as any); 43 | }); 44 | 45 | it('Case 2: { selector, array* }', () => { 46 | const data = SAMPLE_HTML; 47 | const config: RawConfig = { selector: '.unblock div h4 | array' }; 48 | const value = parse(data, config); 49 | expect(['Unblock', 'Unblock']).toEqual(value as any); 50 | }); 51 | 52 | it('Case 3: { selector, array*, schema }', () => { 53 | const data = SAMPLE_HTML; 54 | const config: RawConfig = { 55 | selector: '.blocks @ href', 56 | schema: { 57 | unblock: { 58 | selector: '.unblock div', 59 | type: 'array', 60 | schema: { title: 'h4', description: 'p' } 61 | } 62 | } 63 | }; 64 | const value = parse(data, config); 65 | const expected = { 66 | unblock: [ 67 | { 68 | title: 'Unblock', 69 | description: 'Description' 70 | }, 71 | { 72 | title: 'Unblock', 73 | description: 'Description' 74 | } 75 | ] 76 | }; 77 | 78 | expect(value).toEqual(expected); 79 | }); 80 | }); 81 | -------------------------------------------------------------------------------- /tests/parseSelector.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | 3 | import parseSelector from '../src/config/parseSelector'; 4 | 5 | describe('parseSelector Tests', () => { 6 | it('Case 1: @ attr', () => { 7 | const selector = '@ href'; 8 | const value = parseSelector(selector); 9 | const expected = { selector: '', attr: 'href' }; 10 | 11 | expect(value).toEqual(expected); 12 | }); 13 | 14 | it('Case 1.1: | @ multiple attrs', () => { 15 | const selector = '@ href, rel'; 16 | const value = parseSelector(selector); 17 | const expected = { selector: '', attr: ['href', 'rel'] }; 18 | 19 | expect(value).toEqual(expected); 20 | }); 21 | 22 | it('Case 1.2: @ all attrs', () => { 23 | const selector = '@ $all'; 24 | const value = parseSelector(selector); 25 | const expected = { selector: '', attr: '$all' }; 26 | 27 | expect(value).toEqual(expected); 28 | }); 29 | 30 | it('Case 2: selector @ attr', () => { 31 | const selector = 'a.link @ href'; 32 | const value = parseSelector(selector); 33 | const expected = { selector: 'a.link', attr: 'href' }; 34 | 35 | expect(value).toEqual(expected); 36 | }); 37 | 38 | it('Case 3: selector @ attr | method', () => { 39 | const selector = 'a.link @ href | url'; 40 | const value = parseSelector(selector); 41 | expect(value).toEqual({ 42 | selector: 'a.link', 43 | attr: 'href', 44 | methods: ['url'] 45 | }); 46 | }); 47 | 48 | it('Case 4: selector @ attr | method | method', () => { 49 | const selector = 'a.link @ href | url | uppercase'; 50 | const value = parseSelector(selector); 51 | expect(value).toEqual({ 52 | selector: 'a.link', 53 | attr: 'href', 54 | methods: ['url', 'uppercase'] 55 | }); 56 | }); 57 | 58 | it('Case 5: [selector, selector]', () => { 59 | const selector = 'a.link, b.link'; 60 | const value = parseSelector(selector); 61 | expect(value).toEqual({ 62 | selector: 'a.link, b.link' 63 | }); 64 | }); 65 | 66 | it('Case 6: selector, array*', () => { 67 | const selector = '.parent div | array'; 68 | const value = parseSelector(selector); 69 | expect(value).toEqual({ 70 | selector: '.parent div', 71 | type: 'array' 72 | }); 73 | }); 74 | 75 | it('only a method provided', () => { 76 | const selector = '| uppercase'; 77 | const result = parseSelector(selector); 78 | const expected = { 79 | selector: '', 80 | methods: ['uppercase'] 81 | }; 82 | 83 | expect(result).toEqual(expected as any); 84 | }); 85 | 86 | it('only two methods provided', () => { 87 | const selector = '| uppercase | lowercase'; 88 | const result = parseSelector(selector); 89 | const expected = { 90 | selector: '', 91 | methods: ['uppercase', 'lowercase'] 92 | }; 93 | 94 | expect(result).toEqual(expected as any); 95 | }); 96 | 97 | it('only an attribute provided', () => { 98 | const selector = '@ href'; 99 | const result = parseSelector(selector); 100 | const expected = { 101 | selector: '', 102 | attr: 'href' 103 | }; 104 | 105 | expect(result).toEqual(expected as any); 106 | }); 107 | }); 108 | -------------------------------------------------------------------------------- /tests/transformValue.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import { load } from 'cheerio'; 3 | import transformValue from '../src/parser/transformValue'; 4 | import { type RawConfig } from '../src/config/types'; 5 | 6 | const SAMPLE_HTML = ` 7 |
8 |
sample
9 |
10 | `; 11 | 12 | const $ = load(SAMPLE_HTML); 13 | 14 | describe('transformValue Tests', () => { 15 | it('should transform empty string to boolean false', () => { 16 | const config: RawConfig = { selector: '', methods: ['boolean'] }; 17 | const value = ''; 18 | const result = transformValue(value, config, $('div')); 19 | expect(false).toEqual(result); 20 | }); 21 | 22 | it('should transform non-empty string to boolean true', () => { 23 | const config: RawConfig = { selector: '', methods: ['boolean'] }; 24 | const value = 'Test'; 25 | const result = transformValue(value, config, $('div')); 26 | expect(true).toEqual(result); 27 | }); 28 | 29 | it('should transform string to number', () => { 30 | const config: RawConfig = { selector: '', methods: ['number'] }; 31 | const value = '12'; 32 | const result = transformValue(value, config, $('div')); 33 | expect(12).toEqual(result); 34 | }); 35 | 36 | it('should transform string to float', () => { 37 | const config: RawConfig = { selector: '', methods: ['float'] }; 38 | const value = '3.5'; 39 | const result = transformValue(value, config, $('div')); 40 | expect(3.5).toEqual(result); 41 | }); 42 | 43 | it('should trim the string', () => { 44 | const config: RawConfig = { selector: '', trim: true }; 45 | const value = ' content '; 46 | const result = transformValue(value, config, $('div')); 47 | expect('content').toEqual(result); 48 | }); 49 | 50 | it('should not trim the string', () => { 51 | const config: RawConfig = { selector: '', trim: false }; 52 | const value = ' content '; 53 | const result = transformValue(value, config, $('div')); 54 | 55 | expect(result).toEqual(value); 56 | }); 57 | 58 | it('should convert string to lowercase', () => { 59 | const config: RawConfig = { selector: '', methods: ['lowercase'] }; 60 | const value = 'CONTENT'; 61 | const result = transformValue(value, config, $('div')); 62 | expect('content').toEqual(result); 63 | }); 64 | 65 | it('should convert string to uppercase', () => { 66 | const config: RawConfig = { selector: '', methods: ['uppercase'] }; 67 | const value = 'content'; 68 | const result = transformValue(value, config, $('div')); 69 | expect('CONTENT').toEqual(result); 70 | }); 71 | 72 | it('should return the length of the string', () => { 73 | const config: RawConfig = { selector: '', methods: ['length'] }; 74 | const value = 'content'; 75 | const result = transformValue(value, config, $('div')); 76 | expect(7).toEqual(result); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /tests/utils.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'bun:test'; 2 | import { omit } from '../src/utils/omit'; 3 | import { type RawConfig } from '../src/config/types'; 4 | 5 | describe('Utils Tests', () => { 6 | it('should omit properties from config object', () => { 7 | const config: RawConfig = { 8 | selector: '.first-child', 9 | exist: true, 10 | type: 'array' 11 | }; 12 | 13 | const omitted = omit(config, ['type', 'exist']); 14 | 15 | expect({ selector: '.first-child' }).toEqual(omitted); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build", 4 | "declaration": true, 5 | "declarationMap": true, 6 | "skipLibCheck": true 7 | }, 8 | "exclude": ["./tests/**/*"], 9 | "include": ["./src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@aashutoshrathi/word-wrap@^1.2.3": 6 | version "1.2.6" 7 | resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" 8 | integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== 9 | 10 | "@cspotcode/source-map-support@^0.8.0": 11 | version "0.8.1" 12 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 13 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 14 | dependencies: 15 | "@jridgewell/trace-mapping" "0.3.9" 16 | 17 | "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": 18 | version "4.4.0" 19 | resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" 20 | integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== 21 | dependencies: 22 | eslint-visitor-keys "^3.3.0" 23 | 24 | "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": 25 | version "4.10.0" 26 | resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" 27 | integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== 28 | 29 | "@eslint/eslintrc@^2.1.4": 30 | version "2.1.4" 31 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" 32 | integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== 33 | dependencies: 34 | ajv "^6.12.4" 35 | debug "^4.3.2" 36 | espree "^9.6.0" 37 | globals "^13.19.0" 38 | ignore "^5.2.0" 39 | import-fresh "^3.2.1" 40 | js-yaml "^4.1.0" 41 | minimatch "^3.1.2" 42 | strip-json-comments "^3.1.1" 43 | 44 | "@eslint/js@8.56.0": 45 | version "8.56.0" 46 | resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" 47 | integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== 48 | 49 | "@humanwhocodes/config-array@^0.11.13": 50 | version "0.11.13" 51 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" 52 | integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== 53 | dependencies: 54 | "@humanwhocodes/object-schema" "^2.0.1" 55 | debug "^4.1.1" 56 | minimatch "^3.0.5" 57 | 58 | "@humanwhocodes/module-importer@^1.0.1": 59 | version "1.0.1" 60 | resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" 61 | integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== 62 | 63 | "@humanwhocodes/object-schema@^2.0.1": 64 | version "2.0.1" 65 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" 66 | integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== 67 | 68 | "@jridgewell/resolve-uri@^3.0.3": 69 | version "3.0.7" 70 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe" 71 | integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== 72 | 73 | "@jridgewell/sourcemap-codec@^1.4.10": 74 | version "1.4.13" 75 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c" 76 | integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== 77 | 78 | "@jridgewell/trace-mapping@0.3.9": 79 | version "0.3.9" 80 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 81 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 82 | dependencies: 83 | "@jridgewell/resolve-uri" "^3.0.3" 84 | "@jridgewell/sourcemap-codec" "^1.4.10" 85 | 86 | "@nodelib/fs.scandir@2.1.5": 87 | version "2.1.5" 88 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 89 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 90 | dependencies: 91 | "@nodelib/fs.stat" "2.0.5" 92 | run-parallel "^1.1.9" 93 | 94 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 95 | version "2.0.5" 96 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 97 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 98 | 99 | "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": 100 | version "1.2.8" 101 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 102 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 103 | dependencies: 104 | "@nodelib/fs.scandir" "2.1.5" 105 | fastq "^1.6.0" 106 | 107 | "@pkgr/core@^0.1.0": 108 | version "0.1.1" 109 | resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" 110 | integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== 111 | 112 | "@tsconfig/node10@^1.0.7": 113 | version "1.0.9" 114 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" 115 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== 116 | 117 | "@tsconfig/node12@^1.0.7": 118 | version "1.0.11" 119 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 120 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 121 | 122 | "@tsconfig/node14@^1.0.0": 123 | version "1.0.3" 124 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 125 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 126 | 127 | "@tsconfig/node16@^1.0.2": 128 | version "1.0.4" 129 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" 130 | integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== 131 | 132 | "@types/bun@^1.0.8": 133 | version "1.0.8" 134 | resolved "https://registry.yarnpkg.com/@types/bun/-/bun-1.0.8.tgz#5228b0c5c84150f8fe85d4eac851bca2d6250526" 135 | integrity sha512-E6UWZuN4ymAxzUBWVIGDHJ3Zey7I8cMzDZ+cB1BqhZsmd1uPb9iAQzpWMruY1mKzsuD3R+dZPoBkZz8QL1KhSA== 136 | dependencies: 137 | bun-types "1.0.29" 138 | 139 | "@types/json-schema@^7.0.12": 140 | version "7.0.15" 141 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" 142 | integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== 143 | 144 | "@types/node@*", "@types/node@~20.11.3": 145 | version "20.11.28" 146 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.28.tgz#4fd5b2daff2e580c12316e457473d68f15ee6f66" 147 | integrity sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA== 148 | dependencies: 149 | undici-types "~5.26.4" 150 | 151 | "@types/node@^20.10.5": 152 | version "20.11.20" 153 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.20.tgz#f0a2aee575215149a62784210ad88b3a34843659" 154 | integrity sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg== 155 | dependencies: 156 | undici-types "~5.26.4" 157 | 158 | "@types/semver@^7.5.0": 159 | version "7.5.7" 160 | resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.7.tgz#326f5fdda70d13580777bcaa1bc6fa772a5aef0e" 161 | integrity sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg== 162 | 163 | "@types/ws@~8.5.10": 164 | version "8.5.10" 165 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" 166 | integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== 167 | dependencies: 168 | "@types/node" "*" 169 | 170 | "@typescript-eslint/eslint-plugin@^7.0.2": 171 | version "7.0.2" 172 | resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz#c13a34057be425167cc4a765158c46fdf2fd981d" 173 | integrity sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg== 174 | dependencies: 175 | "@eslint-community/regexpp" "^4.5.1" 176 | "@typescript-eslint/scope-manager" "7.0.2" 177 | "@typescript-eslint/type-utils" "7.0.2" 178 | "@typescript-eslint/utils" "7.0.2" 179 | "@typescript-eslint/visitor-keys" "7.0.2" 180 | debug "^4.3.4" 181 | graphemer "^1.4.0" 182 | ignore "^5.2.4" 183 | natural-compare "^1.4.0" 184 | semver "^7.5.4" 185 | ts-api-utils "^1.0.1" 186 | 187 | "@typescript-eslint/parser@^7.0.2": 188 | version "7.0.2" 189 | resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.0.2.tgz#95c31233d343db1ca1df8df7811b5b87ca7b1a68" 190 | integrity sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q== 191 | dependencies: 192 | "@typescript-eslint/scope-manager" "7.0.2" 193 | "@typescript-eslint/types" "7.0.2" 194 | "@typescript-eslint/typescript-estree" "7.0.2" 195 | "@typescript-eslint/visitor-keys" "7.0.2" 196 | debug "^4.3.4" 197 | 198 | "@typescript-eslint/scope-manager@7.0.2": 199 | version "7.0.2" 200 | resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz#6ec4cc03752758ddd1fdaae6fbd0ed9a2ca4fe63" 201 | integrity sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g== 202 | dependencies: 203 | "@typescript-eslint/types" "7.0.2" 204 | "@typescript-eslint/visitor-keys" "7.0.2" 205 | 206 | "@typescript-eslint/type-utils@7.0.2": 207 | version "7.0.2" 208 | resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz#a7fc0adff0c202562721357e7478207d380a757b" 209 | integrity sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ== 210 | dependencies: 211 | "@typescript-eslint/typescript-estree" "7.0.2" 212 | "@typescript-eslint/utils" "7.0.2" 213 | debug "^4.3.4" 214 | ts-api-utils "^1.0.1" 215 | 216 | "@typescript-eslint/types@7.0.2": 217 | version "7.0.2" 218 | resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.0.2.tgz#b6edd108648028194eb213887d8d43ab5750351c" 219 | integrity sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA== 220 | 221 | "@typescript-eslint/typescript-estree@7.0.2": 222 | version "7.0.2" 223 | resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz#3c6dc8a3b9799f4ef7eca0d224ded01974e4cb39" 224 | integrity sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw== 225 | dependencies: 226 | "@typescript-eslint/types" "7.0.2" 227 | "@typescript-eslint/visitor-keys" "7.0.2" 228 | debug "^4.3.4" 229 | globby "^11.1.0" 230 | is-glob "^4.0.3" 231 | minimatch "9.0.3" 232 | semver "^7.5.4" 233 | ts-api-utils "^1.0.1" 234 | 235 | "@typescript-eslint/utils@7.0.2": 236 | version "7.0.2" 237 | resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.0.2.tgz#8756123054cd934c8ba7db6a6cffbc654b10b5c4" 238 | integrity sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw== 239 | dependencies: 240 | "@eslint-community/eslint-utils" "^4.4.0" 241 | "@types/json-schema" "^7.0.12" 242 | "@types/semver" "^7.5.0" 243 | "@typescript-eslint/scope-manager" "7.0.2" 244 | "@typescript-eslint/types" "7.0.2" 245 | "@typescript-eslint/typescript-estree" "7.0.2" 246 | semver "^7.5.4" 247 | 248 | "@typescript-eslint/visitor-keys@7.0.2": 249 | version "7.0.2" 250 | resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz#2899b716053ad7094962beb895d11396fc12afc7" 251 | integrity sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ== 252 | dependencies: 253 | "@typescript-eslint/types" "7.0.2" 254 | eslint-visitor-keys "^3.4.1" 255 | 256 | "@ungap/structured-clone@^1.2.0": 257 | version "1.2.0" 258 | resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" 259 | integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== 260 | 261 | acorn-jsx@^5.3.2: 262 | version "5.3.2" 263 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 264 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 265 | 266 | acorn-walk@^8.1.1: 267 | version "8.3.1" 268 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.1.tgz#2f10f5b69329d90ae18c58bf1fa8fccd8b959a43" 269 | integrity sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw== 270 | 271 | acorn@^8.4.1, acorn@^8.9.0: 272 | version "8.11.2" 273 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" 274 | integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== 275 | 276 | ajv@^6.12.4: 277 | version "6.12.6" 278 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 279 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 280 | dependencies: 281 | fast-deep-equal "^3.1.1" 282 | fast-json-stable-stringify "^2.0.0" 283 | json-schema-traverse "^0.4.1" 284 | uri-js "^4.2.2" 285 | 286 | ansi-regex@^5.0.1: 287 | version "5.0.1" 288 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 289 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 290 | 291 | ansi-styles@^4.1.0: 292 | version "4.3.0" 293 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 294 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 295 | dependencies: 296 | color-convert "^2.0.1" 297 | 298 | arg@^4.1.0: 299 | version "4.1.3" 300 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 301 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 302 | 303 | argparse@^2.0.1: 304 | version "2.0.1" 305 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 306 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 307 | 308 | array-union@^2.1.0: 309 | version "2.1.0" 310 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" 311 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 312 | 313 | balanced-match@^1.0.0: 314 | version "1.0.2" 315 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 316 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 317 | 318 | boolbase@^1.0.0: 319 | version "1.0.0" 320 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" 321 | integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= 322 | 323 | brace-expansion@^1.1.7: 324 | version "1.1.11" 325 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 326 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 327 | dependencies: 328 | balanced-match "^1.0.0" 329 | concat-map "0.0.1" 330 | 331 | brace-expansion@^2.0.1: 332 | version "2.0.1" 333 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 334 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 335 | dependencies: 336 | balanced-match "^1.0.0" 337 | 338 | braces@^3.0.2: 339 | version "3.0.2" 340 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 341 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 342 | dependencies: 343 | fill-range "^7.0.1" 344 | 345 | bun-types@1.0.29: 346 | version "1.0.29" 347 | resolved "https://registry.yarnpkg.com/bun-types/-/bun-types-1.0.29.tgz#b761f9c181aa0efa1c749ddfba2a28e4778dfaf2" 348 | integrity sha512-Z+U1ORr/2UCwxelIZxE83pyPLclviYL9UewQCNEUmGeLObY8ao+3WF3D8N1+NMv2+S+hUWsdBJam+4GoPEz35g== 349 | dependencies: 350 | "@types/node" "~20.11.3" 351 | "@types/ws" "~8.5.10" 352 | 353 | callsites@^3.0.0: 354 | version "3.1.0" 355 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 356 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 357 | 358 | chalk@^4.0.0: 359 | version "4.1.1" 360 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" 361 | integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== 362 | dependencies: 363 | ansi-styles "^4.1.0" 364 | supports-color "^7.1.0" 365 | 366 | cheerio-select@^2.1.0: 367 | version "2.1.0" 368 | resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" 369 | integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== 370 | dependencies: 371 | boolbase "^1.0.0" 372 | css-select "^5.1.0" 373 | css-what "^6.1.0" 374 | domelementtype "^2.3.0" 375 | domhandler "^5.0.3" 376 | domutils "^3.0.1" 377 | 378 | cheerio@^1.0.0: 379 | version "1.0.0" 380 | resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0.tgz#1ede4895a82f26e8af71009f961a9b8cb60d6a81" 381 | integrity sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww== 382 | dependencies: 383 | cheerio-select "^2.1.0" 384 | dom-serializer "^2.0.0" 385 | domhandler "^5.0.3" 386 | domutils "^3.1.0" 387 | encoding-sniffer "^0.2.0" 388 | htmlparser2 "^9.1.0" 389 | parse5 "^7.1.2" 390 | parse5-htmlparser2-tree-adapter "^7.0.0" 391 | parse5-parser-stream "^7.1.2" 392 | undici "^6.19.5" 393 | whatwg-mimetype "^4.0.0" 394 | 395 | color-convert@^2.0.1: 396 | version "2.0.1" 397 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 398 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 399 | dependencies: 400 | color-name "~1.1.4" 401 | 402 | color-name@~1.1.4: 403 | version "1.1.4" 404 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 405 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 406 | 407 | concat-map@0.0.1: 408 | version "0.0.1" 409 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 410 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 411 | 412 | create-require@^1.1.0: 413 | version "1.1.1" 414 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 415 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 416 | 417 | cross-spawn@^7.0.2: 418 | version "7.0.3" 419 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 420 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 421 | dependencies: 422 | path-key "^3.1.0" 423 | shebang-command "^2.0.0" 424 | which "^2.0.1" 425 | 426 | css-select@^5.1.0: 427 | version "5.1.0" 428 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" 429 | integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== 430 | dependencies: 431 | boolbase "^1.0.0" 432 | css-what "^6.1.0" 433 | domhandler "^5.0.2" 434 | domutils "^3.0.1" 435 | nth-check "^2.0.1" 436 | 437 | css-what@^6.1.0: 438 | version "6.1.0" 439 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" 440 | integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== 441 | 442 | debug@^4.1.1: 443 | version "4.3.1" 444 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" 445 | integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== 446 | dependencies: 447 | ms "2.1.2" 448 | 449 | debug@^4.3.2, debug@^4.3.4: 450 | version "4.3.4" 451 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 452 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 453 | dependencies: 454 | ms "2.1.2" 455 | 456 | deep-is@^0.1.3: 457 | version "0.1.3" 458 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 459 | integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= 460 | 461 | diff@^4.0.1: 462 | version "4.0.2" 463 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 464 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 465 | 466 | dir-glob@^3.0.1: 467 | version "3.0.1" 468 | resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" 469 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 470 | dependencies: 471 | path-type "^4.0.0" 472 | 473 | doctrine@^3.0.0: 474 | version "3.0.0" 475 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 476 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 477 | dependencies: 478 | esutils "^2.0.2" 479 | 480 | dom-serializer@^2.0.0: 481 | version "2.0.0" 482 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" 483 | integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== 484 | dependencies: 485 | domelementtype "^2.3.0" 486 | domhandler "^5.0.2" 487 | entities "^4.2.0" 488 | 489 | domelementtype@^2.3.0: 490 | version "2.3.0" 491 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" 492 | integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== 493 | 494 | domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: 495 | version "5.0.3" 496 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" 497 | integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== 498 | dependencies: 499 | domelementtype "^2.3.0" 500 | 501 | domutils@^3.0.1: 502 | version "3.0.1" 503 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" 504 | integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== 505 | dependencies: 506 | dom-serializer "^2.0.0" 507 | domelementtype "^2.3.0" 508 | domhandler "^5.0.1" 509 | 510 | domutils@^3.1.0: 511 | version "3.2.2" 512 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78" 513 | integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw== 514 | dependencies: 515 | dom-serializer "^2.0.0" 516 | domelementtype "^2.3.0" 517 | domhandler "^5.0.3" 518 | 519 | encoding-sniffer@^0.2.0: 520 | version "0.2.0" 521 | resolved "https://registry.yarnpkg.com/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz#799569d66d443babe82af18c9f403498365ef1d5" 522 | integrity sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg== 523 | dependencies: 524 | iconv-lite "^0.6.3" 525 | whatwg-encoding "^3.1.1" 526 | 527 | entities@^4.2.0, entities@^4.4.0: 528 | version "4.4.0" 529 | resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" 530 | integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== 531 | 532 | entities@^4.5.0: 533 | version "4.5.0" 534 | resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" 535 | integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== 536 | 537 | escape-string-regexp@^4.0.0: 538 | version "4.0.0" 539 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 540 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 541 | 542 | eslint-config-prettier@^9.1.0: 543 | version "9.1.0" 544 | resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" 545 | integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== 546 | 547 | eslint-plugin-prettier@^5.1.2: 548 | version "5.1.3" 549 | resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz#17cfade9e732cef32b5f5be53bd4e07afd8e67e1" 550 | integrity sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw== 551 | dependencies: 552 | prettier-linter-helpers "^1.0.0" 553 | synckit "^0.8.6" 554 | 555 | eslint-scope@^7.2.2: 556 | version "7.2.2" 557 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" 558 | integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== 559 | dependencies: 560 | esrecurse "^4.3.0" 561 | estraverse "^5.2.0" 562 | 563 | eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: 564 | version "3.4.3" 565 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" 566 | integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== 567 | 568 | eslint@^8.56.0: 569 | version "8.56.0" 570 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" 571 | integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== 572 | dependencies: 573 | "@eslint-community/eslint-utils" "^4.2.0" 574 | "@eslint-community/regexpp" "^4.6.1" 575 | "@eslint/eslintrc" "^2.1.4" 576 | "@eslint/js" "8.56.0" 577 | "@humanwhocodes/config-array" "^0.11.13" 578 | "@humanwhocodes/module-importer" "^1.0.1" 579 | "@nodelib/fs.walk" "^1.2.8" 580 | "@ungap/structured-clone" "^1.2.0" 581 | ajv "^6.12.4" 582 | chalk "^4.0.0" 583 | cross-spawn "^7.0.2" 584 | debug "^4.3.2" 585 | doctrine "^3.0.0" 586 | escape-string-regexp "^4.0.0" 587 | eslint-scope "^7.2.2" 588 | eslint-visitor-keys "^3.4.3" 589 | espree "^9.6.1" 590 | esquery "^1.4.2" 591 | esutils "^2.0.2" 592 | fast-deep-equal "^3.1.3" 593 | file-entry-cache "^6.0.1" 594 | find-up "^5.0.0" 595 | glob-parent "^6.0.2" 596 | globals "^13.19.0" 597 | graphemer "^1.4.0" 598 | ignore "^5.2.0" 599 | imurmurhash "^0.1.4" 600 | is-glob "^4.0.0" 601 | is-path-inside "^3.0.3" 602 | js-yaml "^4.1.0" 603 | json-stable-stringify-without-jsonify "^1.0.1" 604 | levn "^0.4.1" 605 | lodash.merge "^4.6.2" 606 | minimatch "^3.1.2" 607 | natural-compare "^1.4.0" 608 | optionator "^0.9.3" 609 | strip-ansi "^6.0.1" 610 | text-table "^0.2.0" 611 | 612 | espree@^9.6.0, espree@^9.6.1: 613 | version "9.6.1" 614 | resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" 615 | integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== 616 | dependencies: 617 | acorn "^8.9.0" 618 | acorn-jsx "^5.3.2" 619 | eslint-visitor-keys "^3.4.1" 620 | 621 | esquery@^1.4.2: 622 | version "1.5.0" 623 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" 624 | integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== 625 | dependencies: 626 | estraverse "^5.1.0" 627 | 628 | esrecurse@^4.3.0: 629 | version "4.3.0" 630 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 631 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 632 | dependencies: 633 | estraverse "^5.2.0" 634 | 635 | estraverse@^5.1.0, estraverse@^5.2.0: 636 | version "5.2.0" 637 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" 638 | integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== 639 | 640 | esutils@^2.0.2: 641 | version "2.0.3" 642 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 643 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 644 | 645 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 646 | version "3.1.3" 647 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 648 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 649 | 650 | fast-diff@^1.1.2: 651 | version "1.3.0" 652 | resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" 653 | integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== 654 | 655 | fast-glob@^3.2.9: 656 | version "3.3.2" 657 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" 658 | integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== 659 | dependencies: 660 | "@nodelib/fs.stat" "^2.0.2" 661 | "@nodelib/fs.walk" "^1.2.3" 662 | glob-parent "^5.1.2" 663 | merge2 "^1.3.0" 664 | micromatch "^4.0.4" 665 | 666 | fast-json-stable-stringify@^2.0.0: 667 | version "2.1.0" 668 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 669 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 670 | 671 | fast-levenshtein@^2.0.6: 672 | version "2.0.6" 673 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 674 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 675 | 676 | fastq@^1.6.0: 677 | version "1.17.1" 678 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" 679 | integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== 680 | dependencies: 681 | reusify "^1.0.4" 682 | 683 | file-entry-cache@^6.0.1: 684 | version "6.0.1" 685 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" 686 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 687 | dependencies: 688 | flat-cache "^3.0.4" 689 | 690 | fill-range@^7.0.1: 691 | version "7.0.1" 692 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 693 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 694 | dependencies: 695 | to-regex-range "^5.0.1" 696 | 697 | find-up@^5.0.0: 698 | version "5.0.0" 699 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 700 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 701 | dependencies: 702 | locate-path "^6.0.0" 703 | path-exists "^4.0.0" 704 | 705 | flat-cache@^3.0.4: 706 | version "3.0.4" 707 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" 708 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 709 | dependencies: 710 | flatted "^3.1.0" 711 | rimraf "^3.0.2" 712 | 713 | flatted@^3.1.0: 714 | version "3.1.1" 715 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" 716 | integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== 717 | 718 | fs.realpath@^1.0.0: 719 | version "1.0.0" 720 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 721 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 722 | 723 | glob-parent@^5.1.2: 724 | version "5.1.2" 725 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 726 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 727 | dependencies: 728 | is-glob "^4.0.1" 729 | 730 | glob-parent@^6.0.2: 731 | version "6.0.2" 732 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" 733 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 734 | dependencies: 735 | is-glob "^4.0.3" 736 | 737 | glob@^7.1.3: 738 | version "7.1.7" 739 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" 740 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== 741 | dependencies: 742 | fs.realpath "^1.0.0" 743 | inflight "^1.0.4" 744 | inherits "2" 745 | minimatch "^3.0.4" 746 | once "^1.3.0" 747 | path-is-absolute "^1.0.0" 748 | 749 | globals@^13.19.0: 750 | version "13.24.0" 751 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" 752 | integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== 753 | dependencies: 754 | type-fest "^0.20.2" 755 | 756 | globby@^11.1.0: 757 | version "11.1.0" 758 | resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" 759 | integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== 760 | dependencies: 761 | array-union "^2.1.0" 762 | dir-glob "^3.0.1" 763 | fast-glob "^3.2.9" 764 | ignore "^5.2.0" 765 | merge2 "^1.4.1" 766 | slash "^3.0.0" 767 | 768 | graphemer@^1.4.0: 769 | version "1.4.0" 770 | resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" 771 | integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== 772 | 773 | has-flag@^4.0.0: 774 | version "4.0.0" 775 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 776 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 777 | 778 | htmlparser2@^9.1.0: 779 | version "9.1.0" 780 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23" 781 | integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ== 782 | dependencies: 783 | domelementtype "^2.3.0" 784 | domhandler "^5.0.3" 785 | domutils "^3.1.0" 786 | entities "^4.5.0" 787 | 788 | iconv-lite@0.6.3, iconv-lite@^0.6.3: 789 | version "0.6.3" 790 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" 791 | integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== 792 | dependencies: 793 | safer-buffer ">= 2.1.2 < 3.0.0" 794 | 795 | ignore@^5.2.0, ignore@^5.2.4: 796 | version "5.3.1" 797 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" 798 | integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== 799 | 800 | import-fresh@^3.2.1: 801 | version "3.3.0" 802 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 803 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 804 | dependencies: 805 | parent-module "^1.0.0" 806 | resolve-from "^4.0.0" 807 | 808 | imurmurhash@^0.1.4: 809 | version "0.1.4" 810 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 811 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 812 | 813 | inflight@^1.0.4: 814 | version "1.0.6" 815 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 816 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 817 | dependencies: 818 | once "^1.3.0" 819 | wrappy "1" 820 | 821 | inherits@2: 822 | version "2.0.4" 823 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 824 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 825 | 826 | is-extglob@^2.1.1: 827 | version "2.1.1" 828 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 829 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 830 | 831 | is-glob@^4.0.0: 832 | version "4.0.1" 833 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 834 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== 835 | dependencies: 836 | is-extglob "^2.1.1" 837 | 838 | is-glob@^4.0.1, is-glob@^4.0.3: 839 | version "4.0.3" 840 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 841 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 842 | dependencies: 843 | is-extglob "^2.1.1" 844 | 845 | is-number@^7.0.0: 846 | version "7.0.0" 847 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 848 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 849 | 850 | is-path-inside@^3.0.3: 851 | version "3.0.3" 852 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" 853 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== 854 | 855 | isexe@^2.0.0: 856 | version "2.0.0" 857 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 858 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 859 | 860 | js-yaml@^4.1.0: 861 | version "4.1.0" 862 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 863 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 864 | dependencies: 865 | argparse "^2.0.1" 866 | 867 | json-schema-traverse@^0.4.1: 868 | version "0.4.1" 869 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 870 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 871 | 872 | json-stable-stringify-without-jsonify@^1.0.1: 873 | version "1.0.1" 874 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 875 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 876 | 877 | levn@^0.4.1: 878 | version "0.4.1" 879 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 880 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 881 | dependencies: 882 | prelude-ls "^1.2.1" 883 | type-check "~0.4.0" 884 | 885 | locate-path@^6.0.0: 886 | version "6.0.0" 887 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 888 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 889 | dependencies: 890 | p-locate "^5.0.0" 891 | 892 | lodash.merge@^4.6.2: 893 | version "4.6.2" 894 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 895 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 896 | 897 | lru-cache@^6.0.0: 898 | version "6.0.0" 899 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 900 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 901 | dependencies: 902 | yallist "^4.0.0" 903 | 904 | make-error@^1.1.1: 905 | version "1.3.6" 906 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 907 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 908 | 909 | merge2@^1.3.0, merge2@^1.4.1: 910 | version "1.4.1" 911 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 912 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 913 | 914 | micromatch@^4.0.4: 915 | version "4.0.5" 916 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" 917 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 918 | dependencies: 919 | braces "^3.0.2" 920 | picomatch "^2.3.1" 921 | 922 | minimatch@9.0.3: 923 | version "9.0.3" 924 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" 925 | integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== 926 | dependencies: 927 | brace-expansion "^2.0.1" 928 | 929 | minimatch@^3.0.4: 930 | version "3.0.4" 931 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 932 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 933 | dependencies: 934 | brace-expansion "^1.1.7" 935 | 936 | minimatch@^3.0.5, minimatch@^3.1.2: 937 | version "3.1.2" 938 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 939 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 940 | dependencies: 941 | brace-expansion "^1.1.7" 942 | 943 | ms@2.1.2: 944 | version "2.1.2" 945 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 946 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 947 | 948 | natural-compare@^1.4.0: 949 | version "1.4.0" 950 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 951 | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== 952 | 953 | nth-check@^2.0.1: 954 | version "2.0.1" 955 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" 956 | integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== 957 | dependencies: 958 | boolbase "^1.0.0" 959 | 960 | once@^1.3.0: 961 | version "1.4.0" 962 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 963 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 964 | dependencies: 965 | wrappy "1" 966 | 967 | optionator@^0.9.3: 968 | version "0.9.3" 969 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" 970 | integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== 971 | dependencies: 972 | "@aashutoshrathi/word-wrap" "^1.2.3" 973 | deep-is "^0.1.3" 974 | fast-levenshtein "^2.0.6" 975 | levn "^0.4.1" 976 | prelude-ls "^1.2.1" 977 | type-check "^0.4.0" 978 | 979 | p-limit@^3.0.2: 980 | version "3.1.0" 981 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 982 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 983 | dependencies: 984 | yocto-queue "^0.1.0" 985 | 986 | p-locate@^5.0.0: 987 | version "5.0.0" 988 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 989 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 990 | dependencies: 991 | p-limit "^3.0.2" 992 | 993 | parent-module@^1.0.0: 994 | version "1.0.1" 995 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 996 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 997 | dependencies: 998 | callsites "^3.0.0" 999 | 1000 | parse5-htmlparser2-tree-adapter@^7.0.0: 1001 | version "7.0.0" 1002 | resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" 1003 | integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== 1004 | dependencies: 1005 | domhandler "^5.0.2" 1006 | parse5 "^7.0.0" 1007 | 1008 | parse5-parser-stream@^7.1.2: 1009 | version "7.1.2" 1010 | resolved "https://registry.yarnpkg.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz#d7c20eadc37968d272e2c02660fff92dd27e60e1" 1011 | integrity sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow== 1012 | dependencies: 1013 | parse5 "^7.0.0" 1014 | 1015 | parse5@^7.0.0: 1016 | version "7.1.2" 1017 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" 1018 | integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== 1019 | dependencies: 1020 | entities "^4.4.0" 1021 | 1022 | parse5@^7.1.2: 1023 | version "7.2.1" 1024 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.2.1.tgz#8928f55915e6125f430cc44309765bf17556a33a" 1025 | integrity sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ== 1026 | dependencies: 1027 | entities "^4.5.0" 1028 | 1029 | path-exists@^4.0.0: 1030 | version "4.0.0" 1031 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 1032 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1033 | 1034 | path-is-absolute@^1.0.0: 1035 | version "1.0.1" 1036 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1037 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1038 | 1039 | path-key@^3.1.0: 1040 | version "3.1.1" 1041 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1042 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1043 | 1044 | path-type@^4.0.0: 1045 | version "4.0.0" 1046 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 1047 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 1048 | 1049 | picomatch@^2.3.1: 1050 | version "2.3.1" 1051 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1052 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1053 | 1054 | prelude-ls@^1.2.1: 1055 | version "1.2.1" 1056 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 1057 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 1058 | 1059 | prettier-linter-helpers@^1.0.0: 1060 | version "1.0.0" 1061 | resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" 1062 | integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== 1063 | dependencies: 1064 | fast-diff "^1.1.2" 1065 | 1066 | prettier@^3.1.1: 1067 | version "3.2.5" 1068 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" 1069 | integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== 1070 | 1071 | punycode@^2.1.0: 1072 | version "2.1.1" 1073 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 1074 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1075 | 1076 | queue-microtask@^1.2.2: 1077 | version "1.2.3" 1078 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 1079 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 1080 | 1081 | resolve-from@^4.0.0: 1082 | version "4.0.0" 1083 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 1084 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1085 | 1086 | reusify@^1.0.4: 1087 | version "1.0.4" 1088 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 1089 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 1090 | 1091 | rimraf@^3.0.2: 1092 | version "3.0.2" 1093 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1094 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1095 | dependencies: 1096 | glob "^7.1.3" 1097 | 1098 | run-parallel@^1.1.9: 1099 | version "1.2.0" 1100 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 1101 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1102 | dependencies: 1103 | queue-microtask "^1.2.2" 1104 | 1105 | "safer-buffer@>= 2.1.2 < 3.0.0": 1106 | version "2.1.2" 1107 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1108 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 1109 | 1110 | semver@^7.5.4: 1111 | version "7.6.0" 1112 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" 1113 | integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== 1114 | dependencies: 1115 | lru-cache "^6.0.0" 1116 | 1117 | shebang-command@^2.0.0: 1118 | version "2.0.0" 1119 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1120 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1121 | dependencies: 1122 | shebang-regex "^3.0.0" 1123 | 1124 | shebang-regex@^3.0.0: 1125 | version "3.0.0" 1126 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1127 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1128 | 1129 | slash@^3.0.0: 1130 | version "3.0.0" 1131 | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" 1132 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 1133 | 1134 | strip-ansi@^6.0.1: 1135 | version "6.0.1" 1136 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1137 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1138 | dependencies: 1139 | ansi-regex "^5.0.1" 1140 | 1141 | strip-json-comments@^3.1.1: 1142 | version "3.1.1" 1143 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1144 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1145 | 1146 | supports-color@^7.1.0: 1147 | version "7.2.0" 1148 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1149 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1150 | dependencies: 1151 | has-flag "^4.0.0" 1152 | 1153 | synckit@^0.8.6: 1154 | version "0.8.8" 1155 | resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" 1156 | integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== 1157 | dependencies: 1158 | "@pkgr/core" "^0.1.0" 1159 | tslib "^2.6.2" 1160 | 1161 | text-table@^0.2.0: 1162 | version "0.2.0" 1163 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1164 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 1165 | 1166 | to-regex-range@^5.0.1: 1167 | version "5.0.1" 1168 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1169 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1170 | dependencies: 1171 | is-number "^7.0.0" 1172 | 1173 | ts-api-utils@^1.0.1: 1174 | version "1.2.1" 1175 | resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.2.1.tgz#f716c7e027494629485b21c0df6180f4d08f5e8b" 1176 | integrity sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA== 1177 | 1178 | ts-node@^10.9.2: 1179 | version "10.9.2" 1180 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" 1181 | integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== 1182 | dependencies: 1183 | "@cspotcode/source-map-support" "^0.8.0" 1184 | "@tsconfig/node10" "^1.0.7" 1185 | "@tsconfig/node12" "^1.0.7" 1186 | "@tsconfig/node14" "^1.0.0" 1187 | "@tsconfig/node16" "^1.0.2" 1188 | acorn "^8.4.1" 1189 | acorn-walk "^8.1.1" 1190 | arg "^4.1.0" 1191 | create-require "^1.1.0" 1192 | diff "^4.0.1" 1193 | make-error "^1.1.1" 1194 | v8-compile-cache-lib "^3.0.1" 1195 | yn "3.1.1" 1196 | 1197 | tslib@^2.6.2: 1198 | version "2.6.2" 1199 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" 1200 | integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== 1201 | 1202 | type-check@^0.4.0, type-check@~0.4.0: 1203 | version "0.4.0" 1204 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 1205 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1206 | dependencies: 1207 | prelude-ls "^1.2.1" 1208 | 1209 | type-fest@^0.20.2: 1210 | version "0.20.2" 1211 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 1212 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1213 | 1214 | typescript@^5.3.3: 1215 | version "5.3.3" 1216 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" 1217 | integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== 1218 | 1219 | undici-types@~5.26.4: 1220 | version "5.26.5" 1221 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" 1222 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== 1223 | 1224 | undici@^6.19.5: 1225 | version "6.21.1" 1226 | resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.1.tgz#336025a14162e6837e44ad7b819b35b6c6af0e05" 1227 | integrity sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ== 1228 | 1229 | uri-js@^4.2.2: 1230 | version "4.4.1" 1231 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1232 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1233 | dependencies: 1234 | punycode "^2.1.0" 1235 | 1236 | v8-compile-cache-lib@^3.0.1: 1237 | version "3.0.1" 1238 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 1239 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 1240 | 1241 | whatwg-encoding@^3.1.1: 1242 | version "3.1.1" 1243 | resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5" 1244 | integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== 1245 | dependencies: 1246 | iconv-lite "0.6.3" 1247 | 1248 | whatwg-mimetype@^4.0.0: 1249 | version "4.0.0" 1250 | resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a" 1251 | integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== 1252 | 1253 | which@^2.0.1: 1254 | version "2.0.2" 1255 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1256 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1257 | dependencies: 1258 | isexe "^2.0.0" 1259 | 1260 | wrappy@1: 1261 | version "1.0.2" 1262 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1263 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1264 | 1265 | yallist@^4.0.0: 1266 | version "4.0.0" 1267 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1268 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1269 | 1270 | yn@3.1.1: 1271 | version "3.1.1" 1272 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 1273 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 1274 | 1275 | yocto-queue@^0.1.0: 1276 | version "0.1.0" 1277 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1278 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1279 | --------------------------------------------------------------------------------