├── .eslintrc.json ├── .gitignore ├── .prettierrc.json ├── LICENSE.md ├── README.md ├── example ├── .env.example ├── basic.ts ├── beer.ts ├── countries.ts ├── index.ts └── order.ts ├── package.json ├── src ├── api.ts ├── client.ts ├── config.ts ├── index.ts ├── inputs │ ├── OrderInput.ts │ └── index.ts ├── models │ ├── Address.ts │ ├── Bank.ts │ ├── Category.ts │ ├── Choice.ts │ ├── Country.ts │ ├── HistoryOrder.ts │ ├── HistoryProduct.ts │ ├── Loyalty.ts │ ├── Model.ts │ ├── Option.ts │ ├── Order.ts │ ├── Product.ts │ ├── ProductSize.ts │ ├── Restaurant.ts │ ├── Review.ts │ ├── User.ts │ └── index.ts ├── parse.ts ├── requests │ ├── base.ts │ ├── getAddresses.ts │ ├── getBanks.ts │ ├── getCountries.ts │ ├── getDiscounts.ts │ ├── getGeoLocation.ts │ ├── getHistory.ts │ ├── getHistoryDetails.ts │ ├── getLoyaltyPoints.ts │ ├── getMenuCard.ts │ ├── getRestaurantData.ts │ ├── getRestaurants.ts │ ├── getReviews.ts │ ├── getServerTime.ts │ ├── getURLs.ts │ ├── index.ts │ ├── login.ts │ ├── order.ts │ ├── resetPassword.ts │ ├── restaurant.ts │ └── util.ts └── util.ts ├── tsconfig.json └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 4 | "parser": "@typescript-eslint/parser", 5 | "plugins": ["@typescript-eslint"], 6 | "rules": { 7 | "@typescript-eslint/consistent-type-imports": [ 8 | "warn", 9 | { 10 | "prefer": "type-imports", 11 | "fixStyle": "inline-type-imports" 12 | } 13 | ], 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/no-unused-vars": ["warn", {"argsIgnorePattern": "^_"}] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/node 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | .pnpm-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # Snowpack dependency directory (https://snowpack.dev/) 50 | web_modules/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Optional stylelint cache 62 | .stylelintcache 63 | 64 | # Microbundle cache 65 | .rpt2_cache/ 66 | .rts2_cache_cjs/ 67 | .rts2_cache_es/ 68 | .rts2_cache_umd/ 69 | 70 | # Optional REPL history 71 | .node_repl_history 72 | 73 | # Output of 'npm pack' 74 | *.tgz 75 | 76 | # Yarn Integrity file 77 | .yarn-integrity 78 | 79 | # dotenv environment variable files 80 | .env 81 | .env.development.local 82 | .env.test.local 83 | .env.production.local 84 | .env.local 85 | 86 | # parcel-bundler cache (https://parceljs.org/) 87 | .cache 88 | .parcel-cache 89 | 90 | # Next.js build output 91 | .next 92 | out 93 | 94 | # Nuxt.js build / generate output 95 | .nuxt 96 | dist 97 | 98 | # Gatsby files 99 | .cache/ 100 | # Comment in the public line in if your project uses Gatsby and not Next.js 101 | # https://nextjs.org/blog/next-9-1#public-directory-support 102 | # public 103 | 104 | # vuepress build output 105 | .vuepress/dist 106 | 107 | # vuepress v2.x temp and cache directory 108 | .temp 109 | 110 | # Docusaurus cache and generated files 111 | .docusaurus 112 | 113 | # Serverless directories 114 | .serverless/ 115 | 116 | # FuseBox cache 117 | .fusebox/ 118 | 119 | # DynamoDB Local files 120 | .dynamodb/ 121 | 122 | # TernJS port file 123 | .tern-port 124 | 125 | # Stores VSCode versions used for testing VSCode extensions 126 | .vscode-test 127 | 128 | # yarn v2 129 | .yarn/cache 130 | .yarn/unplugged 131 | .yarn/build-state.yml 132 | .yarn/install-state.gz 133 | .pnp.* 134 | 135 | ### Node Patch ### 136 | # Serverless Webpack directories 137 | .webpack/ 138 | 139 | # Optional stylelint cache 140 | 141 | # SvelteKit build / generate output 142 | .svelte-kit 143 | 144 | # End of https://www.toptal.com/developers/gitignore/api/node 145 | 146 | .idea/ 147 | 148 | lib/ 149 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@trivago/prettier-plugin-sort-imports"], 3 | "bracketSpacing": false, 4 | "importOrder": ["^~/", "^[.]{2}/", "^[.]/"], 5 | "importOrderParserPlugins": ["typescript", "decorators-legacy"], 6 | "importOrderSeparation": true, 7 | "importOrderSortSpecifiers": true, 8 | "printWidth": 120, 9 | "singleQuote": true, 10 | "tabWidth": 4, 11 | "trailingComma": "none" 12 | } 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Daniel Huisman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node.js Takeaway.com API 2 | 3 | Unofficial JavaScript implementation of the [Takeaway.com](https://www.takeaway.com) API. 4 | 5 | ## Installation 6 | 7 | ``` 8 | yarn add takeaway 9 | ``` 10 | 11 | ## Endpoints 12 | 13 | - [x] Banks 14 | - [ ] CheckVoucher 15 | - [x] Config 16 | - [ ] CreateAccount 17 | - [x] Discounts 18 | - [x] GeoLocation 19 | - [x] HistoryDetails 20 | - [x] LoyaltyPoints 21 | - [ ] ImportOrder 22 | - [x] Menucard 23 | - [ ] OnlinePaymentStatus 24 | - [ ] Order 25 | - [ ] OrderWithOnlinePayment 26 | - [ ] RecurringPayment 27 | - [x] ResetPassword 28 | - [x] RestaurantData 29 | - [x] RestaurantList 30 | - [x] Reviews 31 | - [x] ServerTime 32 | - [x] URLs 33 | - [x] UserAddressList 34 | - [x] UserLogin 35 | - [x] UserOrderHistory 36 | - [ ] VietnamDeliveryArea 37 | 38 | ## Example 39 | 40 | ```javascript 41 | import {Takeaway, TakeawayConfig} from 'takeaway'; 42 | import {inspect} from 'util'; 43 | 44 | (async () => { 45 | try { 46 | // Initialize configuration 47 | // See `src/config.js` for defaults 48 | const config = new TakeawayConfig({ 49 | language: 'nl', 50 | url: 'https://nl.citymeal.com/android/android.php' 51 | }); 52 | 53 | // Initialize Takeaway API 54 | const takeaway = new Takeaway(config); 55 | 56 | // Fetch country 57 | const country = await takeaway.getCountryById('NL'); 58 | 59 | // Login to the country specific site 60 | const user = await country.login('test@exampl.com', 'testpassword123'); 61 | console.log(inspect(user, false, null)); 62 | 63 | // Request restaurants list for area 64 | const restaurants = await country.getRestaurants('7500', '52.0000000', '6.0000000'); 65 | console.log(inspect(restaurants, false, null)); 66 | } catch (err) { 67 | console.error(err); 68 | } 69 | })(); 70 | ``` 71 | 72 | ## Development 73 | 74 | ### Setup 75 | 76 | ```bash 77 | # Clone Git repository 78 | git clone git@github.com:TakeawayAPI/node-takeaway.git 79 | cd node-takeaway 80 | 81 | # Install dependencies 82 | yarn 83 | ``` 84 | -------------------------------------------------------------------------------- /example/.env.example: -------------------------------------------------------------------------------- 1 | NAME = John Doe 2 | STREET = Somestreet 1 3 | CITY = Somecity 4 | POSTAL_CODE = 1111ZZ 5 | EMAIL = name@example.com 6 | PHONE = +31612345678 7 | -------------------------------------------------------------------------------- /example/basic.ts: -------------------------------------------------------------------------------- 1 | import {inspect} from 'util'; 2 | 3 | import {Takeaway} from '../src'; 4 | 5 | (async () => { 6 | try { 7 | const takeaway = new Takeaway(); 8 | 9 | const postalCode = '7523'; 10 | 11 | const country = await takeaway.getCountryById('NL'); 12 | const restaurants = await country.getRestaurants(postalCode, '', ''); 13 | 14 | const user = await country.login('', ''); 15 | const history = await user.getHistory(1); 16 | await history[0].getDetails(); 17 | 18 | console.log(inspect(history[0], false, null)); 19 | console.log(inspect(await user.getLoyalty(), false, null)); 20 | 21 | await restaurants[0].getMenu(postalCode); 22 | console.log(inspect(restaurants[0].categories[0].products, false, null)); 23 | } catch (err) { 24 | console.error(err); 25 | } 26 | })(); 27 | -------------------------------------------------------------------------------- /example/beer.ts: -------------------------------------------------------------------------------- 1 | import {Takeaway} from '../src'; 2 | 3 | (async () => { 4 | try { 5 | const takeaway = new Takeaway(); 6 | const postalCode = '7523'; 7 | 8 | const country = await takeaway.getCountryById('NL'); 9 | const restaurants = await country.getRestaurants(postalCode, '', ''); 10 | 11 | for (const restaurant of restaurants) { 12 | console.log(restaurant.data.name); 13 | console.group(); 14 | await restaurant.getMenu(postalCode); 15 | 16 | if (restaurant.categories) { 17 | for (const category of restaurant.categories) { 18 | for (const product of category.products) { 19 | if (product.name && product.name.toLowerCase().includes('grolsch')) { 20 | console.log(product.name, (product.deliveryPrice ?? 0) / 100); 21 | } 22 | } 23 | } 24 | } 25 | 26 | console.groupEnd(); 27 | } 28 | } catch (err) { 29 | console.error(err); 30 | } 31 | })(); 32 | -------------------------------------------------------------------------------- /example/countries.ts: -------------------------------------------------------------------------------- 1 | import {inspect} from 'util'; 2 | 3 | import {Takeaway, TakeawayConfig} from '../src'; 4 | 5 | const DEBUG = false; 6 | 7 | const print = (obj: any) => { 8 | if (DEBUG) { 9 | console.log(inspect(obj, false, null)); 10 | } 11 | }; 12 | 13 | const inputs = [ 14 | { 15 | language: 'nl', 16 | url: 'https://nl.citymeal.com/android/android.php', 17 | postalCode: '7522' 18 | }, 19 | { 20 | language: 'de', 21 | url: 'https://de.citymeal.com/android/android.php', 22 | postalCode: '44369' 23 | } 24 | ]; 25 | 26 | (async () => { 27 | try { 28 | // Choose input 29 | const input = inputs[0]; 30 | 31 | // Initialize API 32 | const takeaway = new Takeaway( 33 | new TakeawayConfig({ 34 | language: input.language, 35 | url: input.url 36 | }) 37 | ); 38 | 39 | // Get country 40 | const country = await takeaway.getCountryById(input.language.toUpperCase()); 41 | print(country.data); 42 | 43 | // Get restaurants for the postal code 44 | const restaurants = await country.getRestaurants(input.postalCode, '', ''); 45 | 46 | // Loop over all restaurants 47 | for (const restaurant of restaurants) { 48 | print(restaurant); 49 | 50 | const name = restaurant.data.name; 51 | const address = `${restaurant.address.data.street}, ${restaurant.address.data.city}`; 52 | 53 | console.log(`${name} - ${address} - ${restaurant.data.open ? 'OPEN' : 'CLOSED'}`); 54 | } 55 | } catch (err) { 56 | console.error(err); 57 | } 58 | })(); 59 | -------------------------------------------------------------------------------- /example/index.ts: -------------------------------------------------------------------------------- 1 | import {readdirSync} from 'fs'; 2 | 3 | // Parse npm run arguments 4 | const args = JSON.parse(process.env.npm_config_argv as string).original; 5 | 6 | // Find available files 7 | const names = readdirSync('./example') 8 | .filter((f) => f !== 'index.ts' && f.substring(f.length - 3) === '.ts') 9 | .map((f) => f.substring(0, f.length - 3)); 10 | 11 | // Help text 12 | const printHelp = () => { 13 | console.log('Please specify a valid example:'); 14 | console.log(' - npm run example '); 15 | console.log(' - yarn run example '); 16 | console.log(`Options: ${names.join(', ')}`); 17 | }; 18 | 19 | // Check if there are enough arguments 20 | if (args.length <= args.indexOf('example') + 1) { 21 | printHelp(); 22 | } else { 23 | const name = args[args.indexOf('example') + 1]; 24 | if (!names.includes(name)) { 25 | printHelp(); 26 | } else { 27 | console.log(`Running example ./example/${name}.ts`); 28 | 29 | // Execute the file 30 | import(`./${name}.ts`); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/order.ts: -------------------------------------------------------------------------------- 1 | import {inspect} from 'util'; 2 | 3 | import {OptionType, OrderDeliveryMethod, PaymentMethod, Takeaway} from '../src'; 4 | 5 | (async () => { 6 | try { 7 | const takeaway = new Takeaway(); 8 | const postalCode = process.env.POSTAL_CODE as string; 9 | 10 | const country = await takeaway.getCountryById('NL'); 11 | const restaurants = await country.getRestaurants(postalCode, '', ''); 12 | 13 | for (const restaurant of restaurants) { 14 | if (!restaurant.name?.toLowerCase().includes('domino')) { 15 | continue; 16 | } 17 | if (!restaurant.address.street?.toLowerCase().includes('hortensiastraat')) { 18 | continue; 19 | } 20 | 21 | await restaurant.getMenu(postalCode); 22 | await restaurant.getBanks(); 23 | 24 | console.log('Restaurant:'); 25 | console.group(); 26 | console.log(inspect(restaurant.data, false, null)); 27 | console.groupEnd(); 28 | 29 | console.log('Banks:'); 30 | console.group(); 31 | for (const bank of restaurant.banks) { 32 | console.log(bank.data); 33 | } 34 | console.groupEnd(); 35 | 36 | if (restaurant.categories) { 37 | for (const category of restaurant.categories) { 38 | for (const product of category.products) { 39 | if (product.name) { 40 | if (!product.name.toLowerCase().includes('pizza margaritha')) { 41 | continue; 42 | } 43 | if ( 44 | product.name.toLowerCase().includes('vegan') || 45 | product.name.toLowerCase().includes('glutenvrij') 46 | ) { 47 | continue; 48 | } 49 | 50 | const sizeId = product.id as string; 51 | const choiceIds: string[] = []; 52 | 53 | console.log(product.data); 54 | if (product.options) { 55 | console.log('Options:'); 56 | console.group(); 57 | for (const option of product.options) { 58 | console.log(option.optionType, option.data); 59 | 60 | if (option.optionType === OptionType.SINGLE) { 61 | choiceIds.push(option.choices[0].id as string); 62 | } 63 | 64 | if (option.choices) { 65 | console.log('Choices:'); 66 | console.group(); 67 | for (const choice of option.choices) { 68 | console.log(choice.data); 69 | } 70 | console.groupEnd(); 71 | } 72 | } 73 | console.groupEnd(); 74 | } 75 | if (product.sizes) { 76 | console.log('Sizes:'); 77 | console.group(); 78 | for (const size of product.sizes) { 79 | console.log(size.data.id, size.data.name); 80 | } 81 | console.groupEnd(); 82 | } 83 | console.log(); 84 | 85 | console.log('Order format:', product.toOrderFormat(sizeId, choiceIds)); 86 | 87 | const order = await country.order({ 88 | name: process.env.NAME as string, 89 | address: { 90 | street: process.env.STREET as string, 91 | city: process.env.CITY as string, 92 | postalCode: process.env.POSTAL_CODE as string, 93 | deliveryArea: (process.env.POSTAL_CODE as string).substring(0, 4) 94 | }, 95 | phone: process.env.PHONE as string, 96 | email: process.env.EMAIL as string, 97 | 98 | restaurant, 99 | products: [ 100 | { 101 | product, 102 | sizeId, 103 | choiceIds 104 | } 105 | ], 106 | 107 | deliveryMethod: OrderDeliveryMethod.DELIVERY, 108 | deliveryTime: '', 109 | paymentMethod: PaymentMethod.IDEAL, 110 | bank: restaurant.banks.find((bank) => bank.name?.toLowerCase() === 'bunq'), 111 | 112 | clientId: Math.floor(Math.random() * 10 ** 10) 113 | .toString() 114 | .padStart(10, '0') 115 | }); 116 | console.log(order.data); 117 | 118 | // Exit after ordering 119 | process.exit(0); 120 | } 121 | } 122 | } 123 | } 124 | } 125 | } catch (err) { 126 | console.error(err); 127 | } 128 | })(); 129 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "takeaway", 3 | "description": "Unofficial JavaScript implementation of the Takeaway.com API.", 4 | "version": "0.4.6", 5 | "license": "MIT", 6 | "author": "Danielle Huisman (https://github.com/DanielleHuisman)", 7 | "contributors": [], 8 | "repository": "github:TakeawayAPI/node-takeaway", 9 | "keywords": [ 10 | "takeaway", 11 | "thuisbezorgd", 12 | "food", 13 | "api" 14 | ], 15 | "main": "lib/index.js", 16 | "types": "lib/index.d.ts", 17 | "files": [ 18 | "lib", 19 | "README.md", 20 | "LICENSE.md", 21 | "package.json" 22 | ], 23 | "scripts": { 24 | "lint": "eslint ./src --ext ts", 25 | "clean": "rimraf lib", 26 | "build": "yarn run clean && yarn run lint && yarn run build:ts", 27 | "build:ts": "tsc", 28 | "test": "echo \"Test are not implemented yet.\"", 29 | "example": "dotenv -e example/.env -- ts-node example/index.ts", 30 | "prepublish": "yarn run build" 31 | }, 32 | "dependencies": { 33 | "@rgrove/parse-xml": "^4.1.0" 34 | }, 35 | "devDependencies": { 36 | "@trivago/prettier-plugin-sort-imports": "^4.2.1", 37 | "@types/node": "^20.9.0", 38 | "@typescript-eslint/eslint-plugin": "^6.10.0", 39 | "@typescript-eslint/parser": "^6.10.0", 40 | "dotenv-cli": "^7.3.0", 41 | "eslint": "^8.53.0", 42 | "prettier": "^3.0.3", 43 | "rimraf": "^5.0.5", 44 | "ts-node": "^10.9.1", 45 | "typescript": "^5.2.2" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/api.ts: -------------------------------------------------------------------------------- 1 | import {TakeawayClient} from './client'; 2 | import {TakeawayConfig} from './config'; 3 | import {Country} from './models'; 4 | 5 | export class Takeaway { 6 | client: TakeawayClient; 7 | 8 | constructor(client?: TakeawayConfig | TakeawayClient) { 9 | if (client instanceof TakeawayConfig) { 10 | this.client = new TakeawayClient(client); 11 | } else if (client instanceof TakeawayClient) { 12 | this.client = client; 13 | } else { 14 | this.client = new TakeawayClient(new TakeawayConfig()); 15 | } 16 | } 17 | 18 | getClient() { 19 | return this.client; 20 | } 21 | 22 | getConfig() { 23 | return this.getClient().config; 24 | } 25 | 26 | getLanguage() { 27 | return this.getConfig().language; 28 | } 29 | 30 | async getCountries(): Promise { 31 | const data = await this.getClient().getCountries(); 32 | return data.config.countries.map((country: any) => new Country(this, country)); 33 | } 34 | 35 | async getCountryById(id: string): Promise { 36 | const countries = await this.getCountries(); 37 | return countries.filter((country: any) => country.id === id)[0]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/client.ts: -------------------------------------------------------------------------------- 1 | import {parseXml} from '@rgrove/parse-xml'; 2 | 3 | import {TakeawayConfig} from './config'; 4 | import parse from './parse'; 5 | import requests from './requests'; 6 | import {md5} from './util'; 7 | 8 | export interface RequestDefinition { 9 | parameters: (parameters?: RequestParameters) => string[]; 10 | response: ResponseDefinition; 11 | } 12 | 13 | export interface ResponseDefinition { 14 | [k: string]: string | string[] | ResponseDefinition | ResponseDefinition[]; 15 | } 16 | 17 | export interface RequestParameters { 18 | [k: string]: any; 19 | } 20 | 21 | export interface RequestOptions { 22 | format?: 'text' | 'xml' | 'json'; 23 | debug?: boolean; 24 | } 25 | 26 | export class TakeawayClient { 27 | config: TakeawayConfig; 28 | 29 | constructor(config: TakeawayConfig) { 30 | if (!config || !(config instanceof TakeawayConfig)) { 31 | throw new Error('Invalid configuration'); 32 | } 33 | this.config = config; 34 | } 35 | 36 | getAddresses = (data?: RequestParameters, options?: RequestOptions) => 37 | this.request(requests.getAddresses, data, options); 38 | getBanks = (data?: RequestParameters, options?: RequestOptions) => this.request(requests.getBanks, data, options); 39 | getCountries = (data?: RequestParameters, options?: RequestOptions) => 40 | this.request(requests.getCountries, data, options); 41 | getDiscounts = (data?: RequestParameters, options?: RequestOptions) => 42 | this.request(requests.getDiscounts, data, options); 43 | getGeoLocation = (data?: RequestParameters, options?: RequestOptions) => 44 | this.request(requests.getGeoLocation, data, options); 45 | getHistory = (data?: RequestParameters, options?: RequestOptions) => 46 | this.request(requests.getHistory, data, options); 47 | getHistoryDetails = (data?: RequestParameters, options?: RequestOptions) => 48 | this.request(requests.getHistoryDetails, data, options); 49 | getLoyaltyPoints = (data?: RequestParameters, options?: RequestOptions) => 50 | this.request(requests.getLoyaltyPoints, data, options); 51 | getMenuCard = (data?: RequestParameters, options?: RequestOptions) => 52 | this.request(requests.getMenuCard, data, options); 53 | getRestaurantData = (data?: RequestParameters, options?: RequestOptions) => 54 | this.request(requests.getRestaurantData, data, options); 55 | getRestaurants = (data?: RequestParameters, options?: RequestOptions) => 56 | this.request(requests.getRestaurants, data, options); 57 | getReviews = (data?: RequestParameters, options?: RequestOptions) => 58 | this.request(requests.getReviews, data, options); 59 | getServerTime = (data?: RequestParameters, options?: RequestOptions) => 60 | this.request(requests.getServerTime, data, options); 61 | getURLs = (data?: RequestParameters, options?: RequestOptions) => this.request(requests.getURLs, data, options); 62 | login = (data?: RequestParameters, options?: RequestOptions) => this.request(requests.login, data, options); 63 | order = (data?: RequestParameters, options?: RequestOptions) => this.request(requests.order, data, options); 64 | resetPassword = (data?: RequestParameters, options?: RequestOptions) => 65 | this.request(requests.resetPassword, data, options); 66 | 67 | async request( 68 | definition: RequestDefinition, 69 | data?: RequestParameters, 70 | {format = 'json', debug = false, ...options}: RequestOptions = {} 71 | ): Promise { 72 | // Generate parameter list from data 73 | const parameters = definition.parameters(data); 74 | 75 | // Generate MD5 hash of parameters and password 76 | let inputMd5 = ''; 77 | for (const parameter of parameters) { 78 | inputMd5 += parameter; 79 | } 80 | parameters.unshift(md5(inputMd5 + this.config.getPassword())); 81 | 82 | // Set headers 83 | const headers = new Headers(); 84 | headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8'); 85 | 86 | // Make the request 87 | const response = await fetch(this.config.getUrl(), { 88 | method: 'POST', 89 | headers, 90 | body: parameters 91 | .map((parameter, index) => `var${index}=${encodeURIComponent(parameter)}`) 92 | .concat([this.config.getDefaultQuery()]) 93 | .join('&'), 94 | ...options 95 | }); 96 | 97 | // Check if the request was successful 98 | if (response.status >= 200 && response.status <= 399) { 99 | const text = await response.text(); 100 | if (debug) { 101 | console.debug(text); 102 | } 103 | 104 | // Return raw XML text 105 | if (format === 'text') { 106 | return text; 107 | } 108 | 109 | // Parse the raw XML to a JS representation 110 | const xml = parseXml(text); 111 | if (format === 'xml') { 112 | return xml; 113 | } 114 | 115 | // Parse the XML representation to JSON with beatified names 116 | if (format === 'json') { 117 | return parse(definition.response, xml); 118 | } 119 | 120 | // Unknown format, return the raw response 121 | return response; 122 | } else { 123 | throw new Error(`Request failed (${response.status} ${response.statusText}): ${await response.text()}`); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | export class TakeawayConfig { 2 | language: string; 3 | url: string; 4 | password: string; 5 | version: string; 6 | systemVersion: string; 7 | appVersion: string; 8 | appName: string; 9 | 10 | constructor({ 11 | language = 'nl', 12 | url = 'https://nl.citymeal.com/android/android.php', 13 | password = '4ndro1d', 14 | version = '5.7', 15 | systemVersion = '29', 16 | appVersion = '8.29.0', 17 | appName = 'Takeaway.com' 18 | } = {}) { 19 | this.language = language; 20 | this.url = url; 21 | this.password = password; 22 | this.version = version; 23 | this.systemVersion = systemVersion; 24 | this.appVersion = appVersion; 25 | this.appName = appName; 26 | } 27 | 28 | getLanguage() { 29 | return this.language; 30 | } 31 | 32 | getUrl() { 33 | return this.url; 34 | } 35 | 36 | getPassword() { 37 | return this.password; 38 | } 39 | 40 | getDefaultQuery() { 41 | return `&version=${this.version}&systemversion=${this.systemVersion};${this.appVersion}&appname=${this.appName}&language=${this.language}`; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api'; 2 | export * from './config'; 3 | export * from './client'; 4 | export * from './inputs'; 5 | export * from './models'; 6 | -------------------------------------------------------------------------------- /src/inputs/OrderInput.ts: -------------------------------------------------------------------------------- 1 | import {type Address, type Bank, type PaymentMethod, type Product, type Restaurant, type User} from '../models'; 2 | 3 | export interface OrderAddress { 4 | street: string; 5 | city: string; 6 | postalCode: string; 7 | deliveryArea: string; 8 | } 9 | 10 | export interface OrderVietnamAddress { 11 | street: string; 12 | city: string; 13 | district: string; 14 | } 15 | 16 | export enum OrderDeliveryMethod { 17 | DELIVERY = '0', 18 | PICKUP = '1' 19 | } 20 | 21 | export interface OrderInput { 22 | name: string; 23 | companyName?: string; 24 | address: OrderAddress | OrderVietnamAddress; 25 | phone: string; 26 | email: string; 27 | 28 | restaurant: Restaurant; 29 | products: { 30 | product: Product; 31 | sizeId: string; 32 | choiceIds: string[]; 33 | }[]; 34 | 35 | remarks?: string; 36 | newsLetter?: boolean; 37 | 38 | deliveryMethod: OrderDeliveryMethod; 39 | deliveryTime: string; 40 | paymentMethod: PaymentMethod; 41 | bank?: Bank; 42 | voucherCode?: string; 43 | 44 | clientId?: string; 45 | user?: User; 46 | userAddress?: Address; 47 | 48 | latitude?: boolean; 49 | longitude?: boolean; 50 | isLocationAccurate?: boolean; 51 | } 52 | -------------------------------------------------------------------------------- /src/inputs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './OrderInput'; 2 | -------------------------------------------------------------------------------- /src/models/Address.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | 5 | @Model 6 | export class Address extends BaseModel { 7 | static relationships = []; 8 | 9 | id?: string; 10 | street?: string; 11 | number?: string; 12 | postalCode?: string; 13 | city?: string; 14 | phone?: string; 15 | latitude?: string; 16 | longitude?: string; 17 | deliveryAreaId?: string; 18 | deliveryArea?: string; 19 | vietnamCity?: string; 20 | vietnamArea?: string; 21 | vietnamCityId?: string; 22 | vietnamDistrict?: string; 23 | vietnamDistrictId?: string; 24 | extra?: { 25 | flatNumber?: string; 26 | house?: string; 27 | entrance?: string; 28 | stock?: string; 29 | door?: string; 30 | accessCode?: string; 31 | intercom?: string; 32 | floor?: string; 33 | residence?: string; 34 | apartment?: string; 35 | building?: string; 36 | hotel?: string; 37 | compound?: string; 38 | room?: string; 39 | compoundAddresss?: string; 40 | ward?: string; 41 | company?: string; 42 | }; 43 | 44 | constructor(takeaway: Takeaway, data: Data) { 45 | super(takeaway, data); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/models/Bank.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | 5 | @Model 6 | export class Bank extends BaseModel { 7 | static relationships = []; 8 | 9 | id?: string; 10 | name?: string; 11 | mobileWebsite?: string; 12 | 13 | constructor(takeaway: Takeaway, data: Data) { 14 | super(takeaway, data); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/models/Category.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | import {Product} from './Product'; 5 | 6 | @Model 7 | export class Category extends BaseModel { 8 | static relationships = ['products']; 9 | 10 | id?: string; 11 | name?: string; 12 | description?: string; 13 | imageUrl?: string; 14 | openingHours?: { 15 | day?: { 16 | number?: string; 17 | time?: { 18 | start?: Date; 19 | end?: Date; 20 | }; 21 | }; 22 | }; 23 | time?: { 24 | start?: Date; 25 | end?: Date; 26 | }; 27 | products: Product[]; 28 | 29 | constructor(takeaway: Takeaway, data: Data) { 30 | super(takeaway, data); 31 | 32 | this.products = data.products.products.map((product) => new Product(takeaway, product)); 33 | delete data.products; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/models/Choice.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | import {type FoodInformation} from './Product'; 5 | 6 | @Model 7 | export class Choice extends BaseModel { 8 | static relationships = []; 9 | 10 | id?: string; 11 | name?: string; 12 | deliveryPrice?: number; 13 | pickupPrice?: number; 14 | excludedFromMinimum?: boolean; 15 | information?: FoodInformation; 16 | 17 | constructor(takeaway: Takeaway, data: Data) { 18 | super(takeaway, data); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/models/Country.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | import {type OrderAddress, type OrderInput, type OrderVietnamAddress} from '../inputs/OrderInput'; 3 | 4 | import {Address} from './Address'; 5 | import {BaseModel, type Data, Model} from './Model'; 6 | import {Order} from './Order'; 7 | import {PaymentMethod, Restaurant} from './Restaurant'; 8 | import {User} from './User'; 9 | 10 | interface Translations { 11 | bg?: string; 12 | da?: string; 13 | de?: string; 14 | en?: string; 15 | fr?: string; 16 | it?: string; 17 | lu?: string; 18 | nl?: string; 19 | pl?: string; 20 | pt?: string; 21 | ro?: string; 22 | sv?: string; 23 | vi?: string; 24 | } 25 | 26 | @Model 27 | export class Country extends BaseModel { 28 | static relationships = []; 29 | 30 | id?: string; 31 | name?: string; 32 | siteUrl?: string; 33 | pregMatch1?: RegExp; 34 | pregMatch2?: RegExp; 35 | pregMatch3?: RegExp; 36 | message1?: string; 37 | message2?: string; 38 | twitter?: string; 39 | email?: string; 40 | logoUrl?: string; 41 | iconUrl?: string; 42 | headerUrl?: string; 43 | code?: string; 44 | siteCode?: string; 45 | pickupEnabled?: boolean; 46 | loyaltyShopEnabled?: boolean; 47 | languages?: { 48 | languages?: string[]; 49 | }; 50 | descriptions?: Translations; 51 | movies?: Translations; 52 | enabledRecurringPayments?: { 53 | methods?: string[]; 54 | }; 55 | autoComplete?: { 56 | gp: { 57 | id?: string; 58 | apiKey?: string; 59 | poweredBy?: string; 60 | }; 61 | nm: { 62 | id?: string; 63 | url?: string; 64 | apiKey?: string; 65 | }; 66 | preferred?: string; 67 | }; 68 | 69 | constructor(takeaway: Takeaway, data: Data) { 70 | super(takeaway, data); 71 | } 72 | 73 | async login(email: string, credentials: string): Promise { 74 | const data = await this.takeaway.getClient().login({ 75 | email, 76 | credentials, 77 | countryCode: this.code, 78 | siteCode: this.siteCode 79 | }); 80 | return new User(this.takeaway, data.login, this); 81 | } 82 | 83 | async socialLogin(socialType: string, socialToken: string): Promise { 84 | const data = await this.takeaway.getClient().login({ 85 | socialType, 86 | socialToken, 87 | countryCode: this.code, 88 | siteCode: this.siteCode 89 | }); 90 | return new User(this.takeaway, data.login, this); 91 | } 92 | 93 | async getLocation(latitude: string, longitude: string): Promise
{ 94 | const data = await this.takeaway.getClient().getGeoLocation({ 95 | country: this.code, 96 | latitude, 97 | longitude 98 | }); 99 | return new Address(this.takeaway, data.location); 100 | } 101 | 102 | async getRestaurants(postalCode: string, latitude: string, longitude: string): Promise { 103 | const data = await this.takeaway.getClient().getRestaurants({ 104 | country: this.code, 105 | postalCode, 106 | latitude, 107 | longitude, 108 | language: this.takeaway.getLanguage() 109 | }); 110 | return data.restaurants.restaurants.map((restaurant) => new Restaurant(this.takeaway, restaurant, this)); 111 | } 112 | 113 | async order(orderInput: OrderInput): Promise { 114 | const address: {[k: string]: any} = {}; 115 | 116 | if ((orderInput.address as OrderVietnamAddress).district) { 117 | orderInput.address = orderInput.address as OrderVietnamAddress; 118 | 119 | address.street = orderInput.address.street; 120 | address.vietnamCity = orderInput.address.city; 121 | address.vietnamDistrict = orderInput.address.district; 122 | } else { 123 | orderInput.address = orderInput.address as OrderAddress; 124 | 125 | address.street = orderInput.address.street; 126 | address.postalCode = orderInput.address.postalCode; 127 | address.city = orderInput.address.city; 128 | address.deliveryArea = orderInput.address.deliveryArea; 129 | } 130 | 131 | const data = await this.takeaway.getClient().order({ 132 | // Country information 133 | countryCode: this.code, 134 | siteCode: this.siteCode, 135 | language: this.takeaway.getLanguage(), 136 | 137 | // Address information 138 | name: orderInput.name, 139 | companyName: orderInput.companyName || '', 140 | phone: orderInput.phone, 141 | email: orderInput.email, 142 | ...address, 143 | extraAddress: '', // TODO 144 | 145 | // Order information 146 | restaurantId: orderInput.restaurant.id, 147 | formattedOrder: orderInput.products.map((product) => 148 | product.product.toOrderFormat(product.sizeId, product.choiceIds) 149 | ), 150 | 151 | // Remarks 152 | remarks: orderInput.remarks, 153 | productRemarks: '', // TODO 154 | newsLetter: orderInput.newsLetter ? '1' : '0', 155 | 156 | // Delivery information 157 | deliveryMethod: orderInput.deliveryMethod, 158 | deliveryTime: orderInput.deliveryTime || '', 159 | 160 | // Payment information 161 | paymentMethod: orderInput.paymentMethod, 162 | bankId: orderInput.bank ? orderInput.bank.id : '', 163 | paymentPart: '', // TODO 164 | voucherCode: orderInput.paymentMethod === PaymentMethod.VOUCHER ? orderInput.voucherCode : '', 165 | 166 | // User/client information 167 | foodTrackerId: '', // TODO 168 | clientId: orderInput.user ? '' : orderInput.clientId || '', 169 | username: orderInput.user ? orderInput.user.email : '', 170 | // credentials: orderInput.user ? orderInput.user.credentials : '', 171 | credentials: '', // TODO: ^ 172 | addressId: orderInput.user && orderInput.userAddress ? orderInput.userAddress.id || '' : '', 173 | 174 | // Location information 175 | latitude: orderInput.latitude || '', 176 | longitude: orderInput.longitude || '', 177 | isLocationAccurate: orderInput.isLocationAccurate ? '1' : '0' 178 | }); 179 | return new Order(this.takeaway, data); 180 | } 181 | } 182 | 183 | export default Country; 184 | -------------------------------------------------------------------------------- /src/models/HistoryOrder.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {HistoryProduct} from './HistoryProduct'; 4 | import {BaseModel, type Data, Model} from './Model'; 5 | import {type User} from './User'; 6 | 7 | @Model 8 | export class HistoryOrder extends BaseModel { 9 | static relationships = ['user', 'products']; 10 | 11 | id?: string; 12 | timestamp?: string; 13 | addressId?: string; 14 | steet?: string; 15 | number?: string; 16 | postalCode?: string; 17 | deliveryAreaId?: string; 18 | deliveryArea?: string; 19 | city?: string; 20 | restaurantId?: string; 21 | restaurantName?: string; 22 | restaurantLogoUrl?: string; 23 | orderNumber?: string; 24 | deliveryMethod?: string; 25 | vietnamCity?: string; 26 | vietnamDistrict?: string; 27 | vietnamDistrictId?: string; 28 | latitude?: string; 29 | longitude?: string; 30 | totalPrice?: number; 31 | deliveryCosts?: number; 32 | transactionCosts?: number; 33 | paymentMethod?: string; 34 | discountReceived?: boolean; 35 | polygonStatus?: string; 36 | user: User; 37 | products: HistoryProduct[]; 38 | 39 | constructor(takeaway: Takeaway, data: Data, user: User) { 40 | super(takeaway, data); 41 | this.user = user; 42 | } 43 | 44 | async getDetails() { 45 | const data = await this.takeaway.getClient().getHistoryDetails({ 46 | email: this.user.email, 47 | credentials: this.user.token, 48 | countryCode: this.user.country.code, 49 | siteCode: this.user.country.siteCode, 50 | orderId: this.id 51 | }); 52 | this.data = Object.assign({}, this.data, data.order); 53 | 54 | this.products = data.order.products.map((product: any) => new HistoryProduct(this.takeaway, product)); 55 | delete this.data.products; 56 | return this.products; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/models/HistoryProduct.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | 5 | @Model 6 | export class HistoryProduct extends BaseModel { 7 | static relationships = []; 8 | 9 | id?: string; 10 | name?: string; 11 | price?: number; 12 | rmk?: string; 13 | options?: { 14 | id?: string; 15 | name?: string; 16 | price?: number; 17 | }; 18 | 19 | constructor(takeaway: Takeaway, data: Data) { 20 | super(takeaway, data); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/models/Loyalty.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | 5 | @Model 6 | export class Loyalty extends BaseModel { 7 | static relationships = []; 8 | 9 | unavailable?: boolean; 10 | points?: string; 11 | url?: string; 12 | externalBrowser?: boolean; 13 | 14 | constructor(takeaway: Takeaway, data: Data) { 15 | super(takeaway, data); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/models/Model.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | export const Model = (ProxyTarget) => { 4 | return new Proxy(ProxyTarget, { 5 | construct(Target, args) { 6 | const model = new Target(...args); 7 | 8 | return new Proxy(model, { 9 | get(target, name, receiver) { 10 | if (name === 'data' || (Target.relationships && Target.relationships.includes(name))) { 11 | return target[name]; 12 | } 13 | 14 | if (target.data && Object.prototype.hasOwnProperty.call(target.data, name)) { 15 | return target.data[name]; 16 | } 17 | return Reflect.get(target, name, receiver); 18 | }, 19 | set(target, name, value) { 20 | if (name === 'data' || (Target.relationships && Target.relationships.includes(name))) { 21 | target[name] = value; 22 | return true; 23 | } 24 | 25 | target.data[name] = value; 26 | return true; 27 | } 28 | }); 29 | } 30 | }); 31 | }; 32 | 33 | export interface Data { 34 | [k: string]: any; 35 | } 36 | 37 | export class BaseModel { 38 | takeaway: Takeaway; 39 | data: any; 40 | 41 | constructor(takeaway: Takeaway, data: Data) { 42 | this.takeaway = takeaway; 43 | this.data = data; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/models/Option.ts: -------------------------------------------------------------------------------- 1 | import type {Takeaway} from '../api'; 2 | 3 | import {Choice} from './Choice'; 4 | import {BaseModel, type Data, Model} from './Model'; 5 | 6 | export enum OptionType { 7 | SINGLE = 'SINGLE', 8 | MULTIPLE = 'MULTIPLE' 9 | } 10 | 11 | const OPTION_TYPES = { 12 | 1: OptionType.SINGLE, 13 | 2: OptionType.MULTIPLE 14 | }; 15 | 16 | @Model 17 | export class Option extends BaseModel { 18 | static relationships = ['choices']; 19 | 20 | name?: string; 21 | type?: string; 22 | optionType?: OptionType; 23 | choices: Choice[]; 24 | 25 | constructor(takeaway: Takeaway, data: Data) { 26 | super(takeaway, data); 27 | 28 | if (data.type) { 29 | this.optionType = OPTION_TYPES[data.type]; 30 | } 31 | 32 | if (data.choices) { 33 | this.choices = data.choices.choices.map((choice) => new Choice(takeaway, choice)); 34 | delete data.choices; 35 | } else { 36 | this.choices = []; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/models/Order.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | 5 | @Model 6 | export class Order extends BaseModel { 7 | static relationships = []; 8 | 9 | constructor(takeaway: Takeaway, data: Data) { 10 | super(takeaway, data); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/models/Product.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | import {Option} from './Option'; 5 | import {ProductSize} from './ProductSize'; 6 | 7 | export interface FoodInformation { 8 | allergens?: { 9 | ids?: string[]; 10 | }; 11 | additives?: { 12 | ids?: string[]; 13 | }; 14 | nutritionFacts?: string; 15 | extra?: { 16 | caffeine?: string; 17 | alcoholPerVolume?: string; 18 | bottleDeposit?: string; 19 | volumePerLitre?: string; 20 | costPerLitreDelivery?: string; 21 | costPerLitrePickup?: string; 22 | volumePerKilogram?: string; 23 | costPerGramDelivery?: string; 24 | costPerGramPickup?: string; 25 | costPerLiterDelivery?: string; 26 | }; 27 | } 28 | 29 | @Model 30 | export class Product extends BaseModel { 31 | static relationships = ['options', 'sizes']; 32 | 33 | id?: string; 34 | name?: string; 35 | description?: string; 36 | photoUrl?: string; 37 | deliveryMethod?: string; 38 | deliveryPrice?: number; 39 | pickupPrice?: number; 40 | excludedFromMinimum?: boolean; 41 | information?: FoodInformation; 42 | options: Option[]; 43 | sizes: ProductSize[]; 44 | sizeIds: string[]; 45 | choiceIds: string[]; 46 | 47 | constructor(takeaway: Takeaway, data: Data) { 48 | super(takeaway, data); 49 | 50 | if (data.options && data.options.options) { 51 | this.options = data.options.options.map((choice) => new Option(takeaway, choice)); 52 | delete data.options; 53 | 54 | this.choiceIds = this.options.reduce( 55 | (prev, option) => prev.concat(option.choices.map((choice) => choice.id)), 56 | [] 57 | ); 58 | } else { 59 | this.options = []; 60 | this.choiceIds = []; 61 | } 62 | 63 | if (data.sizes && data.sizes.products) { 64 | // NOTE: product sizes are exactly the same as products, but due to a weird bug the model proxy woudln't work when recursively creating the product 65 | this.sizes = data.sizes.products.map((size) => new ProductSize(takeaway, size)); 66 | this.sizeIds = this.sizes.map((size) => size.id).concat([data.id]); 67 | delete data.sizes; 68 | } else { 69 | this.sizes = []; 70 | } 71 | } 72 | 73 | toOrderFormat(sizeId: string = null, choiceIds: string[] = []) { 74 | // Validate size ID 75 | if (!sizeId) { 76 | sizeId = this.data.id; 77 | } else if (!this.sizeIds.includes(sizeId)) { 78 | throw new Error(`Unknown product size ID "${sizeId}"`); 79 | } 80 | 81 | // Validate choice IDs 82 | for (const choiceId of choiceIds) { 83 | if (!this.choiceIds.includes(choiceId)) { 84 | throw new Error(`Unknown choice ID "${choiceId}"`); 85 | } 86 | } 87 | 88 | // Format product as order 89 | if (choiceIds.length > 0) { 90 | return `${sizeId},${choiceIds.join(',')};`; 91 | } 92 | return `${sizeId};`; 93 | } 94 | } 95 | 96 | export default Product; 97 | -------------------------------------------------------------------------------- /src/models/ProductSize.ts: -------------------------------------------------------------------------------- 1 | import {type Takeaway} from '../api'; 2 | 3 | import {BaseModel, Model} from './Model'; 4 | import {Option} from './Option'; 5 | import {type FoodInformation} from './Product'; 6 | 7 | @Model 8 | export class ProductSize extends BaseModel { 9 | static relationships = ['options']; 10 | 11 | id?: string; 12 | description?: string; 13 | photoUrl?: string; 14 | deliveryMethod?: string; 15 | deliveryPrice?: number; 16 | pickupPrice?: number; 17 | excludedFromMinimum?: boolean; 18 | information?: FoodInformation; 19 | options: Option[]; 20 | 21 | constructor(takeaway: Takeaway, data) { 22 | super(takeaway, data); 23 | 24 | if (data.options && data.options.options) { 25 | this.options = data.options.options.map((choice) => new Option(takeaway, choice)); 26 | delete data.options; 27 | } else { 28 | this.options = []; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/models/Restaurant.ts: -------------------------------------------------------------------------------- 1 | import type {Takeaway} from '../api'; 2 | 3 | import {Address} from './Address'; 4 | import {Bank} from './Bank'; 5 | import {Category} from './Category'; 6 | import type Country from './Country'; 7 | import {BaseModel, type Data, Model} from './Model'; 8 | import {Review} from './Review'; 9 | 10 | export enum PaymentMethod { 11 | DELIVERY_CASH = '0', 12 | DELIVERY_MOBILE_PIN = '2', 13 | DELIVERY_CREDITCARD = '4', 14 | DELIVERY_BANCONTACT = '20', 15 | IDEAL = '3', 16 | CREDITCARD = '6', 17 | VOUCHER = '13', 18 | SOFORT = '15', 19 | MRCASH = '16', 20 | PAYPAL = '18', 21 | GOOGLE_PAY = '30', 22 | PAYU = '31', 23 | MOMO = '33' 24 | } 25 | 26 | export enum DeliveryMethod { 27 | DELIVERY = '1', 28 | DELIVERY_AND_PICKUP = '2', 29 | PICKUP = '3' 30 | } 31 | 32 | export interface Time { 33 | currentTime?: Date; 34 | td?: { 35 | time?: { 36 | start?: Date; 37 | end?: Date; 38 | }; 39 | }; 40 | tm?: { 41 | time?: { 42 | start?: Date; 43 | end?: Date; 44 | }; 45 | }; 46 | } 47 | 48 | @Model 49 | export class Restaurant extends BaseModel { 50 | static relationships = ['country', 'address', 'categories', 'banks']; 51 | 52 | id?: string; 53 | name?: string; 54 | tip?: boolean; 55 | new?: boolean; 56 | open?: boolean; 57 | branch?: string; 58 | payments?: { 59 | methods?: { 60 | id?: string; 61 | fixedCosts?: number; 62 | percentageCosts?: string; 63 | }[]; 64 | }; 65 | estimatedDeliveryTime?: string; 66 | polygonStatus?: string; 67 | deliveryMethods?: { 68 | orderMethods?: string; 69 | delivery?: { 70 | open?: boolean; 71 | orderAhead?: boolean; 72 | mealPrepTime?: number; 73 | }; 74 | pickup?: { 75 | open?: boolean; 76 | orderAhead?: boolean; 77 | mealPrepTime?: number; 78 | }; 79 | }; 80 | deliveryCosts?: { 81 | minimumAmount?: number; 82 | costs?: { 83 | from?: number; 84 | to?: number; 85 | costs?: number; 86 | }; 87 | }; 88 | deliveryDistricts?: { 89 | areas?: { 90 | postalCode?: string[]; 91 | minimumAmount?: number; 92 | costs?: { 93 | from?: number; 94 | to?: number; 95 | costs?: number; 96 | }; 97 | }[]; 98 | }; 99 | kitchens?: { 100 | ids: string[]; 101 | }; 102 | subKitchens?: { 103 | ids: string[]; 104 | }; 105 | popularDishes?: { 106 | ids: string[]; 107 | }; 108 | sorting?: { 109 | s1?: string; 110 | s2?: string; 111 | s3?: string; 112 | s4?: string; 113 | s5?: string; 114 | s6?: string; 115 | s7?: string; 116 | s8?: string; 117 | s9?: string; 118 | }; 119 | information?: string; 120 | grade?: number; 121 | ratingCount?: number; 122 | logoUrl?: string; 123 | headerImageUrl?: string; 124 | cacheKey?: string; 125 | hasDiscounts?: boolean; 126 | hasFoodTracker?: boolean; 127 | distance?: number; 128 | legal?: { 129 | owner?: string; 130 | commericalRegister?: string; 131 | chamberOfCommerce?: string; 132 | vat?: string; 133 | address?: { 134 | street?: string; 135 | number?: string; 136 | postalCode?: string; 137 | city?: string; 138 | }; 139 | }; 140 | deliveryTime?: Time; 141 | pickupTime?: Time; 142 | country: Country; 143 | address: Address; 144 | categories: Category[]; 145 | banks: Bank[]; 146 | 147 | constructor(takeaway: Takeaway, data: Data, country: Country) { 148 | super(takeaway, data); 149 | this.country = country; 150 | 151 | this.address = new Address(takeaway, data.address); 152 | delete data.address; 153 | } 154 | 155 | async getMenu(postalCode: string): Promise { 156 | const data = await this.takeaway.getClient().getMenuCard({ 157 | restaurantId: this.id, 158 | country: this.country.code, 159 | postalCode, 160 | latitude: this.address.latitude, 161 | longitude: this.address.longitude 162 | }); 163 | this.data = Object.assign({}, this.data, data.restaurant); 164 | 165 | if (this.data.menu && this.data.menu.length > 0) { 166 | this.categories = this.data.menu[0].categories.categories.map( 167 | (category: any) => new Category(this.takeaway, category) 168 | ); 169 | delete this.data.menu[0].categories; 170 | return this.categories; 171 | } else { 172 | return []; 173 | } 174 | } 175 | 176 | async getReviews(page = 1): Promise { 177 | const data = await this.takeaway.getClient().getReviews({ 178 | restaurantId: this.id, 179 | page 180 | }); 181 | 182 | return data.reviews.reviews.map((review: any) => new Review(this.takeaway, review)); 183 | } 184 | 185 | async getTime(orderMode: string) { 186 | const data = await this.takeaway.getClient().getServerTime({ 187 | country: this.country.code, 188 | restaurantId: this.id, 189 | orderMode 190 | }); 191 | 192 | this.open = data.time.open; 193 | return data.time; 194 | } 195 | 196 | async getBanks(): Promise { 197 | const data = await this.takeaway.getClient().getBanks({ 198 | restaurantId: this.id 199 | }); 200 | 201 | this.banks = data.banks.banks.map((bank: any) => new Bank(this.takeaway, bank)); 202 | return this.banks; 203 | } 204 | } 205 | 206 | export default Restaurant; 207 | -------------------------------------------------------------------------------- /src/models/Review.ts: -------------------------------------------------------------------------------- 1 | import type {Takeaway} from '../api'; 2 | 3 | import {BaseModel, type Data, Model} from './Model'; 4 | 5 | @Model 6 | export class Review extends BaseModel { 7 | static relationships = []; 8 | 9 | name?: string; 10 | time?: string; 11 | description?: string; 12 | quality?: number; 13 | delivery?: string; 14 | sunday?: boolean; 15 | orderMethod?: string; 16 | 17 | constructor(takeaway: Takeaway, data: Data) { 18 | super(takeaway, data); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/models/User.ts: -------------------------------------------------------------------------------- 1 | import type {Takeaway} from '../api'; 2 | 3 | import {Address} from './Address'; 4 | import type {Country} from './Country'; 5 | import {HistoryOrder} from './HistoryOrder'; 6 | import {Loyalty} from './Loyalty'; 7 | import {BaseModel, Model} from './Model'; 8 | 9 | @Model 10 | export class User extends BaseModel { 11 | static relationships = ['country', 'addresses', 'loyalty']; 12 | 13 | id?: string; 14 | token?: string; 15 | firstName?: string; 16 | lastName?: string; 17 | email?: string; 18 | oldOrders?: string; 19 | ac?: string; 20 | social?: { 21 | id?: string; 22 | username?: string; 23 | }; 24 | migrated?: boolean; 25 | country: Country; 26 | addresses: Address[]; 27 | loyalty: Loyalty; 28 | 29 | constructor(takeaway: Takeaway, data, country: Country) { 30 | super(takeaway, data); 31 | this.country = country; 32 | 33 | if (data.contacts) { 34 | this.addresses = data.contacts.addresses.map((address: any) => new Address(takeaway, address)); 35 | delete data.contacts; 36 | } else { 37 | this.addresses = []; 38 | } 39 | } 40 | 41 | async getLoyalty(): Promise { 42 | const data = await this.takeaway.getClient().getLoyaltyPoints({ 43 | email: this.email, 44 | credentials: this.token, 45 | countryCode: this.country.code, 46 | siteCode: this.country.siteCode, 47 | language: this.takeaway.getLanguage() 48 | }); 49 | 50 | this.loyalty = new Loyalty(this.takeaway, data.loyalty); 51 | return this.loyalty; 52 | } 53 | 54 | async getHistory(page = 1): Promise { 55 | const data = await this.takeaway.getClient().getHistory({ 56 | email: this.email, 57 | credentials: this.token, 58 | countryCode: this.country.code, 59 | siteCode: this.country.siteCode, 60 | page 61 | }); 62 | 63 | return data.history.orders.map((order: any) => new HistoryOrder(this.takeaway, order, this)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Address'; 2 | export * from './Bank'; 3 | export * from './Category'; 4 | export * from './Choice'; 5 | export * from './Country'; 6 | export * from './HistoryOrder'; 7 | export * from './HistoryProduct'; 8 | export * from './Loyalty'; 9 | export * from './Option'; 10 | export * from './Product'; 11 | export * from './Restaurant'; 12 | export * from './Review'; 13 | export * from './User'; 14 | -------------------------------------------------------------------------------- /src/parse.ts: -------------------------------------------------------------------------------- 1 | import type {ResponseDefinition} from './client'; 2 | import {print} from './util'; 3 | 4 | const parseChild = (def: string | ResponseDefinition, child) => { 5 | if (typeof def === 'object') { 6 | return [def._self, parseChildren(def, child)]; 7 | } else { 8 | const text = child.children.length === 0 ? '' : child.children[0].text; 9 | const sub = def.substring(1); 10 | 11 | switch (def.charAt(0)) { 12 | case '!': 13 | return [sub, text === '1']; 14 | case '#': 15 | return [sub, text === '' ? null : parseInt(text, 10)]; 16 | case '.': 17 | return [sub, text === '' ? null : parseFloat(text)]; 18 | case '$': { 19 | // Pad with extra zeros if necessary 20 | const i = text.includes('.') ? text.length - text.indexOf('.') - 1 : 0; 21 | const t = text.replace('.', ''); 22 | if (i === 0) { 23 | return [sub, parseInt(`${t}00`, 10)]; 24 | } else if (i === 1) { 25 | return [sub, parseInt(`${t}0`, 10)]; 26 | } 27 | return [sub, parseInt(t, 10)]; 28 | } 29 | case '/': 30 | return [sub, text === '' ? null : new RegExp(text)]; 31 | case '*': 32 | return [sub, text === '' ? null : new Date(text)]; 33 | default: 34 | return [def, text]; 35 | } 36 | } 37 | }; 38 | 39 | const parseChildren = (definition: ResponseDefinition, xml) => { 40 | const data = {}; 41 | 42 | if (!xml.children) { 43 | throw new Error(`XML ${xml.type} "${xml.name}" has no children`); 44 | } 45 | 46 | for (const child of xml.children) { 47 | // Skip text children, these are just newlines or spaces 48 | if (child.type === 'text') { 49 | continue; 50 | } 51 | 52 | if (!definition[child.name]) { 53 | console.debug(`Unknown tag: "${child.name}", parent tag: "${xml.name}"`); 54 | console.debug(print(child)); 55 | } else { 56 | const def = definition[child.name]; 57 | 58 | if (Array.isArray(def)) { 59 | const [key, value] = parseChild(def[0], child); 60 | 61 | if (!data[key]) { 62 | data[key] = []; 63 | } 64 | data[key].push(value); 65 | } else { 66 | const [key, value] = parseChild(def, child); 67 | data[key] = value; 68 | } 69 | } 70 | } 71 | 72 | return data; 73 | }; 74 | 75 | const parse = (definition: ResponseDefinition, xml) => { 76 | // print(xml); 77 | return parseChildren(definition, xml); 78 | }; 79 | 80 | export default parse; 81 | -------------------------------------------------------------------------------- /src/requests/base.ts: -------------------------------------------------------------------------------- 1 | export const descriptions = (tag) => ({ 2 | _self: tag, 3 | bg: 'bg', 4 | da: 'da', 5 | de: 'de', 6 | en: 'en', 7 | fr: 'fr', 8 | it: 'it', 9 | lu: 'lu', 10 | nl: 'nl', 11 | no: 'no', 12 | pl: 'pl', 13 | pt: 'pt', 14 | ro: 'ro', 15 | sv: 'sv', 16 | vi: 'vi' 17 | }); 18 | 19 | export const deliveryMethods = (tag) => ({ 20 | _self: tag, 21 | orderMethods: 'ah', 22 | delivery: { 23 | _self: 'dl', 24 | open: '!op', 25 | orderAhead: '!oh', 26 | mealPrepTime: '#mpt', 27 | eta: { 28 | _self: 'eta', 29 | min: '#min', 30 | max: '#max' 31 | } 32 | }, 33 | pickup: { 34 | _self: 'pu', 35 | open: '!op', 36 | orderAhead: '!oh', 37 | mealPrepTime: '#mpt' 38 | } 39 | }); 40 | 41 | export const deliveryCosts = (tag) => ({ 42 | _self: tag, 43 | minimumAmount: '$ma', 44 | costs: { 45 | _self: 'co', 46 | from: '#fr', 47 | to: '#to', 48 | costs: '$ct' 49 | }, 50 | // Unknown attributes 51 | ddf: 'ddf' 52 | }); 53 | 54 | export const contacts = (tag) => ({ 55 | _self: tag, 56 | firstName: 'fn', 57 | lastName: 'ln', 58 | addresses: [ 59 | { 60 | _self: 'ad', 61 | id: 'id', 62 | street: 'st', 63 | number: 'hn', 64 | postalCode: 'pc', 65 | city: 'tn', 66 | phone: 'nr', 67 | deliveryAreaId: 'bg', 68 | deliveryArea: 'bn', 69 | vietnamCity: 'vc', 70 | vietnamArea: 'va', 71 | vietnamCityId: 'va', 72 | vietnamDistrict: 'vd', 73 | vietnamDistrictId: 'vi', 74 | extra: { 75 | _self: 'ei', 76 | flatNumber: 'flatnumber', 77 | house: 'housename', 78 | entrance: 'entrance', 79 | stock: 'stock', 80 | door: 'door', 81 | accessCode: 'accesscode', 82 | intercom: 'intercom', 83 | floor: 'floor', 84 | residence: 'residencetype', 85 | apartment: 'apartmentname', 86 | building: 'buildingname', 87 | hotel: 'hotelname', 88 | compound: 'compoundname', 89 | room: 'roomnumber', 90 | compoundAddresss: 'addressatcompound', 91 | ward: 'ward', 92 | company: 'companyname' 93 | } 94 | } 95 | ] 96 | }); 97 | -------------------------------------------------------------------------------- /src/requests/getAddresses.ts: -------------------------------------------------------------------------------- 1 | import {contacts} from './base'; 2 | 3 | export default { 4 | parameters: ({email, credentials, countryCode, siteCode}) => [ 5 | 'getaddresslist', 6 | email, 7 | credentials, 8 | countryCode, 9 | siteCode 10 | ], 11 | response: { 12 | contacts: contacts('cs') 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /src/requests/getBanks.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({restaurantId}) => ['getidealmobielbanks', restaurantId], 3 | response: { 4 | banks: { 5 | _self: 'bs', 6 | banks: [ 7 | { 8 | _self: 'bk', 9 | id: 'ii', 10 | name: 'in', 11 | mobileWebsite: 'mw' 12 | } 13 | ] 14 | } 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/requests/getCountries.ts: -------------------------------------------------------------------------------- 1 | import {descriptions} from './base'; 2 | 3 | export default { 4 | parameters: () => ['getcountriesdata'], 5 | response: { 6 | config: { 7 | _self: 'av', 8 | countries: [ 9 | { 10 | _self: 'cd', 11 | id: 'cy', 12 | name: 'nm', 13 | siteUrl: 'su', 14 | pregMatch1: '/p1', 15 | pregMatch2: '/p2', 16 | pregMatch3: '/p3', 17 | message1: 'e1', 18 | message2: 'e2', 19 | twitter: 'tw', 20 | email: 'se', 21 | logoUrl: 'lo', 22 | iconUrl: 'fl', 23 | headerUrl: 'hl', 24 | code: 'ic', 25 | siteCode: 'sc', 26 | pickupEnabled: '!pie', 27 | loyaltyShopEnabled: '!lye', 28 | languages: { 29 | _self: 'ls', 30 | languages: ['la'] 31 | }, 32 | descriptions: descriptions('cn'), 33 | movies: descriptions('mv'), 34 | autoComplete: { 35 | _self: 'ac', 36 | gp: { 37 | _self: 'gp', 38 | id: 'sid', 39 | apiKey: 'ak', 40 | poweredBy: 'pb' 41 | }, 42 | nm: { 43 | _self: 'nm', 44 | id: 'sid', 45 | url: 'ul', 46 | apiKey: 'ak' 47 | }, 48 | preferred: 'as' 49 | }, 50 | enabledRecurringPayments: { 51 | _self: 'erp', 52 | methods: ['pm'] 53 | }, 54 | // Unknown attributes 55 | cre: 'cre', 56 | dcr: 'dcr', 57 | gse: 'gse', 58 | lyn: 'lyn', 59 | lyv: 'lyv', 60 | mor: 'mor', 61 | pse: 'pse', 62 | psw: 'psw', 63 | si: 'si', 64 | taa: 'taa', 65 | tip: 'tip' 66 | } 67 | ], 68 | kitchens: { 69 | _self: 'cs', 70 | kitchens: [ 71 | { 72 | _self: 'ct', 73 | id: 'ci', 74 | descriptions: descriptions('tr'), 75 | imageUrl: 'im', 76 | subKitchens: { 77 | _self: 'sc', 78 | subKitchens: [ 79 | { 80 | _self: 'st', 81 | id: 'si', 82 | descriptions: descriptions('tr') 83 | } 84 | ] 85 | } 86 | } 87 | ] 88 | }, 89 | em: 'em', 90 | api: { 91 | _self: 'api', 92 | rd: 'rd', 93 | rdc: 'rdc' 94 | } 95 | } 96 | } 97 | }; 98 | -------------------------------------------------------------------------------- /src/requests/getDiscounts.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({restaurantId, country, language}) => ['getdiscounts', restaurantId, country, language, 'restid'], 3 | response: { 4 | discounts: { 5 | _self: 'dc', 6 | restaurant: { 7 | _self: 'rc', 8 | id: 'ri', 9 | discounts: [ 10 | { 11 | _self: 'dr', 12 | id: 'di', 13 | name: 'dt', 14 | description: 'dd', 15 | deliveryMode: 'ddm' 16 | } 17 | ] 18 | } 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /src/requests/getGeoLocation.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({latitude, longitude, country}) => ['getdatafromgeolocation', latitude, longitude, country], 3 | response: { 4 | location: { 5 | _self: 'ld', 6 | postalCode: 'pc', 7 | country: 'cy', 8 | city: 'tn', 9 | province: 'pr' 10 | } 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /src/requests/getHistory.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({email, credentials, countryCode, siteCode, page = 1, isLoggedIn = true}) => [ 3 | 'getorderhistory', 4 | email, 5 | credentials, 6 | countryCode, 7 | page, 8 | siteCode, 9 | isLoggedIn ? '0' : '1' 10 | ], 11 | response: { 12 | history: { 13 | _self: 'hi', 14 | orders: [ 15 | { 16 | _self: 'or', 17 | timestamp: 'ot', 18 | id: 'id', 19 | addressId: 'ai', 20 | steet: 'ad', 21 | number: 'hn', 22 | postalCode: 'da', 23 | deliveryAreaId: 'bg', 24 | deliveryArea: 'bn', 25 | city: 'tn', 26 | restaurantId: 'rd', 27 | restaurantName: 'nm', 28 | restaurantLogoUrl: 'lu', 29 | orderNumber: 'on', 30 | deliveryMethod: 'dm', 31 | vietnamCity: 'vc', 32 | vietnamDistrict: 'vd', 33 | vietnamDistrictId: 'va', 34 | latitude: 'lat', 35 | longitude: 'lng' 36 | } 37 | ] 38 | } 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /src/requests/getHistoryDetails.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({email, credentials, countryCode, orderId, siteCode, isLoggedIn = true}) => [ 3 | 'getorderdetails', 4 | email, 5 | credentials, 6 | countryCode, 7 | orderId, 8 | siteCode, 9 | isLoggedIn ? '0' : '1' 10 | ], 11 | response: { 12 | order: { 13 | _self: 'od', 14 | totalPrice: '$tt', 15 | deliveryCosts: '$dc', 16 | paymentMethod: 'pm', 17 | discountReceived: '!ds', 18 | products: [ 19 | { 20 | _self: 'pr', 21 | id: 'id', 22 | name: 'nm', 23 | price: '$pc', 24 | rmk: 'rmk', 25 | options: [ 26 | { 27 | _self: 'sd', 28 | id: 'id', 29 | name: 'nm', 30 | price: '$pc' 31 | } 32 | ] 33 | } 34 | ], 35 | transactionCosts: '$mf', 36 | polygonStatus: 'ply' 37 | } 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /src/requests/getLoyaltyPoints.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({email, credentials, countryCode, siteCode, language}) => [ 3 | 'loyaltypoints', 4 | countryCode, 5 | email, 6 | credentials, 7 | siteCode, 8 | language, 9 | 'takeawayuk-home://' 10 | ], 11 | response: { 12 | loyalty: { 13 | _self: 'ok', 14 | unavailable: '!unavailable', 15 | points: 'pts', 16 | url: 'url', 17 | externalBrowser: '!ext' 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/requests/getMenuCard.ts: -------------------------------------------------------------------------------- 1 | import {restaurant} from './restaurant'; 2 | 3 | export const product = (tag: string, sizes = true) => ({ 4 | _self: tag, 5 | id: 'id', 6 | name: 'nm', 7 | description: 'ds', 8 | photoUrl: 'pu', 9 | deliveryMethod: 'ah', 10 | deliveryPrice: '$pc', 11 | pickupPrice: '$tc', 12 | information: foodInformation('fai'), 13 | excludedFromMinimum: '!xfm', 14 | options: { 15 | _self: 'ss', 16 | options: [ 17 | { 18 | _self: 'sd', 19 | name: 'nm', 20 | type: 'tp', 21 | choices: { 22 | _self: 'cc', 23 | choices: [ 24 | { 25 | _self: 'ch', 26 | id: 'id', 27 | name: 'nm', 28 | deliveryPrice: '$pc', 29 | pickupPrice: '$tc', 30 | excludedFromMinimum: '!xfm', 31 | information: foodInformation('fai') 32 | } 33 | ] 34 | } 35 | } 36 | ] 37 | }, 38 | sizes: sizes 39 | ? { 40 | _self: 'sz', 41 | products: [product('pr', false)] 42 | } 43 | : { 44 | _self: 'sz' 45 | }, 46 | cloudinaryProduct: 'cloudinaryProduct', 47 | // NOTE: this field is not used in the Android app, so no clue what it is 48 | ea: '$ea' 49 | }); 50 | 51 | const foodInformation = (tag: string) => ({ 52 | _self: tag, 53 | allergens: { 54 | _self: 'all', 55 | ids: ['id'] 56 | }, 57 | additives: { 58 | _self: 'add', 59 | ids: ['id'] 60 | }, 61 | nutritionFacts: 'nut', 62 | extra: { 63 | _self: 'xtr', 64 | caffeine: 'caf', 65 | alcoholPerVolume: 'abv', 66 | bottleDeposit: 'dep', 67 | volumePerLitre: 'ltr', 68 | costPerLitreDelivery: 'ltr', 69 | costPerLitrePickup: 'clp', 70 | volumePerKilogram: 'kgm', 71 | costPerGramDelivery: 'cgd', 72 | costPerGramPickup: 'cgp', 73 | costPerLiterDelivery: 'cld' 74 | } 75 | }); 76 | 77 | export const discount = (tag: string) => ({ 78 | _self: tag, 79 | type: 'tp', 80 | name: 'nm', 81 | description: 'ds', 82 | price: '$pr', 83 | amount: '#da', 84 | percentage: 'dp', 85 | productNumber: 'dn', 86 | productGroups: { 87 | _self: 'kg', 88 | items: [ 89 | { 90 | _self: 'ki', 91 | ids: ['id'] 92 | } 93 | ] 94 | }, 95 | repeat: 'en', 96 | calculateSideDishes: '!is', 97 | minimumAmount: 'doo', 98 | deliveryMode: 'ddm', 99 | wd: 'wd', 100 | do: 'do' 101 | }); 102 | 103 | export default { 104 | parameters: ({restaurantId, postalCode, latitude, longitude, clientId = '', isLocationAccurate = '1'}) => [ 105 | 'getrestaurantdata', 106 | restaurantId, 107 | postalCode, 108 | '1', 109 | latitude, 110 | longitude, 111 | clientId, 112 | isLocationAccurate 113 | ], 114 | response: { 115 | restaurant: { 116 | ...restaurant('rd'), 117 | menu: [ 118 | { 119 | _self: 'mc', 120 | categories: { 121 | _self: 'cs', 122 | categories: [ 123 | { 124 | _self: 'ct', 125 | id: 'id', 126 | name: 'nm', 127 | description: 'ds', 128 | imageUrl: 'cti', 129 | ot: { 130 | _self: 'ot' 131 | // TODO 132 | }, 133 | openingHours: { 134 | _self: 'ao', 135 | day: { 136 | _self: 'dr', 137 | number: 'od', 138 | time: { 139 | _self: 'ru', 140 | start: '*st', 141 | end: '*en' 142 | } 143 | } 144 | }, 145 | products: { 146 | _self: 'ps', 147 | products: [product('pr')] 148 | }, 149 | time: { 150 | _self: 'ru', 151 | start: '*st', 152 | end: '*en' 153 | }, 154 | cloudinaryChain: 'cloudinaryChain', 155 | ctoi: 'ctoi' 156 | } 157 | ], 158 | discounts1: { 159 | _self: 'ks', 160 | discounts: [discount('kk')] 161 | }, 162 | discounts2: { 163 | _self: 'ak', 164 | discounts: [discount('kk')] 165 | } 166 | }, 167 | plasticBag: { 168 | _self: 'ap', 169 | products: [product('pr')] 170 | } 171 | } 172 | ], 173 | // TODO: ap 174 | currentTime: '*ct', 175 | weekday: 'wd', 176 | clearEmail: 'ce' 177 | } 178 | } 179 | }; 180 | -------------------------------------------------------------------------------- /src/requests/getRestaurantData.ts: -------------------------------------------------------------------------------- 1 | import {restaurant} from './restaurant'; 2 | 3 | export default { 4 | parameters: ({restaurantId, postalCode, latitude, longitude, clientId, isLocationAccurate = '1'}) => [ 5 | 'getrestaurantdatacheckout', 6 | restaurantId, 7 | postalCode, 8 | '1', 9 | latitude, 10 | longitude, 11 | clientId, 12 | isLocationAccurate 13 | ], 14 | response: { 15 | restaurant: { 16 | ...restaurant('rd'), 17 | 18 | weekday: 'wd', 19 | currentTime: '*ct', 20 | clearEmail: 'ce' 21 | } 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /src/requests/getRestaurants.ts: -------------------------------------------------------------------------------- 1 | import {deliveryCosts, deliveryMethods} from './base'; 2 | 3 | export default { 4 | parameters: ({postalCode, country, latitude, longitude, language, isLocationAccurate = '1'}) => [ 5 | 'getrestaurants', 6 | postalCode, 7 | country, 8 | latitude, 9 | longitude, 10 | language, 11 | '0', 12 | isLocationAccurate 13 | ], 14 | response: { 15 | restaurants: { 16 | _self: 'rs', 17 | location: { 18 | _self: 'cp', 19 | street: 'ps', 20 | city: 'pt', 21 | postalCode: 'ptd', 22 | vietnamDistrict: 'vd', 23 | vietnamCity: 'vc', 24 | vietnamDistrictId: 'vi', 25 | vietnamCityId: 'va' 26 | }, 27 | restaurants: [ 28 | { 29 | _self: 'rt', 30 | id: 'id', 31 | name: 'nm', 32 | tip: '!tip', 33 | new: '!new', 34 | branch: 'bn', 35 | open: '!op', 36 | payment: { 37 | _self: 'pm', 38 | methods: [ 39 | { 40 | _self: 'me', 41 | id: 'mi' 42 | } 43 | ] 44 | }, 45 | estimatedDeliveryTime: 'est', 46 | deliveryMethods: deliveryMethods('dm'), 47 | polygonStatus: 'ply', 48 | kitchens: { 49 | _self: 'cs', 50 | ids: ['ct'] 51 | }, 52 | subKitchens: { 53 | _self: 'sc', 54 | ids: ['si'] 55 | }, 56 | popularDishes: { 57 | _self: 'pd', 58 | ids: ['pz'] 59 | }, 60 | sorting: { 61 | _self: 'sr', 62 | s1: 's1', 63 | s2: 's2', 64 | s3: 's3', 65 | s4: 's4', 66 | s5: 's5', 67 | s6: 's6', 68 | s7: 's7', 69 | s8: 's8', 70 | s9: 's9', 71 | s10: 's10', 72 | s11: 's11', 73 | s12: 's12' 74 | }, 75 | information: 'nt', 76 | grade: '#rv', 77 | address: { 78 | _self: 'ad', 79 | street: 'st', 80 | city: 'ci', 81 | latitude: 'lt', 82 | longitude: 'ln', 83 | vietnamDistrict: 'pp' 84 | }, 85 | ratingCount: '#bd', 86 | logoUrl: 'lo', 87 | cacheKey: 'ck', 88 | deliveryCosts: deliveryCosts('dc'), 89 | hasDiscounts: '!hd', 90 | hasFoodTracker: '!ft', 91 | distance: '.ds', 92 | cloudinaryLogo: 'cloudinaryLogo', 93 | eta: { 94 | _self: 'eta', 95 | min: '#min', 96 | max: '#max' 97 | }, 98 | // Unknown attributes 99 | rvd: 'rvd' 100 | } 101 | ], 102 | weekday: 'wd', 103 | currentTime: '*ct', 104 | // Unknown attributes 105 | unx: 'unx' 106 | } 107 | } 108 | }; 109 | -------------------------------------------------------------------------------- /src/requests/getReviews.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({restaurantId, page = 1}) => ['restaurantreviews', restaurantId, page], 3 | response: { 4 | reviews: { 5 | _self: 'rr', 6 | reviews: [ 7 | { 8 | _self: 'rv', 9 | name: 'nm', 10 | time: 'ti', 11 | description: 'rm', 12 | quality: '#kw', 13 | delivery: 'be', 14 | sunday: '!zo', 15 | orderMethod: 'dm' 16 | } 17 | ] 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/requests/getServerTime.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({country, restaurantId, orderMode}) => ['getcurrenttime', country, restaurantId, orderMode], 3 | response: { 4 | time: { 5 | currentTime: '*ct', 6 | weekday: 'wd', 7 | open: '!rs' 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /src/requests/getURLs.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({country, language}) => ['geturls', country, language], 3 | response: { 4 | urls: { 5 | _self: 'gu', 6 | country: 'cc', 7 | language: 'ln', 8 | urls: { 9 | _self: 'urls', 10 | items: [ 11 | { 12 | _self: 'it', 13 | type: 'typ', 14 | url: 'url' 15 | } 16 | ] 17 | } 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/requests/index.ts: -------------------------------------------------------------------------------- 1 | import getAddresses from './getAddresses'; 2 | import getBanks from './getBanks'; 3 | import getCountries from './getCountries'; 4 | import getDiscounts from './getDiscounts'; 5 | import getGeoLocation from './getGeoLocation'; 6 | import getHistory from './getHistory'; 7 | import getHistoryDetails from './getHistoryDetails'; 8 | import getLoyaltyPoints from './getLoyaltyPoints'; 9 | import getMenuCard from './getMenuCard'; 10 | import getRestaurantData from './getRestaurantData'; 11 | import getRestaurants from './getRestaurants'; 12 | import getReviews from './getReviews'; 13 | import getServerTime from './getServerTime'; 14 | import getURLs from './getURLs'; 15 | import login from './login'; 16 | import order from './order'; 17 | import resetPassword from './resetPassword'; 18 | import {reverse} from './util'; 19 | 20 | const requests = { 21 | getAddresses, 22 | getBanks, 23 | getCountries, 24 | getDiscounts, 25 | getGeoLocation, 26 | getHistory, 27 | getHistoryDetails, 28 | getLoyaltyPoints, 29 | getMenuCard, 30 | getRestaurantData, 31 | getRestaurants, 32 | getReviews, 33 | getServerTime, 34 | getURLs, 35 | login, 36 | order, 37 | resetPassword 38 | }; 39 | 40 | // Reverse all request definition objects for the parser 41 | for (const request of Object.values(requests)) { 42 | request.response = reverse(request.response); 43 | } 44 | 45 | export default requests; 46 | -------------------------------------------------------------------------------- /src/requests/login.ts: -------------------------------------------------------------------------------- 1 | import {contacts} from './base'; 2 | 3 | export default { 4 | parameters: ({email, credentials, countryCode, clientId = '', siteCode, socialType = '', socialToken = ''}) => [ 5 | 'userauth', 6 | email, 7 | credentials, 8 | countryCode, 9 | clientId, 10 | siteCode, 11 | socialType && socialType.length > 0 ? '1' : '0', 12 | socialType, 13 | socialToken 14 | ], 15 | response: { 16 | login: { 17 | _self: 'ua', 18 | id: 'id', 19 | token: 'tk', 20 | firstName: 'fn', 21 | lastName: 'ln', 22 | email: 'em', 23 | oldOrders: 'oo', 24 | ac: 'ac', 25 | social: { 26 | _self: 'sm', 27 | id: 'sid', 28 | username: 'un' 29 | }, 30 | migrated: '!mig', 31 | contacts: contacts('cs') 32 | } 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /src/requests/order.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({ 3 | name, 4 | companyName = '', 5 | street, 6 | countryCode, 7 | postalCode, 8 | city, 9 | vietnamDistrict, 10 | vietnamCity, 11 | phone, 12 | email, 13 | deliveryTime, 14 | paymentPart, 15 | remarks, 16 | newsLetter, 17 | restaurantId, 18 | formattedOrder, 19 | siteCode, 20 | language, 21 | clientId, 22 | paymentMethod, 23 | bankId, 24 | foodTrackerId, 25 | deliveryArea, 26 | extraAddress = '', 27 | username = '', 28 | credentials = '', 29 | addressId = '', 30 | deliveryMethod, 31 | voucherCode = '', 32 | latitude, 33 | longitude, 34 | productRemarks = '', 35 | isLocationAccurate = '1' 36 | }) => [ 37 | paymentMethod === 13 || paymentMethod === '13' ? 'reserveorder' : 'placeorder', 38 | name, 39 | companyName, 40 | street, 41 | '', 42 | countryCode === 239 || countryCode === '239' ? vietnamDistrict : postalCode, 43 | countryCode === 239 || countryCode === '239' ? vietnamCity : city, 44 | phone, 45 | email, 46 | deliveryTime, 47 | paymentPart, 48 | remarks, 49 | newsLetter, 50 | restaurantId, 51 | formattedOrder, 52 | siteCode, 53 | language, 54 | countryCode, 55 | clientId, 56 | paymentMethod, 57 | bankId, 58 | foodTrackerId, 59 | countryCode === 239 || countryCode === '239' ? vietnamDistrict : deliveryArea, 60 | 'com.takeaway.android', 61 | extraAddress, 62 | username, 63 | credentials, 64 | addressId, 65 | deliveryMethod, 66 | '0', 67 | paymentMethod === 13 || paymentMethod === '13' ? voucherCode : '', 68 | latitude, 69 | longitude, 70 | productRemarks, 71 | isLocationAccurate 72 | ], 73 | response: {} 74 | }; 75 | -------------------------------------------------------------------------------- /src/requests/resetPassword.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | parameters: ({email, country, language, siteCode}) => ['resetpassword', email, country, language, siteCode], 3 | response: { 4 | reset: { 5 | _self: 'ok', 6 | status: 'status' 7 | } 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /src/requests/restaurant.ts: -------------------------------------------------------------------------------- 1 | import {deliveryCosts, deliveryMethods} from './base'; 2 | 3 | const time = (tag: string) => ({ 4 | _self: tag, 5 | currentTime: '*ct', 6 | td: { 7 | _self: 'td', 8 | time: { 9 | _self: 'ti', 10 | start: '*st', 11 | end: '*et' 12 | } 13 | }, 14 | tm: { 15 | _self: 'tm', 16 | time: { 17 | _self: 'ti', 18 | start: '*st', 19 | end: '*et' 20 | } 21 | } 22 | }); 23 | 24 | export const restaurant = (tag: string) => ({ 25 | _self: tag, 26 | id: 'ri', 27 | name: 'nm', 28 | branch: 'bn', 29 | open: '!op', 30 | polygonStatus: 'ply', 31 | cacheKey: 'ck', 32 | distance: '.ds', 33 | address: { 34 | _self: 'ad', 35 | street: 'st', 36 | number: 'hn', 37 | postalCode: 'pc', 38 | city: 'tn', 39 | latitude: 'lt', 40 | longitude: 'ln' 41 | }, 42 | telephone: { 43 | _self: 'tel', 44 | number: 'no1' 45 | }, 46 | legal: { 47 | _self: 'lgl', 48 | owner: 'own', 49 | commericalRegister: 'tcr', 50 | chamberOfCommerce: 'crn', 51 | vat: 'vat', 52 | address: { 53 | _self: 'adr', 54 | street: 'st', 55 | number: 'hn', 56 | postalCode: 'pc', 57 | city: 'tn' 58 | } 59 | }, 60 | information: { 61 | _self: 'oo', 62 | logoUrl: 'lu', 63 | information: 'nt', 64 | slogan: 'sl', 65 | grade: '#rv', 66 | ratingCount: '#bd', 67 | hasFoodTracker: '!ft', 68 | cloudinaryLogo: 'cloudinaryLogo', 69 | // Unknown attributes 70 | cim: 'cim', 71 | rvd: 'rvd', 72 | eba: 'eba' 73 | }, 74 | deliveryMethods: deliveryMethods('dm'), 75 | deliveryCosts: deliveryCosts('dc'), 76 | payment: { 77 | _self: 'pm', 78 | methods: [ 79 | { 80 | _self: 'me', 81 | id: 'mi', 82 | fixedCosts: '$mt', 83 | percentageCosts: 'mf' 84 | } 85 | ] 86 | }, 87 | deliveryTime: time('dt'), 88 | pickupTime: time('pt'), 89 | deliveryDistricts: { 90 | _self: 'dd', 91 | areas: [ 92 | { 93 | ...deliveryCosts('da'), 94 | postalCode: { 95 | _self: 'pc', 96 | codes: ['pp'] 97 | } 98 | } 99 | ] 100 | }, 101 | popularDishes: { 102 | _self: 'pd', 103 | ids: ['pz'] 104 | }, 105 | headerImageUrl: 'mh', 106 | slug: 'murl', 107 | cloudinaryHeader: 'cloudinaryHeader', 108 | // Unknown attributes 109 | ac: 'ac', 110 | ddf: 'ddf', 111 | pne: 'pne', 112 | pty: 'pty', 113 | pro: 'pro', 114 | rci: 'rci', 115 | rte: 'rte', 116 | rt: { 117 | _self: 'rt', 118 | cr: 'cr', 119 | prr: 'prr' 120 | }, 121 | sco: 'sco', 122 | smid: 'smid', 123 | tr: 'tr' 124 | }); 125 | -------------------------------------------------------------------------------- /src/requests/util.ts: -------------------------------------------------------------------------------- 1 | import type {ResponseDefinition} from '../client'; 2 | 3 | export const TYPES = '!#.$/*'; 4 | 5 | export const reverseChild = ( 6 | key: string, 7 | value: string | ResponseDefinition 8 | ): [string, string | ResponseDefinition] => { 9 | if (typeof value === 'object') { 10 | // Type hint 11 | value = value as ResponseDefinition; 12 | 13 | const child: ResponseDefinition = reverse(value); 14 | child._self = key; 15 | return [value._self as string, child]; 16 | } else { 17 | value = value as string; 18 | 19 | if (TYPES.includes(value.charAt(0))) { 20 | return [value.substring(1), `${value.charAt(0)}${key}`]; 21 | } else { 22 | return [value, key]; 23 | } 24 | } 25 | }; 26 | 27 | export const reverse = (definition: ResponseDefinition) => { 28 | const output: ResponseDefinition = {}; 29 | for (const [key, value] of Object.entries(definition)) { 30 | if (key.startsWith('_')) { 31 | continue; 32 | } 33 | 34 | if (Array.isArray(value)) { 35 | const [k, v] = reverseChild(key, value[0]); 36 | output[k] = [v] as string[] | ResponseDefinition[]; 37 | } else { 38 | const [k, v] = reverseChild(key, value); 39 | output[k] = v; 40 | } 41 | } 42 | return output; 43 | }; 44 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import crypto from 'crypto'; 2 | 3 | export const md5 = (data: string) => { 4 | return crypto.createHash('md5').update(data).digest('hex'); 5 | }; 6 | 7 | export const print = (xml) => { 8 | if (!xml) { 9 | return; 10 | } 11 | 12 | if (xml.type === 'document') { 13 | for (const child of xml.children) { 14 | print(child); 15 | } 16 | } else if (xml.type === 'element') { 17 | let attributes = Object.entries(xml.attributes) 18 | .map(([key, value]) => `${key}="${value}"`) 19 | .join(' '); 20 | if (attributes !== '') { 21 | attributes = ` ${attributes}`; 22 | } 23 | 24 | if (xml.children.length === 1 && xml.children[0].type === 'text') { 25 | console.log(`<${xml.name}${attributes}>${xml.children[0].text}`); 26 | } else if (xml.children.length > 0) { 27 | console.log(`<${xml.name}${attributes}>`); 28 | console.group(); 29 | for (const child of xml.children) { 30 | print(child); 31 | } 32 | console.groupEnd(); 33 | console.log(``); 34 | } else { 35 | console.log(`<${xml.name}${attributes} />`); 36 | } 37 | } else if (xml.type === 'text') { 38 | if (xml.text.trim().length > 0) { 39 | console.log(xml.text); 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["esnext", "dom"], 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "esModuleInterop": true, 8 | "sourceMap": true, 9 | "outDir": "lib", 10 | "baseUrl": ".", 11 | "paths": { 12 | "*": ["node_modules/*", "src/types/*"] 13 | }, 14 | "emitDecoratorMetadata": true, 15 | "experimentalDecorators": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": false, 18 | "declaration": true 19 | }, 20 | "include": ["src/**/*"] 21 | } 22 | -------------------------------------------------------------------------------- /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 | "@babel/code-frame@^7.22.13": 11 | version "7.22.13" 12 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" 13 | integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== 14 | dependencies: 15 | "@babel/highlight" "^7.22.13" 16 | chalk "^2.4.2" 17 | 18 | "@babel/generator@7.17.7": 19 | version "7.17.7" 20 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad" 21 | integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== 22 | dependencies: 23 | "@babel/types" "^7.17.0" 24 | jsesc "^2.5.1" 25 | source-map "^0.5.0" 26 | 27 | "@babel/generator@^7.23.0": 28 | version "7.23.0" 29 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" 30 | integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== 31 | dependencies: 32 | "@babel/types" "^7.23.0" 33 | "@jridgewell/gen-mapping" "^0.3.2" 34 | "@jridgewell/trace-mapping" "^0.3.17" 35 | jsesc "^2.5.1" 36 | 37 | "@babel/helper-environment-visitor@^7.22.20": 38 | version "7.22.20" 39 | resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" 40 | integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== 41 | 42 | "@babel/helper-function-name@^7.23.0": 43 | version "7.23.0" 44 | resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" 45 | integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== 46 | dependencies: 47 | "@babel/template" "^7.22.15" 48 | "@babel/types" "^7.23.0" 49 | 50 | "@babel/helper-hoist-variables@^7.22.5": 51 | version "7.22.5" 52 | resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" 53 | integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== 54 | dependencies: 55 | "@babel/types" "^7.22.5" 56 | 57 | "@babel/helper-split-export-declaration@^7.22.6": 58 | version "7.22.6" 59 | resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" 60 | integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== 61 | dependencies: 62 | "@babel/types" "^7.22.5" 63 | 64 | "@babel/helper-string-parser@^7.22.5": 65 | version "7.22.5" 66 | resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" 67 | integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== 68 | 69 | "@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.22.20": 70 | version "7.22.20" 71 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" 72 | integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== 73 | 74 | "@babel/highlight@^7.22.13": 75 | version "7.22.20" 76 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" 77 | integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== 78 | dependencies: 79 | "@babel/helper-validator-identifier" "^7.22.20" 80 | chalk "^2.4.2" 81 | js-tokens "^4.0.0" 82 | 83 | "@babel/parser@^7.20.5", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": 84 | version "7.23.0" 85 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" 86 | integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== 87 | 88 | "@babel/template@^7.22.15": 89 | version "7.22.15" 90 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" 91 | integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== 92 | dependencies: 93 | "@babel/code-frame" "^7.22.13" 94 | "@babel/parser" "^7.22.15" 95 | "@babel/types" "^7.22.15" 96 | 97 | "@babel/traverse@7.23.2": 98 | version "7.23.2" 99 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" 100 | integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== 101 | dependencies: 102 | "@babel/code-frame" "^7.22.13" 103 | "@babel/generator" "^7.23.0" 104 | "@babel/helper-environment-visitor" "^7.22.20" 105 | "@babel/helper-function-name" "^7.23.0" 106 | "@babel/helper-hoist-variables" "^7.22.5" 107 | "@babel/helper-split-export-declaration" "^7.22.6" 108 | "@babel/parser" "^7.23.0" 109 | "@babel/types" "^7.23.0" 110 | debug "^4.1.0" 111 | globals "^11.1.0" 112 | 113 | "@babel/types@7.17.0": 114 | version "7.17.0" 115 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" 116 | integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== 117 | dependencies: 118 | "@babel/helper-validator-identifier" "^7.16.7" 119 | to-fast-properties "^2.0.0" 120 | 121 | "@babel/types@^7.17.0", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0": 122 | version "7.23.0" 123 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" 124 | integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== 125 | dependencies: 126 | "@babel/helper-string-parser" "^7.22.5" 127 | "@babel/helper-validator-identifier" "^7.22.20" 128 | to-fast-properties "^2.0.0" 129 | 130 | "@cspotcode/source-map-support@^0.8.0": 131 | version "0.8.1" 132 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 133 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 134 | dependencies: 135 | "@jridgewell/trace-mapping" "0.3.9" 136 | 137 | "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": 138 | version "4.4.0" 139 | resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" 140 | integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== 141 | dependencies: 142 | eslint-visitor-keys "^3.3.0" 143 | 144 | "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": 145 | version "4.10.0" 146 | resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" 147 | integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== 148 | 149 | "@eslint/eslintrc@^2.1.3": 150 | version "2.1.3" 151 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" 152 | integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== 153 | dependencies: 154 | ajv "^6.12.4" 155 | debug "^4.3.2" 156 | espree "^9.6.0" 157 | globals "^13.19.0" 158 | ignore "^5.2.0" 159 | import-fresh "^3.2.1" 160 | js-yaml "^4.1.0" 161 | minimatch "^3.1.2" 162 | strip-json-comments "^3.1.1" 163 | 164 | "@eslint/js@8.53.0": 165 | version "8.53.0" 166 | resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" 167 | integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== 168 | 169 | "@humanwhocodes/config-array@^0.11.13": 170 | version "0.11.13" 171 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" 172 | integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== 173 | dependencies: 174 | "@humanwhocodes/object-schema" "^2.0.1" 175 | debug "^4.1.1" 176 | minimatch "^3.0.5" 177 | 178 | "@humanwhocodes/module-importer@^1.0.1": 179 | version "1.0.1" 180 | resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" 181 | integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== 182 | 183 | "@humanwhocodes/object-schema@^2.0.1": 184 | version "2.0.1" 185 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" 186 | integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== 187 | 188 | "@isaacs/cliui@^8.0.2": 189 | version "8.0.2" 190 | resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" 191 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== 192 | dependencies: 193 | string-width "^5.1.2" 194 | string-width-cjs "npm:string-width@^4.2.0" 195 | strip-ansi "^7.0.1" 196 | strip-ansi-cjs "npm:strip-ansi@^6.0.1" 197 | wrap-ansi "^8.1.0" 198 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" 199 | 200 | "@jridgewell/gen-mapping@^0.3.2": 201 | version "0.3.3" 202 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" 203 | integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== 204 | dependencies: 205 | "@jridgewell/set-array" "^1.0.1" 206 | "@jridgewell/sourcemap-codec" "^1.4.10" 207 | "@jridgewell/trace-mapping" "^0.3.9" 208 | 209 | "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": 210 | version "3.1.1" 211 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" 212 | integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== 213 | 214 | "@jridgewell/set-array@^1.0.1": 215 | version "1.1.2" 216 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" 217 | integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== 218 | 219 | "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": 220 | version "1.4.15" 221 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" 222 | integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== 223 | 224 | "@jridgewell/trace-mapping@0.3.9": 225 | version "0.3.9" 226 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 227 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 228 | dependencies: 229 | "@jridgewell/resolve-uri" "^3.0.3" 230 | "@jridgewell/sourcemap-codec" "^1.4.10" 231 | 232 | "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": 233 | version "0.3.20" 234 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" 235 | integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== 236 | dependencies: 237 | "@jridgewell/resolve-uri" "^3.1.0" 238 | "@jridgewell/sourcemap-codec" "^1.4.14" 239 | 240 | "@nodelib/fs.scandir@2.1.5": 241 | version "2.1.5" 242 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 243 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 244 | dependencies: 245 | "@nodelib/fs.stat" "2.0.5" 246 | run-parallel "^1.1.9" 247 | 248 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 249 | version "2.0.5" 250 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 251 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 252 | 253 | "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": 254 | version "1.2.8" 255 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 256 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 257 | dependencies: 258 | "@nodelib/fs.scandir" "2.1.5" 259 | fastq "^1.6.0" 260 | 261 | "@pkgjs/parseargs@^0.11.0": 262 | version "0.11.0" 263 | resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 264 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== 265 | 266 | "@rgrove/parse-xml@^4.1.0": 267 | version "4.1.0" 268 | resolved "https://registry.yarnpkg.com/@rgrove/parse-xml/-/parse-xml-4.1.0.tgz#ff489b59c4794569fa1b798515eef6826daeeb5e" 269 | integrity sha512-pBiltENdy8SfI0AeR1e5TRpS9/9Gl0eiOEt6ful2jQfzsgvZYWqsKiBWaOCLdocQuk0wS7KOHI37n0C1pnKqTw== 270 | 271 | "@trivago/prettier-plugin-sort-imports@^4.2.1": 272 | version "4.2.1" 273 | resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.2.1.tgz#a4f57df41a46803a75bd8e8ce371b29e78a27eb4" 274 | integrity sha512-iuy2MPVURGdxILTchHr15VAioItuYBejKfcTmQFlxIuqA7jeaT6ngr5aUIG6S6U096d6a6lJCgaOwlRrPLlOPg== 275 | dependencies: 276 | "@babel/generator" "7.17.7" 277 | "@babel/parser" "^7.20.5" 278 | "@babel/traverse" "7.23.2" 279 | "@babel/types" "7.17.0" 280 | javascript-natural-sort "0.7.1" 281 | lodash "^4.17.21" 282 | 283 | "@tsconfig/node10@^1.0.7": 284 | version "1.0.9" 285 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" 286 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== 287 | 288 | "@tsconfig/node12@^1.0.7": 289 | version "1.0.11" 290 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 291 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 292 | 293 | "@tsconfig/node14@^1.0.0": 294 | version "1.0.3" 295 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 296 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 297 | 298 | "@tsconfig/node16@^1.0.2": 299 | version "1.0.4" 300 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" 301 | integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== 302 | 303 | "@types/json-schema@^7.0.12": 304 | version "7.0.15" 305 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" 306 | integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== 307 | 308 | "@types/node@^20.9.0": 309 | version "20.9.0" 310 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298" 311 | integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw== 312 | dependencies: 313 | undici-types "~5.26.4" 314 | 315 | "@types/semver@^7.5.0": 316 | version "7.5.5" 317 | resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.5.tgz#deed5ab7019756c9c90ea86139106b0346223f35" 318 | integrity sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg== 319 | 320 | "@typescript-eslint/eslint-plugin@^6.10.0": 321 | version "6.10.0" 322 | resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz#cfe2bd34e26d2289212946b96ab19dcad64b661a" 323 | integrity sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg== 324 | dependencies: 325 | "@eslint-community/regexpp" "^4.5.1" 326 | "@typescript-eslint/scope-manager" "6.10.0" 327 | "@typescript-eslint/type-utils" "6.10.0" 328 | "@typescript-eslint/utils" "6.10.0" 329 | "@typescript-eslint/visitor-keys" "6.10.0" 330 | debug "^4.3.4" 331 | graphemer "^1.4.0" 332 | ignore "^5.2.4" 333 | natural-compare "^1.4.0" 334 | semver "^7.5.4" 335 | ts-api-utils "^1.0.1" 336 | 337 | "@typescript-eslint/parser@^6.10.0": 338 | version "6.10.0" 339 | resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.10.0.tgz#578af79ae7273193b0b6b61a742a2bc8e02f875a" 340 | integrity sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog== 341 | dependencies: 342 | "@typescript-eslint/scope-manager" "6.10.0" 343 | "@typescript-eslint/types" "6.10.0" 344 | "@typescript-eslint/typescript-estree" "6.10.0" 345 | "@typescript-eslint/visitor-keys" "6.10.0" 346 | debug "^4.3.4" 347 | 348 | "@typescript-eslint/scope-manager@6.10.0": 349 | version "6.10.0" 350 | resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz#b0276118b13d16f72809e3cecc86a72c93708540" 351 | integrity sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg== 352 | dependencies: 353 | "@typescript-eslint/types" "6.10.0" 354 | "@typescript-eslint/visitor-keys" "6.10.0" 355 | 356 | "@typescript-eslint/type-utils@6.10.0": 357 | version "6.10.0" 358 | resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz#1007faede067c78bdbcef2e8abb31437e163e2e1" 359 | integrity sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg== 360 | dependencies: 361 | "@typescript-eslint/typescript-estree" "6.10.0" 362 | "@typescript-eslint/utils" "6.10.0" 363 | debug "^4.3.4" 364 | ts-api-utils "^1.0.1" 365 | 366 | "@typescript-eslint/types@6.10.0": 367 | version "6.10.0" 368 | resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.10.0.tgz#f4f0a84aeb2ac546f21a66c6e0da92420e921367" 369 | integrity sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg== 370 | 371 | "@typescript-eslint/typescript-estree@6.10.0": 372 | version "6.10.0" 373 | resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz#667381eed6f723a1a8ad7590a31f312e31e07697" 374 | integrity sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg== 375 | dependencies: 376 | "@typescript-eslint/types" "6.10.0" 377 | "@typescript-eslint/visitor-keys" "6.10.0" 378 | debug "^4.3.4" 379 | globby "^11.1.0" 380 | is-glob "^4.0.3" 381 | semver "^7.5.4" 382 | ts-api-utils "^1.0.1" 383 | 384 | "@typescript-eslint/utils@6.10.0": 385 | version "6.10.0" 386 | resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.10.0.tgz#4d76062d94413c30e402c9b0df8c14aef8d77336" 387 | integrity sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg== 388 | dependencies: 389 | "@eslint-community/eslint-utils" "^4.4.0" 390 | "@types/json-schema" "^7.0.12" 391 | "@types/semver" "^7.5.0" 392 | "@typescript-eslint/scope-manager" "6.10.0" 393 | "@typescript-eslint/types" "6.10.0" 394 | "@typescript-eslint/typescript-estree" "6.10.0" 395 | semver "^7.5.4" 396 | 397 | "@typescript-eslint/visitor-keys@6.10.0": 398 | version "6.10.0" 399 | resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz#b9eaf855a1ac7e95633ae1073af43d451e8f84e3" 400 | integrity sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg== 401 | dependencies: 402 | "@typescript-eslint/types" "6.10.0" 403 | eslint-visitor-keys "^3.4.1" 404 | 405 | "@ungap/structured-clone@^1.2.0": 406 | version "1.2.0" 407 | resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" 408 | integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== 409 | 410 | acorn-jsx@^5.3.2: 411 | version "5.3.2" 412 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 413 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 414 | 415 | acorn-walk@^8.1.1: 416 | version "8.3.0" 417 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" 418 | integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== 419 | 420 | acorn@^8.4.1, acorn@^8.9.0: 421 | version "8.11.2" 422 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" 423 | integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== 424 | 425 | ajv@^6.12.4: 426 | version "6.12.6" 427 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 428 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 429 | dependencies: 430 | fast-deep-equal "^3.1.1" 431 | fast-json-stable-stringify "^2.0.0" 432 | json-schema-traverse "^0.4.1" 433 | uri-js "^4.2.2" 434 | 435 | ansi-regex@^5.0.1: 436 | version "5.0.1" 437 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 438 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 439 | 440 | ansi-regex@^6.0.1: 441 | version "6.0.1" 442 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 443 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 444 | 445 | ansi-styles@^3.2.1: 446 | version "3.2.1" 447 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 448 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 449 | dependencies: 450 | color-convert "^1.9.0" 451 | 452 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 453 | version "4.3.0" 454 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 455 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 456 | dependencies: 457 | color-convert "^2.0.1" 458 | 459 | ansi-styles@^6.1.0: 460 | version "6.2.1" 461 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" 462 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== 463 | 464 | arg@^4.1.0: 465 | version "4.1.3" 466 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 467 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 468 | 469 | argparse@^2.0.1: 470 | version "2.0.1" 471 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 472 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 473 | 474 | array-union@^2.1.0: 475 | version "2.1.0" 476 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" 477 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 478 | 479 | balanced-match@^1.0.0: 480 | version "1.0.2" 481 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 482 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 483 | 484 | brace-expansion@^1.1.7: 485 | version "1.1.11" 486 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 487 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 488 | dependencies: 489 | balanced-match "^1.0.0" 490 | concat-map "0.0.1" 491 | 492 | brace-expansion@^2.0.1: 493 | version "2.0.1" 494 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 495 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 496 | dependencies: 497 | balanced-match "^1.0.0" 498 | 499 | braces@^3.0.3: 500 | version "3.0.3" 501 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" 502 | integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== 503 | dependencies: 504 | fill-range "^7.1.1" 505 | 506 | callsites@^3.0.0: 507 | version "3.1.0" 508 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 509 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 510 | 511 | chalk@^2.4.2: 512 | version "2.4.2" 513 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 514 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 515 | dependencies: 516 | ansi-styles "^3.2.1" 517 | escape-string-regexp "^1.0.5" 518 | supports-color "^5.3.0" 519 | 520 | chalk@^4.0.0: 521 | version "4.1.2" 522 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 523 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 524 | dependencies: 525 | ansi-styles "^4.1.0" 526 | supports-color "^7.1.0" 527 | 528 | color-convert@^1.9.0: 529 | version "1.9.3" 530 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 531 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 532 | dependencies: 533 | color-name "1.1.3" 534 | 535 | color-convert@^2.0.1: 536 | version "2.0.1" 537 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 538 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 539 | dependencies: 540 | color-name "~1.1.4" 541 | 542 | color-name@1.1.3: 543 | version "1.1.3" 544 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 545 | integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== 546 | 547 | color-name@~1.1.4: 548 | version "1.1.4" 549 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 550 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 551 | 552 | concat-map@0.0.1: 553 | version "0.0.1" 554 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 555 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 556 | 557 | create-require@^1.1.0: 558 | version "1.1.1" 559 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 560 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 561 | 562 | cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: 563 | version "7.0.6" 564 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" 565 | integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== 566 | dependencies: 567 | path-key "^3.1.0" 568 | shebang-command "^2.0.0" 569 | which "^2.0.1" 570 | 571 | debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: 572 | version "4.3.4" 573 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 574 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 575 | dependencies: 576 | ms "2.1.2" 577 | 578 | deep-is@^0.1.3: 579 | version "0.1.4" 580 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" 581 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 582 | 583 | diff@^4.0.1: 584 | version "4.0.2" 585 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 586 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 587 | 588 | dir-glob@^3.0.1: 589 | version "3.0.1" 590 | resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" 591 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 592 | dependencies: 593 | path-type "^4.0.0" 594 | 595 | doctrine@^3.0.0: 596 | version "3.0.0" 597 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 598 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 599 | dependencies: 600 | esutils "^2.0.2" 601 | 602 | dotenv-cli@^7.3.0: 603 | version "7.3.0" 604 | resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-7.3.0.tgz#21e33e7944713001677658d68856063968edfbd2" 605 | integrity sha512-314CA4TyK34YEJ6ntBf80eUY+t1XaFLyem1k9P0sX1gn30qThZ5qZr/ZwE318gEnzyYP9yj9HJk6SqwE0upkfw== 606 | dependencies: 607 | cross-spawn "^7.0.3" 608 | dotenv "^16.3.0" 609 | dotenv-expand "^10.0.0" 610 | minimist "^1.2.6" 611 | 612 | dotenv-expand@^10.0.0: 613 | version "10.0.0" 614 | resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" 615 | integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== 616 | 617 | dotenv@^16.3.0: 618 | version "16.3.1" 619 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" 620 | integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== 621 | 622 | eastasianwidth@^0.2.0: 623 | version "0.2.0" 624 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 625 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 626 | 627 | emoji-regex@^8.0.0: 628 | version "8.0.0" 629 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 630 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 631 | 632 | emoji-regex@^9.2.2: 633 | version "9.2.2" 634 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 635 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 636 | 637 | escape-string-regexp@^1.0.5: 638 | version "1.0.5" 639 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 640 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 641 | 642 | escape-string-regexp@^4.0.0: 643 | version "4.0.0" 644 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 645 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 646 | 647 | eslint-scope@^7.2.2: 648 | version "7.2.2" 649 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" 650 | integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== 651 | dependencies: 652 | esrecurse "^4.3.0" 653 | estraverse "^5.2.0" 654 | 655 | eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: 656 | version "3.4.3" 657 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" 658 | integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== 659 | 660 | eslint@^8.53.0: 661 | version "8.53.0" 662 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" 663 | integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== 664 | dependencies: 665 | "@eslint-community/eslint-utils" "^4.2.0" 666 | "@eslint-community/regexpp" "^4.6.1" 667 | "@eslint/eslintrc" "^2.1.3" 668 | "@eslint/js" "8.53.0" 669 | "@humanwhocodes/config-array" "^0.11.13" 670 | "@humanwhocodes/module-importer" "^1.0.1" 671 | "@nodelib/fs.walk" "^1.2.8" 672 | "@ungap/structured-clone" "^1.2.0" 673 | ajv "^6.12.4" 674 | chalk "^4.0.0" 675 | cross-spawn "^7.0.2" 676 | debug "^4.3.2" 677 | doctrine "^3.0.0" 678 | escape-string-regexp "^4.0.0" 679 | eslint-scope "^7.2.2" 680 | eslint-visitor-keys "^3.4.3" 681 | espree "^9.6.1" 682 | esquery "^1.4.2" 683 | esutils "^2.0.2" 684 | fast-deep-equal "^3.1.3" 685 | file-entry-cache "^6.0.1" 686 | find-up "^5.0.0" 687 | glob-parent "^6.0.2" 688 | globals "^13.19.0" 689 | graphemer "^1.4.0" 690 | ignore "^5.2.0" 691 | imurmurhash "^0.1.4" 692 | is-glob "^4.0.0" 693 | is-path-inside "^3.0.3" 694 | js-yaml "^4.1.0" 695 | json-stable-stringify-without-jsonify "^1.0.1" 696 | levn "^0.4.1" 697 | lodash.merge "^4.6.2" 698 | minimatch "^3.1.2" 699 | natural-compare "^1.4.0" 700 | optionator "^0.9.3" 701 | strip-ansi "^6.0.1" 702 | text-table "^0.2.0" 703 | 704 | espree@^9.6.0, espree@^9.6.1: 705 | version "9.6.1" 706 | resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" 707 | integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== 708 | dependencies: 709 | acorn "^8.9.0" 710 | acorn-jsx "^5.3.2" 711 | eslint-visitor-keys "^3.4.1" 712 | 713 | esquery@^1.4.2: 714 | version "1.5.0" 715 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" 716 | integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== 717 | dependencies: 718 | estraverse "^5.1.0" 719 | 720 | esrecurse@^4.3.0: 721 | version "4.3.0" 722 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 723 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 724 | dependencies: 725 | estraverse "^5.2.0" 726 | 727 | estraverse@^5.1.0, estraverse@^5.2.0: 728 | version "5.3.0" 729 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" 730 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== 731 | 732 | esutils@^2.0.2: 733 | version "2.0.3" 734 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 735 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 736 | 737 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 738 | version "3.1.3" 739 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 740 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 741 | 742 | fast-glob@^3.2.9: 743 | version "3.3.2" 744 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" 745 | integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== 746 | dependencies: 747 | "@nodelib/fs.stat" "^2.0.2" 748 | "@nodelib/fs.walk" "^1.2.3" 749 | glob-parent "^5.1.2" 750 | merge2 "^1.3.0" 751 | micromatch "^4.0.4" 752 | 753 | fast-json-stable-stringify@^2.0.0: 754 | version "2.1.0" 755 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 756 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 757 | 758 | fast-levenshtein@^2.0.6: 759 | version "2.0.6" 760 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 761 | integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== 762 | 763 | fastq@^1.6.0: 764 | version "1.15.0" 765 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" 766 | integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== 767 | dependencies: 768 | reusify "^1.0.4" 769 | 770 | file-entry-cache@^6.0.1: 771 | version "6.0.1" 772 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" 773 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 774 | dependencies: 775 | flat-cache "^3.0.4" 776 | 777 | fill-range@^7.1.1: 778 | version "7.1.1" 779 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" 780 | integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== 781 | dependencies: 782 | to-regex-range "^5.0.1" 783 | 784 | find-up@^5.0.0: 785 | version "5.0.0" 786 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 787 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 788 | dependencies: 789 | locate-path "^6.0.0" 790 | path-exists "^4.0.0" 791 | 792 | flat-cache@^3.0.4: 793 | version "3.1.1" 794 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" 795 | integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== 796 | dependencies: 797 | flatted "^3.2.9" 798 | keyv "^4.5.3" 799 | rimraf "^3.0.2" 800 | 801 | flatted@^3.2.9: 802 | version "3.2.9" 803 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" 804 | integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== 805 | 806 | foreground-child@^3.1.0: 807 | version "3.1.1" 808 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" 809 | integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== 810 | dependencies: 811 | cross-spawn "^7.0.0" 812 | signal-exit "^4.0.1" 813 | 814 | fs.realpath@^1.0.0: 815 | version "1.0.0" 816 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 817 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 818 | 819 | glob-parent@^5.1.2: 820 | version "5.1.2" 821 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 822 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 823 | dependencies: 824 | is-glob "^4.0.1" 825 | 826 | glob-parent@^6.0.2: 827 | version "6.0.2" 828 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" 829 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 830 | dependencies: 831 | is-glob "^4.0.3" 832 | 833 | glob@^10.3.7: 834 | version "10.3.10" 835 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" 836 | integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== 837 | dependencies: 838 | foreground-child "^3.1.0" 839 | jackspeak "^2.3.5" 840 | minimatch "^9.0.1" 841 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 842 | path-scurry "^1.10.1" 843 | 844 | glob@^7.1.3: 845 | version "7.2.3" 846 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 847 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 848 | dependencies: 849 | fs.realpath "^1.0.0" 850 | inflight "^1.0.4" 851 | inherits "2" 852 | minimatch "^3.1.1" 853 | once "^1.3.0" 854 | path-is-absolute "^1.0.0" 855 | 856 | globals@^11.1.0: 857 | version "11.12.0" 858 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 859 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 860 | 861 | globals@^13.19.0: 862 | version "13.23.0" 863 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" 864 | integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== 865 | dependencies: 866 | type-fest "^0.20.2" 867 | 868 | globby@^11.1.0: 869 | version "11.1.0" 870 | resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" 871 | integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== 872 | dependencies: 873 | array-union "^2.1.0" 874 | dir-glob "^3.0.1" 875 | fast-glob "^3.2.9" 876 | ignore "^5.2.0" 877 | merge2 "^1.4.1" 878 | slash "^3.0.0" 879 | 880 | graphemer@^1.4.0: 881 | version "1.4.0" 882 | resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" 883 | integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== 884 | 885 | has-flag@^3.0.0: 886 | version "3.0.0" 887 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 888 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 889 | 890 | has-flag@^4.0.0: 891 | version "4.0.0" 892 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 893 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 894 | 895 | ignore@^5.2.0, ignore@^5.2.4: 896 | version "5.2.4" 897 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" 898 | integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== 899 | 900 | import-fresh@^3.2.1: 901 | version "3.3.0" 902 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 903 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 904 | dependencies: 905 | parent-module "^1.0.0" 906 | resolve-from "^4.0.0" 907 | 908 | imurmurhash@^0.1.4: 909 | version "0.1.4" 910 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 911 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 912 | 913 | inflight@^1.0.4: 914 | version "1.0.6" 915 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 916 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 917 | dependencies: 918 | once "^1.3.0" 919 | wrappy "1" 920 | 921 | inherits@2: 922 | version "2.0.4" 923 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 924 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 925 | 926 | is-extglob@^2.1.1: 927 | version "2.1.1" 928 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 929 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 930 | 931 | is-fullwidth-code-point@^3.0.0: 932 | version "3.0.0" 933 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 934 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 935 | 936 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: 937 | version "4.0.3" 938 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 939 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 940 | dependencies: 941 | is-extglob "^2.1.1" 942 | 943 | is-number@^7.0.0: 944 | version "7.0.0" 945 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 946 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 947 | 948 | is-path-inside@^3.0.3: 949 | version "3.0.3" 950 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" 951 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== 952 | 953 | isexe@^2.0.0: 954 | version "2.0.0" 955 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 956 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 957 | 958 | jackspeak@^2.3.5: 959 | version "2.3.6" 960 | resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" 961 | integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== 962 | dependencies: 963 | "@isaacs/cliui" "^8.0.2" 964 | optionalDependencies: 965 | "@pkgjs/parseargs" "^0.11.0" 966 | 967 | javascript-natural-sort@0.7.1: 968 | version "0.7.1" 969 | resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" 970 | integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw== 971 | 972 | js-tokens@^4.0.0: 973 | version "4.0.0" 974 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 975 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 976 | 977 | js-yaml@^4.1.0: 978 | version "4.1.0" 979 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 980 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 981 | dependencies: 982 | argparse "^2.0.1" 983 | 984 | jsesc@^2.5.1: 985 | version "2.5.2" 986 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" 987 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== 988 | 989 | json-buffer@3.0.1: 990 | version "3.0.1" 991 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" 992 | integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== 993 | 994 | json-schema-traverse@^0.4.1: 995 | version "0.4.1" 996 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 997 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 998 | 999 | json-stable-stringify-without-jsonify@^1.0.1: 1000 | version "1.0.1" 1001 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 1002 | integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== 1003 | 1004 | keyv@^4.5.3: 1005 | version "4.5.4" 1006 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" 1007 | integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== 1008 | dependencies: 1009 | json-buffer "3.0.1" 1010 | 1011 | levn@^0.4.1: 1012 | version "0.4.1" 1013 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 1014 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 1015 | dependencies: 1016 | prelude-ls "^1.2.1" 1017 | type-check "~0.4.0" 1018 | 1019 | locate-path@^6.0.0: 1020 | version "6.0.0" 1021 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 1022 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 1023 | dependencies: 1024 | p-locate "^5.0.0" 1025 | 1026 | lodash.merge@^4.6.2: 1027 | version "4.6.2" 1028 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 1029 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 1030 | 1031 | lodash@^4.17.21: 1032 | version "4.17.21" 1033 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 1034 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 1035 | 1036 | lru-cache@^6.0.0: 1037 | version "6.0.0" 1038 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 1039 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1040 | dependencies: 1041 | yallist "^4.0.0" 1042 | 1043 | "lru-cache@^9.1.1 || ^10.0.0": 1044 | version "10.0.1" 1045 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" 1046 | integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== 1047 | 1048 | make-error@^1.1.1: 1049 | version "1.3.6" 1050 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 1051 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 1052 | 1053 | merge2@^1.3.0, merge2@^1.4.1: 1054 | version "1.4.1" 1055 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 1056 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 1057 | 1058 | micromatch@^4.0.4: 1059 | version "4.0.8" 1060 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" 1061 | integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== 1062 | dependencies: 1063 | braces "^3.0.3" 1064 | picomatch "^2.3.1" 1065 | 1066 | minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: 1067 | version "3.1.2" 1068 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1069 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1070 | dependencies: 1071 | brace-expansion "^1.1.7" 1072 | 1073 | minimatch@^9.0.1: 1074 | version "9.0.3" 1075 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" 1076 | integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== 1077 | dependencies: 1078 | brace-expansion "^2.0.1" 1079 | 1080 | minimist@^1.2.6: 1081 | version "1.2.8" 1082 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" 1083 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== 1084 | 1085 | "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": 1086 | version "7.0.4" 1087 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" 1088 | integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== 1089 | 1090 | ms@2.1.2: 1091 | version "2.1.2" 1092 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1093 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1094 | 1095 | natural-compare@^1.4.0: 1096 | version "1.4.0" 1097 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 1098 | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== 1099 | 1100 | once@^1.3.0: 1101 | version "1.4.0" 1102 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1103 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 1104 | dependencies: 1105 | wrappy "1" 1106 | 1107 | optionator@^0.9.3: 1108 | version "0.9.3" 1109 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" 1110 | integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== 1111 | dependencies: 1112 | "@aashutoshrathi/word-wrap" "^1.2.3" 1113 | deep-is "^0.1.3" 1114 | fast-levenshtein "^2.0.6" 1115 | levn "^0.4.1" 1116 | prelude-ls "^1.2.1" 1117 | type-check "^0.4.0" 1118 | 1119 | p-limit@^3.0.2: 1120 | version "3.1.0" 1121 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 1122 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 1123 | dependencies: 1124 | yocto-queue "^0.1.0" 1125 | 1126 | p-locate@^5.0.0: 1127 | version "5.0.0" 1128 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 1129 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 1130 | dependencies: 1131 | p-limit "^3.0.2" 1132 | 1133 | parent-module@^1.0.0: 1134 | version "1.0.1" 1135 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 1136 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 1137 | dependencies: 1138 | callsites "^3.0.0" 1139 | 1140 | path-exists@^4.0.0: 1141 | version "4.0.0" 1142 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 1143 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1144 | 1145 | path-is-absolute@^1.0.0: 1146 | version "1.0.1" 1147 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1148 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1149 | 1150 | path-key@^3.1.0: 1151 | version "3.1.1" 1152 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1153 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1154 | 1155 | path-scurry@^1.10.1: 1156 | version "1.10.1" 1157 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" 1158 | integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== 1159 | dependencies: 1160 | lru-cache "^9.1.1 || ^10.0.0" 1161 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 1162 | 1163 | path-type@^4.0.0: 1164 | version "4.0.0" 1165 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 1166 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 1167 | 1168 | picomatch@^2.3.1: 1169 | version "2.3.1" 1170 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1171 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1172 | 1173 | prelude-ls@^1.2.1: 1174 | version "1.2.1" 1175 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 1176 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 1177 | 1178 | prettier@^3.0.3: 1179 | version "3.0.3" 1180 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" 1181 | integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== 1182 | 1183 | punycode@^2.1.0: 1184 | version "2.3.1" 1185 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" 1186 | integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== 1187 | 1188 | queue-microtask@^1.2.2: 1189 | version "1.2.3" 1190 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 1191 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 1192 | 1193 | resolve-from@^4.0.0: 1194 | version "4.0.0" 1195 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 1196 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1197 | 1198 | reusify@^1.0.4: 1199 | version "1.0.4" 1200 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 1201 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 1202 | 1203 | rimraf@^3.0.2: 1204 | version "3.0.2" 1205 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1206 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1207 | dependencies: 1208 | glob "^7.1.3" 1209 | 1210 | rimraf@^5.0.5: 1211 | version "5.0.5" 1212 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf" 1213 | integrity sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A== 1214 | dependencies: 1215 | glob "^10.3.7" 1216 | 1217 | run-parallel@^1.1.9: 1218 | version "1.2.0" 1219 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 1220 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1221 | dependencies: 1222 | queue-microtask "^1.2.2" 1223 | 1224 | semver@^7.5.4: 1225 | version "7.5.4" 1226 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" 1227 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== 1228 | dependencies: 1229 | lru-cache "^6.0.0" 1230 | 1231 | shebang-command@^2.0.0: 1232 | version "2.0.0" 1233 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1234 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1235 | dependencies: 1236 | shebang-regex "^3.0.0" 1237 | 1238 | shebang-regex@^3.0.0: 1239 | version "3.0.0" 1240 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1241 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1242 | 1243 | signal-exit@^4.0.1: 1244 | version "4.1.0" 1245 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" 1246 | integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== 1247 | 1248 | slash@^3.0.0: 1249 | version "3.0.0" 1250 | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" 1251 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 1252 | 1253 | source-map@^0.5.0: 1254 | version "0.5.7" 1255 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 1256 | integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== 1257 | 1258 | "string-width-cjs@npm:string-width@^4.2.0": 1259 | version "4.2.3" 1260 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1261 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1262 | dependencies: 1263 | emoji-regex "^8.0.0" 1264 | is-fullwidth-code-point "^3.0.0" 1265 | strip-ansi "^6.0.1" 1266 | 1267 | string-width@^4.1.0: 1268 | version "4.2.3" 1269 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1270 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1271 | dependencies: 1272 | emoji-regex "^8.0.0" 1273 | is-fullwidth-code-point "^3.0.0" 1274 | strip-ansi "^6.0.1" 1275 | 1276 | string-width@^5.0.1, string-width@^5.1.2: 1277 | version "5.1.2" 1278 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 1279 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 1280 | dependencies: 1281 | eastasianwidth "^0.2.0" 1282 | emoji-regex "^9.2.2" 1283 | strip-ansi "^7.0.1" 1284 | 1285 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1": 1286 | version "6.0.1" 1287 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1288 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1289 | dependencies: 1290 | ansi-regex "^5.0.1" 1291 | 1292 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1293 | version "6.0.1" 1294 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1295 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1296 | dependencies: 1297 | ansi-regex "^5.0.1" 1298 | 1299 | strip-ansi@^7.0.1: 1300 | version "7.1.0" 1301 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" 1302 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== 1303 | dependencies: 1304 | ansi-regex "^6.0.1" 1305 | 1306 | strip-json-comments@^3.1.1: 1307 | version "3.1.1" 1308 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1309 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1310 | 1311 | supports-color@^5.3.0: 1312 | version "5.5.0" 1313 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1314 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1315 | dependencies: 1316 | has-flag "^3.0.0" 1317 | 1318 | supports-color@^7.1.0: 1319 | version "7.2.0" 1320 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1321 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1322 | dependencies: 1323 | has-flag "^4.0.0" 1324 | 1325 | text-table@^0.2.0: 1326 | version "0.2.0" 1327 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1328 | integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== 1329 | 1330 | to-fast-properties@^2.0.0: 1331 | version "2.0.0" 1332 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 1333 | integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== 1334 | 1335 | to-regex-range@^5.0.1: 1336 | version "5.0.1" 1337 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1338 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1339 | dependencies: 1340 | is-number "^7.0.0" 1341 | 1342 | ts-api-utils@^1.0.1: 1343 | version "1.0.3" 1344 | resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" 1345 | integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== 1346 | 1347 | ts-node@^10.9.1: 1348 | version "10.9.1" 1349 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" 1350 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== 1351 | dependencies: 1352 | "@cspotcode/source-map-support" "^0.8.0" 1353 | "@tsconfig/node10" "^1.0.7" 1354 | "@tsconfig/node12" "^1.0.7" 1355 | "@tsconfig/node14" "^1.0.0" 1356 | "@tsconfig/node16" "^1.0.2" 1357 | acorn "^8.4.1" 1358 | acorn-walk "^8.1.1" 1359 | arg "^4.1.0" 1360 | create-require "^1.1.0" 1361 | diff "^4.0.1" 1362 | make-error "^1.1.1" 1363 | v8-compile-cache-lib "^3.0.1" 1364 | yn "3.1.1" 1365 | 1366 | type-check@^0.4.0, type-check@~0.4.0: 1367 | version "0.4.0" 1368 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 1369 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1370 | dependencies: 1371 | prelude-ls "^1.2.1" 1372 | 1373 | type-fest@^0.20.2: 1374 | version "0.20.2" 1375 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 1376 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1377 | 1378 | typescript@^5.2.2: 1379 | version "5.2.2" 1380 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" 1381 | integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== 1382 | 1383 | undici-types@~5.26.4: 1384 | version "5.26.5" 1385 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" 1386 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== 1387 | 1388 | uri-js@^4.2.2: 1389 | version "4.4.1" 1390 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1391 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1392 | dependencies: 1393 | punycode "^2.1.0" 1394 | 1395 | v8-compile-cache-lib@^3.0.1: 1396 | version "3.0.1" 1397 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 1398 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 1399 | 1400 | which@^2.0.1: 1401 | version "2.0.2" 1402 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1403 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1404 | dependencies: 1405 | isexe "^2.0.0" 1406 | 1407 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": 1408 | version "7.0.0" 1409 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1410 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1411 | dependencies: 1412 | ansi-styles "^4.0.0" 1413 | string-width "^4.1.0" 1414 | strip-ansi "^6.0.0" 1415 | 1416 | wrap-ansi@^8.1.0: 1417 | version "8.1.0" 1418 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" 1419 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== 1420 | dependencies: 1421 | ansi-styles "^6.1.0" 1422 | string-width "^5.0.1" 1423 | strip-ansi "^7.0.1" 1424 | 1425 | wrappy@1: 1426 | version "1.0.2" 1427 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1428 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1429 | 1430 | yallist@^4.0.0: 1431 | version "4.0.0" 1432 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1433 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1434 | 1435 | yn@3.1.1: 1436 | version "3.1.1" 1437 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 1438 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 1439 | 1440 | yocto-queue@^0.1.0: 1441 | version "0.1.0" 1442 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1443 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1444 | --------------------------------------------------------------------------------