├── .gitignore ├── LICENSE ├── README.md ├── knexfile.js ├── migrations ├── 20220524_152512_enable_uuid_ossp_ext.js ├── 20220524_153400_create_events_table.js ├── 20220524_221800_add_events_table_indexes.js ├── 20220809_190400_add_replaceable_events_unique_index.js ├── 20220825_204900_add_delegator_to_events_table.js └── 20220827_212200_add_is_deleted_to_events_table.js ├── package.json ├── seeds ├── 0000-events.js └── events.json ├── src ├── @types │ ├── base.ts │ └── event.ts ├── constants │ └── base.ts ├── database │ ├── client.ts │ └── insert.ts ├── index.ts ├── nostr │ ├── event.js │ ├── filter.js │ ├── pool.js │ └── relay.js └── utils │ ├── sleep.ts │ └── transform.ts ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .env 3 | dist 4 | node_modules 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ndxstr - Nostr indexing node 2 | 3 | Bootstrapping Nostr's layer2 with an indexing node. 4 | 5 | **ndxstr** nodes are servers that pull events from multiple known relays, storing them forever-ish and making available to clients via API. 6 | 7 | ## Why 8 | 9 | Modern applications may want: 10 | 11 | - More advanced querying than currently supported by Nostr relays 12 | - Receiving messages in a batch via API, not one at a time over a websocket 13 | - Fewer expensive cryptographic operations done client-side (e.g. trusting an indexer to validate events) 14 | - To retrieve large amounts of messages quickly+reliably via one API without caring about uptime/featuresets of multiple relays 15 | 16 | ## Stack 17 | 18 | - NodeJS 19 | - TypeScript 20 | - Postgres 21 | - REST API 22 | 23 | ## Risks 24 | 25 | - Centralization - Need to avoid Infura-ization 26 | 27 | ## Related 28 | 29 | - [nostr-ts-relay](https://github.com/Cameri/nostr-ts-relay) - We reuse a lot of this code 30 | - [nostr](https://github.com/nostr-protocol/nostr) - Main nostr repo 31 | -------------------------------------------------------------------------------- /knexfile.js: -------------------------------------------------------------------------------- 1 | const dotenv = require('dotenv') 2 | 3 | dotenv.config() 4 | 5 | module.exports = { 6 | client: 'pg', 7 | connection: { 8 | host: process.env.DB_HOST ?? 'localhost', 9 | port: process.env.DB_PORT ?? 5432, 10 | user: process.env.DB_USER ?? 'postgres', 11 | password: process.env.DB_PASSWORD ?? 'postgres', 12 | database: process.env.DB_NAME ?? 'ndxstr', 13 | ssl: { 14 | rejectUnauthorized: true, 15 | ca: process.env.DB_SSL_CERT, 16 | }, 17 | }, 18 | pool: { min: 4, max: 16 }, 19 | seeds: { 20 | directory: './seeds', 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /migrations/20220524_152512_enable_uuid_ossp_ext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Enables uuid-ossp extension for uuid_generate_v4() support 3 | */ 4 | 5 | exports.up = function (knex) { 6 | return knex.raw( 7 | 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA public version "1.1";', 8 | ) 9 | } 10 | 11 | exports.down = function (knex) { 12 | return knex.raw('DROP EXTENSION IF EXISTS "uuid-ossp";') 13 | } 14 | -------------------------------------------------------------------------------- /migrations/20220524_153400_create_events_table.js: -------------------------------------------------------------------------------- 1 | exports.up = function (knex) { 2 | return knex.schema.createTable('events', (table) => { 3 | table.uuid('id').primary().defaultTo(knex.raw('uuid_generate_v4()')) 4 | table.binary('event_id').unique().notNullable().index() 5 | table.binary('event_pubkey').notNullable().index() 6 | table.integer('event_kind').unsigned().notNullable().index() 7 | table.integer('event_created_at').unsigned().notNullable().index() 8 | table.text('event_content').notNullable() 9 | table.jsonb('event_tags') 10 | table.binary('event_signature').notNullable() 11 | table.timestamp('first_seen', { useTz: false }).defaultTo(knex.fn.now()) 12 | }) 13 | } 14 | 15 | exports.down = function (knex) { 16 | return knex.schema.dropTable('events') 17 | } 18 | -------------------------------------------------------------------------------- /migrations/20220524_221800_add_events_table_indexes.js: -------------------------------------------------------------------------------- 1 | exports.up = function (knex) { 2 | return knex.raw( 3 | 'CREATE INDEX event_tags_idx ON events USING GIN ( event_tags );', 4 | ) 5 | } 6 | 7 | exports.down = function (knex) { 8 | return knex.raw('DROP INDEX IF EXISTS event_tags_idx') 9 | } 10 | -------------------------------------------------------------------------------- /migrations/20220809_190400_add_replaceable_events_unique_index.js: -------------------------------------------------------------------------------- 1 | exports.up = function (knex) { 2 | // NIP-16: Replaceable Events 3 | return knex.raw( 4 | 'CREATE UNIQUE INDEX replaceable_events_idx ON events ( event_pubkey, event_kind ) WHERE event_kind = 0 OR event_kind = 3 OR event_kind >= 10000 AND event_kind < 20000;', 5 | ) 6 | } 7 | 8 | exports.down = function (knex) { 9 | return knex.raw('DROP INDEX IF EXISTS replaceable_events_idx') 10 | } 11 | -------------------------------------------------------------------------------- /migrations/20220825_204900_add_delegator_to_events_table.js: -------------------------------------------------------------------------------- 1 | exports.up = function (knex) { 2 | // NIP-26: Delegated Event Signing 3 | return knex.schema.alterTable('events', function (table) { 4 | table.binary('event_delegator').nullable().index() 5 | }) 6 | } 7 | 8 | exports.down = function (knex) { 9 | return knex.schema.alterTable('events', function (table) { 10 | table.dropColumn('event_delegator') 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /migrations/20220827_212200_add_is_deleted_to_events_table.js: -------------------------------------------------------------------------------- 1 | exports.up = function (knex) { 2 | return knex.schema.alterTable('events', function (table) { 3 | table.timestamp('deleted_at', { useTz: false }).nullable() 4 | }) 5 | } 6 | 7 | exports.down = function (knex) { 8 | return knex.schema.alterTable('events', function (table) { 9 | table.dropColumn('deleted_at') 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ndxstr", 3 | "version": "1.0.0", 4 | "description": "Nostr indexing node", 5 | "main": "src/index.ts", 6 | "repository": "git@github.com:ArcadeCity/ndxstr.git", 7 | "author": "Christopher David ", 8 | "license": "CC0-1.0", 9 | "private": true, 10 | "scripts": { 11 | "build": "npx tsc", 12 | "start": "node dist/index.js", 13 | "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"", 14 | "db:migrate": "knex migrate:latest", 15 | "db:migrate:rollback": "knex migrate:rollback", 16 | "db:seed": "knex seed:run" 17 | }, 18 | "dependencies": { 19 | "@noble/secp256k1": "1.6.3", 20 | "create-hash": "1.2.0", 21 | "dotenv": "16.0.2", 22 | "express": "4.18.1", 23 | "knex": "2.3.0", 24 | "pg": "8.8.0", 25 | "pg-query-stream": "4.2.4", 26 | "ramda": "0.28.0", 27 | "websocket-polyfill": "0.0.3" 28 | }, 29 | "devDependencies": { 30 | "@types/express": "4.17.13", 31 | "@types/node": "18.7.14", 32 | "@types/ramda": "0.28.15", 33 | "concurrently": "7.3.0", 34 | "nodemon": "2.0.19", 35 | "typescript": "4.8.2", 36 | "uuid": "8.3.2" 37 | }, 38 | "prettier": { 39 | "arrowParens": "always", 40 | "bracketSameLine": true, 41 | "bracketSpacing": true, 42 | "embeddedLanguageFormatting": "auto", 43 | "htmlWhitespaceSensitivity": "css", 44 | "insertPragma": false, 45 | "jsxBracketSameLine": false, 46 | "jsxSingleQuote": true, 47 | "printWidth": 100, 48 | "proseWrap": "preserve", 49 | "quoteProps": "as-needed", 50 | "requirePragma": false, 51 | "semi": false, 52 | "singleQuote": true, 53 | "tabWidth": 2, 54 | "trailingComma": "es5", 55 | "useTabs": false, 56 | "vueIndentScriptAndStyle": false 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /seeds/0000-events.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | 3 | const NAMESPACE = 'c646b451-db73-47fb-9a70-ea24ce8a225a' 4 | exports.seed = async function (knex) { 5 | await knex('events').del() 6 | 7 | const { v5: uuidv5 } = require('uuid') 8 | 9 | const eventRows = require('./events.json').reduce((result, event) => { 10 | result.push({ 11 | id: uuidv5(event.id, NAMESPACE), 12 | event_id: Buffer.from(event.id, 'hex'), 13 | event_pubkey: Buffer.from(event.pubkey, 'hex'), 14 | event_kind: event.kind, 15 | event_created_at: event.created_at, 16 | event_content: event.content, 17 | event_tags: JSON.stringify(event.tags), 18 | event_signature: Buffer.from(event.sig, 'hex'), 19 | }) 20 | 21 | return result 22 | }, []) 23 | 24 | await knex.batchInsert('events', eventRows, 10) 25 | } 26 | -------------------------------------------------------------------------------- /src/@types/base.ts: -------------------------------------------------------------------------------- 1 | import { Knex } from 'knex' 2 | 3 | export type EventId = string 4 | export type Pubkey = string 5 | export type TagName = string 6 | export type Signature = string 7 | export type Tag = TagBase & string[] 8 | 9 | export interface TagBase { 10 | 0: TagName 11 | [index: number]: string 12 | } 13 | 14 | type Enumerate = Acc['length'] extends N 15 | ? Acc[number] 16 | : Enumerate 17 | 18 | export type Range = Exclude, Enumerate> 19 | 20 | export type Factory = (input: TInput) => TOutput 21 | 22 | export type DatabaseClient = Knex 23 | -------------------------------------------------------------------------------- /src/@types/event.ts: -------------------------------------------------------------------------------- 1 | import { EventDelegatorMetadataKey, EventKinds } from '../constants/base' 2 | import { EventId, Pubkey, Tag } from './base' 3 | 4 | export interface Event { 5 | id: EventId 6 | pubkey: Pubkey 7 | created_at: number 8 | kind: EventKinds 9 | tags: Tag[] 10 | sig: string 11 | content: string 12 | [EventDelegatorMetadataKey]?: Pubkey 13 | } 14 | 15 | export interface DBEvent { 16 | id: string 17 | event_id: Buffer 18 | event_pubkey: Buffer 19 | event_kind: number 20 | event_created_at: number 21 | event_content: string 22 | event_tags: Tag[] 23 | event_signature: Buffer 24 | event_delegator?: Buffer | null 25 | first_seen: Date 26 | deleted_at: Date 27 | } 28 | 29 | export interface CanonicalEvent { 30 | 0: 0 31 | 1: string 32 | 2: number 33 | 3: number 34 | 4: Tag[] 35 | 5: string 36 | } 37 | -------------------------------------------------------------------------------- /src/constants/base.ts: -------------------------------------------------------------------------------- 1 | export enum EventKinds { 2 | SET_METADATA = 0, 3 | TEXT_NODE = 1, 4 | RECOMMEND_SERVER = 2, 5 | CONTACT_LIST = 3, 6 | ENCRYPTED_DIRECT_MESSAGE = 4, 7 | DELETE = 5, 8 | REACTION = 7, 9 | } 10 | 11 | export enum EventTags { 12 | Event = 'e', 13 | Pubkey = 'p', 14 | // Multicast = 'm', 15 | Delegation = 'delegation', 16 | } 17 | 18 | export const EventDelegatorMetadataKey = Symbol('Delegator') 19 | -------------------------------------------------------------------------------- /src/database/client.ts: -------------------------------------------------------------------------------- 1 | import pg from 'pg' 2 | import 'pg-query-stream' 3 | import knex, { Knex } from 'knex' 4 | 5 | const dotenv = require('dotenv') 6 | 7 | dotenv.config() 8 | 9 | if (process.env.DB_SSL !== 'false') { 10 | pg.defaults.ssl = true 11 | } 12 | 13 | const createDbConfig = (): Knex.Config => ({ 14 | client: 'pg', 15 | connection: { 16 | host: process.env.DB_HOST, 17 | port: Number(process.env.DB_PORT), 18 | user: process.env.DB_USER, 19 | password: process.env.DB_PASSWORD, 20 | database: process.env.DB_NAME, 21 | ssl: { 22 | rejectUnauthorized: true, 23 | ca: process.env.DB_SSL_CERT, 24 | }, 25 | }, 26 | pool: { 27 | min: 2, 28 | max: 3, 29 | idleTimeoutMillis: 10000, 30 | }, 31 | acquireConnectionTimeout: 2000, 32 | }) 33 | 34 | let client: Knex 35 | 36 | export const getDbClient = () => { 37 | if (!client) { 38 | client = knex(createDbConfig()) 39 | } 40 | 41 | return client 42 | } 43 | -------------------------------------------------------------------------------- /src/database/insert.ts: -------------------------------------------------------------------------------- 1 | import { always, applySpec, ifElse, is, pipe, prop, propSatisfies } from 'ramda' 2 | import { EventDelegatorMetadataKey } from '../constants/base' 3 | import { toBuffer, toJSON } from '../utils/transform' 4 | import { Event } from '../@types/event' 5 | import { getDbClient } from './client' 6 | 7 | const dbClient = getDbClient() 8 | 9 | export const insert = (event: Event) => { 10 | const row = applySpec({ 11 | event_id: pipe(prop('id'), toBuffer), 12 | event_pubkey: pipe(prop('pubkey'), toBuffer), 13 | event_created_at: prop('created_at'), 14 | event_kind: prop('kind'), 15 | event_tags: pipe(prop('tags'), toJSON), 16 | event_content: prop('content'), 17 | event_signature: pipe(prop('sig'), toBuffer), 18 | event_delegator: ifElse( 19 | propSatisfies(is(String), EventDelegatorMetadataKey), 20 | pipe(prop(EventDelegatorMetadataKey as any), toBuffer), 21 | always(null) 22 | ), 23 | })(event) 24 | 25 | return dbClient('events').insert(row).onConflict().ignore() 26 | } 27 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { getDbClient } from './database/client.js' 2 | import { relayPool } from './nostr/pool.js' 3 | import { Event } from './@types/event' 4 | import { insert } from './database/insert' 5 | import { prop } from 'ramda' 6 | import { sleep } from './utils/sleep' 7 | 8 | const express = require('express') 9 | const dotenv = require('dotenv') 10 | 11 | dotenv.config() 12 | 13 | const app = express() 14 | const port = process.env.PORT || 8000 15 | 16 | const dbClient = getDbClient() 17 | 18 | app.get('/', (req, res) => { 19 | res.send('ndxstr') 20 | }) 21 | 22 | app.get('/chat', (req, res) => { 23 | dbClient('events') 24 | .select('*') 25 | .whereJsonObject('event_tags', [ 26 | ['e', 'f06a690997a1b7d8283c90a7224eb8b7fe96b7c3d3d8cc7b2e7f743532c02b42'], 27 | ]) 28 | .orWhereJsonObject('event_tags', [ 29 | ['e', 'cc7ace95dcd091e8b2822b4c3f71dce88aece2adff66eaaea362caa8da8563b7'], 30 | ]) 31 | .orWhereJsonObject('event_tags', [ 32 | ['e', '6c1ab7e5f8cf33874e5b9d85e000c0683d3133ec8294a5009d2f38854aceafb0'], 33 | ]) 34 | .orWhereJsonObject('event_tags', [ 35 | ['e', '9cb8bf059ae86df40407cfa5871c2111b09d3fb2c85c5be67306fcf6b3bab729'], 36 | ]) 37 | .orderBy('event_created_at', 'desc') 38 | .then((events) => { 39 | res.send(events) 40 | }) 41 | }) 42 | 43 | app.get('/test', (req, res) => { 44 | dbClient('events') 45 | .select('*') 46 | .where('event_created_at', '>', 1662309482) 47 | .orderBy('event_created_at', 'desc') 48 | .then((events) => { 49 | res.send(events) 50 | }) 51 | }) 52 | 53 | app.listen(port, () => { 54 | console.log(`⚡️[server]: Server is running at http://localhost:${port}`) 55 | }) 56 | 57 | const pool = relayPool() 58 | 59 | pool.addRelay('wss://relay.damus.io', { read: true, write: false }) 60 | 61 | let eventsToProcess: Event[] = [] 62 | 63 | async function onEvent(event, relay) { 64 | // console.log(`Received event ${event.id} from ${relay}`) 65 | const normalizedEvent: Event = { 66 | id: event.id, 67 | pubkey: event.pubkey, 68 | created_at: event.created_at, 69 | kind: event.kind, 70 | tags: event.tags, 71 | content: event.content, 72 | sig: event.sig, 73 | } 74 | eventsToProcess.push(normalizedEvent) 75 | } 76 | 77 | // @ts-ignore 78 | pool.sub({ 79 | cb: onEvent, 80 | filter: { 81 | kinds: [40, 41, 42, 43, 44], 82 | since: 1662368190, // TODO: make this dynamic based on last event in db 83 | }, 84 | }) 85 | 86 | const processLoop = async () => { 87 | if (eventsToProcess.length === 0) return 88 | const event = eventsToProcess.pop() 89 | if (!event) return 90 | const rowCount = await insert(event).then(prop('rowCount') as () => number) 91 | console.log(`Saved ${rowCount} rows - ${eventsToProcess.length} events left - ${event.id}`) 92 | } 93 | 94 | setInterval(() => { 95 | processLoop() 96 | }, 100) 97 | -------------------------------------------------------------------------------- /src/nostr/event.js: -------------------------------------------------------------------------------- 1 | import { Buffer } from 'buffer' 2 | import createHash from 'create-hash' 3 | import * as secp256k1 from '@noble/secp256k1' 4 | 5 | export function getBlankEvent() { 6 | return { 7 | kind: 255, 8 | pubkey: null, 9 | content: '', 10 | tags: [], 11 | created_at: 0, 12 | } 13 | } 14 | 15 | export function serializeEvent(evt) { 16 | return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]) 17 | } 18 | 19 | export function getEventHash(event) { 20 | let eventHash = createHash('sha256') 21 | .update(Buffer.from(serializeEvent(event))) 22 | .digest() 23 | return Buffer.from(eventHash).toString('hex') 24 | } 25 | 26 | export function validateEvent(event) { 27 | if (event.id !== getEventHash(event)) return false 28 | if (typeof event.content !== 'string') return false 29 | if (typeof event.created_at !== 'number') return false 30 | 31 | if (!Array.isArray(event.tags)) return false 32 | for (let i = 0; i < event.tags.length; i++) { 33 | let tag = event.tags[i] 34 | if (!Array.isArray(tag)) return false 35 | for (let j = 0; j < tag.length; j++) { 36 | if (typeof tag[j] === 'object') return false 37 | } 38 | } 39 | 40 | return true 41 | } 42 | 43 | export function verifySignature(event) { 44 | return secp256k1.schnorr.verify(event.sig, event.id, event.pubkey) 45 | } 46 | 47 | export async function signEvent(event, key) { 48 | return Buffer.from(await secp256k1.schnorr.sign(getEventHash(event), key)).toString('hex') 49 | } 50 | -------------------------------------------------------------------------------- /src/nostr/filter.js: -------------------------------------------------------------------------------- 1 | export function matchFilter(filter, event) { 2 | if (filter.ids && filter.ids.indexOf(event.id) === -1) return false 3 | if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) return false 4 | if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) return false 5 | 6 | for (let f in filter) { 7 | if (f[0] === '#') { 8 | if ( 9 | filter[f] && 10 | !event.tags.find(([t, v]) => t === f.slice(1) && filter[f].indexOf(v) !== -1) 11 | ) 12 | return false 13 | } 14 | } 15 | 16 | if (filter.since && event.created_at < filter.since) return false 17 | if (filter.until && event.created_at >= filter.until) return false 18 | 19 | return true 20 | } 21 | 22 | export function matchFilters(filters, event) { 23 | for (let i = 0; i < filters.length; i++) { 24 | if (matchFilter(filters[i], event)) return true 25 | } 26 | return false 27 | } 28 | -------------------------------------------------------------------------------- /src/nostr/pool.js: -------------------------------------------------------------------------------- 1 | import { getEventHash, verifySignature, signEvent } from './event.js' 2 | import { relayConnect, normalizeRelayURL } from './relay.js' 3 | 4 | export function relayPool() { 5 | var globalPrivateKey 6 | var globalSigningFunction 7 | 8 | const poolPolicy = { 9 | // setting this to a number will cause events to be published to a random 10 | // set of relays only, instead of publishing to all relays all the time 11 | randomChoice: null, 12 | 13 | // setting this to true will cause .publish() calls to wait until the event has 14 | // been published -- or at least attempted to be published -- to all relays 15 | wait: false, 16 | } 17 | const relays = {} 18 | const noticeCallbacks = [] 19 | 20 | function propagateNotice(notice, relayURL) { 21 | for (let i = 0; i < noticeCallbacks.length; i++) { 22 | let { relay } = relays[relayURL] 23 | noticeCallbacks[i](notice, relay) 24 | } 25 | } 26 | 27 | const activeSubscriptions = {} 28 | 29 | const sub = ({ cb, filter, beforeSend }, id) => { 30 | if (!id) id = Math.random().toString().slice(2) 31 | 32 | const subControllers = Object.fromEntries( 33 | Object.values(relays) 34 | .filter(({ policy }) => policy.read) 35 | .map(({ relay }) => [ 36 | relay.url, 37 | relay.sub({ cb: (event) => cb(event, relay.url), filter, beforeSend }, id), 38 | ]) 39 | ) 40 | 41 | const activeCallback = cb 42 | const activeFilters = filter 43 | const activeBeforeSend = beforeSend 44 | 45 | const unsub = () => { 46 | Object.values(subControllers).forEach((sub) => sub.unsub()) 47 | delete activeSubscriptions[id] 48 | } 49 | const sub = ({ 50 | cb = activeCallback, 51 | filter = activeFilters, 52 | beforeSend = activeBeforeSend, 53 | }) => { 54 | Object.entries(subControllers).map(([relayURL, sub]) => [ 55 | relayURL, 56 | sub.sub({ cb: (event) => cb(event, relayURL), filter, beforeSend }, id), 57 | ]) 58 | return activeSubscriptions[id] 59 | } 60 | const addRelay = (relay) => { 61 | subControllers[relay.url] = relay.sub( 62 | { cb: (event) => cb(event, relay.url), filter, beforeSend }, 63 | id 64 | ) 65 | return activeSubscriptions[id] 66 | } 67 | const removeRelay = (relayURL) => { 68 | if (relayURL in subControllers) { 69 | subControllers[relayURL].unsub() 70 | if (Object.keys(subControllers).length === 0) unsub() 71 | } 72 | return activeSubscriptions[id] 73 | } 74 | 75 | activeSubscriptions[id] = { 76 | sub, 77 | unsub, 78 | addRelay, 79 | removeRelay, 80 | } 81 | 82 | return activeSubscriptions[id] 83 | } 84 | 85 | return { 86 | sub, 87 | relays, 88 | setPrivateKey(privateKey) { 89 | globalPrivateKey = privateKey 90 | }, 91 | registerSigningFunction(fn) { 92 | globalSigningFunction = fn 93 | }, 94 | setPolicy(key, value) { 95 | poolPolicy[key] = value 96 | }, 97 | addRelay(url, policy = { read: true, write: true }) { 98 | let relayURL = normalizeRelayURL(url) 99 | if (relayURL in relays) return 100 | 101 | let relay = relayConnect(url, (notice) => { 102 | propagateNotice(notice, relayURL) 103 | }) 104 | relays[relayURL] = { relay, policy } 105 | 106 | if (policy.read) { 107 | Object.values(activeSubscriptions).forEach((subscription) => subscription.addRelay(relay)) 108 | } 109 | 110 | return relay 111 | }, 112 | removeRelay(url) { 113 | let relayURL = normalizeRelayURL(url) 114 | let data = relays[relayURL] 115 | if (!data) return 116 | 117 | let { relay } = data 118 | Object.values(activeSubscriptions).forEach((subscription) => subscription.removeRelay(relay)) 119 | relay.close() 120 | delete relays[relayURL] 121 | }, 122 | onNotice(cb) { 123 | noticeCallbacks.push(cb) 124 | }, 125 | offNotice(cb) { 126 | let index = noticeCallbacks.indexOf(cb) 127 | if (index !== -1) noticeCallbacks.splice(index, 1) 128 | }, 129 | async publish(event, statusCallback) { 130 | event.id = getEventHash(event) 131 | 132 | if (!event.sig) { 133 | event.tags = event.tags || [] 134 | 135 | if (globalPrivateKey) { 136 | event.sig = await signEvent(event, globalPrivateKey) 137 | } else if (globalSigningFunction) { 138 | event.sig = await globalSigningFunction(event) 139 | if (!event.sig) { 140 | // abort here 141 | return 142 | } else { 143 | // check 144 | if (!(await verifySignature(event))) 145 | throw new Error('signature provided by custom signing function is invalid.') 146 | } 147 | } else { 148 | throw new Error( 149 | "can't publish unsigned event. either sign this event beforehand, provide a signing function or pass a private key while initializing this relay pool so it can be signed automatically." 150 | ) 151 | } 152 | } 153 | 154 | let writeable = Object.values(relays) 155 | .filter(({ policy }) => policy.write) 156 | .sort(() => Math.random() - 0.5) // random 157 | 158 | let maxTargets = poolPolicy.randomChoice ? poolPolicy.randomChoice : writeable.length 159 | 160 | let successes = 0 161 | 162 | if (poolPolicy.wait) { 163 | for (let i = 0; i < writeable.length; i++) { 164 | let { relay } = writeable[i] 165 | 166 | try { 167 | await new Promise(async (resolve, reject) => { 168 | try { 169 | await relay.publish(event, (status) => { 170 | if (statusCallback) statusCallback(status, relay.url) 171 | resolve() 172 | }) 173 | } catch (err) { 174 | if (statusCallback) statusCallback(-1, relay.url) 175 | } 176 | }) 177 | 178 | successes++ 179 | if (successes >= maxTargets) { 180 | break 181 | } 182 | } catch (err) { 183 | /***/ 184 | } 185 | } 186 | } else { 187 | writeable.forEach(async ({ relay }) => { 188 | let callback = statusCallback ? (status) => statusCallback(status, relay.url) : null 189 | relay.publish(event, callback) 190 | }) 191 | } 192 | 193 | return event 194 | }, 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/nostr/relay.js: -------------------------------------------------------------------------------- 1 | /* global WebSocket */ 2 | 3 | import 'websocket-polyfill' 4 | 5 | import { verifySignature, validateEvent } from './event.js' 6 | import { matchFilters } from './filter.js' 7 | 8 | export function normalizeRelayURL(url) { 9 | let [host, ...qs] = url.trim().split('?') 10 | if (host.slice(0, 4) === 'http') host = 'ws' + host.slice(4) 11 | if (host.slice(0, 2) !== 'ws') host = 'wss://' + host 12 | if (host.length && host[host.length - 1] === '/') host = host.slice(0, -1) 13 | return [host, ...qs].join('?') 14 | } 15 | 16 | export function relayConnect(url, onNotice = () => {}, onError = () => {}) { 17 | url = normalizeRelayURL(url) 18 | 19 | var ws, resolveOpen, untilOpen, wasClosed 20 | var openSubs = {} 21 | var isSetToSkipVerification = {} 22 | let attemptNumber = 1 23 | let nextAttemptSeconds = 1 24 | 25 | function resetOpenState() { 26 | untilOpen = new Promise((resolve) => { 27 | resolveOpen = resolve 28 | }) 29 | } 30 | 31 | var channels = {} 32 | 33 | function connect() { 34 | ws = new WebSocket(url) 35 | 36 | ws.onopen = () => { 37 | console.log('connected to', url) 38 | resolveOpen() 39 | 40 | // restablish old subscriptions 41 | if (wasClosed) { 42 | wasClosed = false 43 | for (let channel in openSubs) { 44 | let filters = openSubs[channel] 45 | let cb = channels[channel] 46 | sub({ cb, filter: filters }, channel) 47 | } 48 | } 49 | } 50 | ws.onerror = (err) => { 51 | console.log('error connecting to relay', url) 52 | onError(err) 53 | } 54 | ws.onclose = () => { 55 | resetOpenState() 56 | attemptNumber++ 57 | nextAttemptSeconds += attemptNumber ** 2 58 | if (nextAttemptSeconds > 14400) { 59 | nextAttemptSeconds = 14400 // 4 hours 60 | } 61 | console.log(`relay ${url} connection closed. reconnecting in 1 second.`) 62 | setTimeout(async () => { 63 | try { 64 | connect() 65 | } catch (err) {} 66 | }, 1000) // nextAttemptSeconds * 67 | 68 | wasClosed = true 69 | } 70 | 71 | ws.onmessage = async (e) => { 72 | var data 73 | try { 74 | data = JSON.parse(e.data) 75 | } catch (err) { 76 | data = e.data 77 | } 78 | 79 | if (data.length > 1) { 80 | if (data[0] === 'NOTICE') { 81 | if (data.length < 2) return 82 | 83 | console.log('message from relay ' + url + ': ' + data[1]) 84 | onNotice(data[1]) 85 | return 86 | } 87 | 88 | if (data[0] === 'EVENT') { 89 | if (data.length < 3) return 90 | 91 | let channel = data[1] 92 | let event = data[2] 93 | 94 | if ( 95 | validateEvent(event) && 96 | (isSetToSkipVerification[channel] || verifySignature(event)) && 97 | channels[channel] && 98 | matchFilters(openSubs[channel], event) 99 | ) { 100 | channels[channel](event) 101 | } 102 | return 103 | } 104 | } 105 | } 106 | } 107 | 108 | resetOpenState() 109 | 110 | try { 111 | connect() 112 | } catch (err) {} 113 | 114 | async function trySend(params) { 115 | let msg = JSON.stringify(params) 116 | await untilOpen 117 | ws.send(msg) 118 | } 119 | 120 | const sub = ( 121 | { cb, filter, beforeSend, skipVerification }, 122 | channel = Math.random().toString().slice(2) 123 | ) => { 124 | var filters = [] 125 | if (Array.isArray(filter)) { 126 | filters = filter 127 | } else { 128 | filters.push(filter) 129 | } 130 | 131 | if (beforeSend) { 132 | const beforeSendResult = beforeSend({ filter, relay: url, channel }) 133 | filters = beforeSendResult.filter 134 | } 135 | 136 | trySend(['REQ', channel, ...filters]) 137 | channels[channel] = cb 138 | openSubs[channel] = filters 139 | isSetToSkipVerification[channel] = skipVerification 140 | 141 | const activeCallback = cb 142 | const activeFilters = filters 143 | const activeBeforeSend = beforeSend 144 | 145 | return { 146 | sub: ({ cb = activeCallback, filter = activeFilters, beforeSend = activeBeforeSend }) => 147 | sub({ cb, filter, beforeSend, skipVerification }, channel), 148 | unsub: () => { 149 | delete openSubs[channel] 150 | delete channels[channel] 151 | delete isSetToSkipVerification[channel] 152 | trySend(['CLOSE', channel]) 153 | }, 154 | } 155 | } 156 | 157 | return { 158 | url, 159 | sub, 160 | async publish(event, statusCallback) { 161 | try { 162 | await trySend(['EVENT', event]) 163 | if (statusCallback) { 164 | statusCallback(0) 165 | let { unsub } = sub( 166 | { 167 | cb: () => { 168 | statusCallback(1) 169 | unsub() 170 | clearTimeout(willUnsub) 171 | }, 172 | filter: { ids: [event.id] }, 173 | }, 174 | `monitor-${event.id.slice(0, 5)}` 175 | ) 176 | let willUnsub = setTimeout(unsub, 5000) 177 | } 178 | } catch (err) { 179 | if (statusCallback) statusCallback(-1) 180 | } 181 | }, 182 | close() { 183 | ws.onclose = () => { 184 | console.log('Closed and not reconnecting') 185 | } 186 | ws.close() 187 | }, 188 | get status() { 189 | return ws.readyState 190 | }, 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/utils/sleep.ts: -------------------------------------------------------------------------------- 1 | export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)) 2 | -------------------------------------------------------------------------------- /src/utils/transform.ts: -------------------------------------------------------------------------------- 1 | export const toJSON = (input: any) => JSON.stringify(input) 2 | 3 | export const toBuffer = (input: any) => Buffer.from(input, 'hex') 4 | 5 | export const fromBuffer = (input: Buffer) => input.toString('hex') 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs" /* Specify what module code is generated. */, 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "resolveJsonModule": true, /* Enable importing .json files. */ 39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | "allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */, 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 45 | 46 | /* Emit */ 47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 50 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 51 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 52 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 53 | // "removeComments": true, /* Disable emitting comments. */ 54 | // "noEmit": true, /* Disable emitting files from a compilation. */ 55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 63 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 64 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 67 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 70 | 71 | /* Interop Constraints */ 72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 73 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 74 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 76 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 77 | 78 | /* Type Checking */ 79 | "strict": true /* Enable all strict type-checking options. */, 80 | "noImplicitAny": false /* Enable error reporting for expressions and declarations with an implied 'any' type. */, 81 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 83 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 85 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 86 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 88 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 93 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 98 | 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 102 | }, 103 | "include": ["src/**/*.ts"] 104 | } 105 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@noble/secp256k1@1.6.3": 6 | version "1.6.3" 7 | resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" 8 | integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ== 9 | 10 | "@types/body-parser@*": 11 | version "1.19.2" 12 | resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" 13 | integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== 14 | dependencies: 15 | "@types/connect" "*" 16 | "@types/node" "*" 17 | 18 | "@types/connect@*": 19 | version "3.4.35" 20 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" 21 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== 22 | dependencies: 23 | "@types/node" "*" 24 | 25 | "@types/express-serve-static-core@^4.17.18": 26 | version "4.17.30" 27 | resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" 28 | integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== 29 | dependencies: 30 | "@types/node" "*" 31 | "@types/qs" "*" 32 | "@types/range-parser" "*" 33 | 34 | "@types/express@4.17.13": 35 | version "4.17.13" 36 | resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" 37 | integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== 38 | dependencies: 39 | "@types/body-parser" "*" 40 | "@types/express-serve-static-core" "^4.17.18" 41 | "@types/qs" "*" 42 | "@types/serve-static" "*" 43 | 44 | "@types/mime@*": 45 | version "3.0.1" 46 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" 47 | integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== 48 | 49 | "@types/node@*", "@types/node@18.7.14": 50 | version "18.7.14" 51 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.14.tgz#0fe081752a3333392d00586d815485a17c2cf3c9" 52 | integrity sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA== 53 | 54 | "@types/qs@*": 55 | version "6.9.7" 56 | resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" 57 | integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== 58 | 59 | "@types/ramda@0.28.15": 60 | version "0.28.15" 61 | resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.28.15.tgz#36bb4c8de430e3bbcd29590537569aef64409716" 62 | integrity sha512-FCaLNVZry65jW8x/FDnKgjgkCNQxgc5AYMQwdNn6yW5M+62R+0nt2Y36U43dTNora9hcquemfrY5gxhE5pcilQ== 63 | dependencies: 64 | ts-toolbelt "^6.15.1" 65 | 66 | "@types/range-parser@*": 67 | version "1.2.4" 68 | resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" 69 | integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== 70 | 71 | "@types/serve-static@*": 72 | version "1.15.0" 73 | resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" 74 | integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== 75 | dependencies: 76 | "@types/mime" "*" 77 | "@types/node" "*" 78 | 79 | abbrev@1: 80 | version "1.1.1" 81 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 82 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 83 | 84 | accepts@~1.3.8: 85 | version "1.3.8" 86 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" 87 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== 88 | dependencies: 89 | mime-types "~2.1.34" 90 | negotiator "0.6.3" 91 | 92 | ansi-regex@^5.0.1: 93 | version "5.0.1" 94 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 95 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 96 | 97 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 98 | version "4.3.0" 99 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 100 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 101 | dependencies: 102 | color-convert "^2.0.1" 103 | 104 | anymatch@~3.1.2: 105 | version "3.1.2" 106 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 107 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 108 | dependencies: 109 | normalize-path "^3.0.0" 110 | picomatch "^2.0.4" 111 | 112 | array-flatten@1.1.1: 113 | version "1.1.1" 114 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 115 | integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== 116 | 117 | balanced-match@^1.0.0: 118 | version "1.0.2" 119 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 120 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 121 | 122 | binary-extensions@^2.0.0: 123 | version "2.2.0" 124 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 125 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 126 | 127 | body-parser@1.20.0: 128 | version "1.20.0" 129 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" 130 | integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== 131 | dependencies: 132 | bytes "3.1.2" 133 | content-type "~1.0.4" 134 | debug "2.6.9" 135 | depd "2.0.0" 136 | destroy "1.2.0" 137 | http-errors "2.0.0" 138 | iconv-lite "0.4.24" 139 | on-finished "2.4.1" 140 | qs "6.10.3" 141 | raw-body "2.5.1" 142 | type-is "~1.6.18" 143 | unpipe "1.0.0" 144 | 145 | brace-expansion@^1.1.7: 146 | version "1.1.11" 147 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 148 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 149 | dependencies: 150 | balanced-match "^1.0.0" 151 | concat-map "0.0.1" 152 | 153 | braces@~3.0.2: 154 | version "3.0.2" 155 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 156 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 157 | dependencies: 158 | fill-range "^7.0.1" 159 | 160 | buffer-writer@2.0.0: 161 | version "2.0.0" 162 | resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" 163 | integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== 164 | 165 | bufferutil@^4.0.1: 166 | version "4.0.6" 167 | resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" 168 | integrity sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw== 169 | dependencies: 170 | node-gyp-build "^4.3.0" 171 | 172 | bytes@3.1.2: 173 | version "3.1.2" 174 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" 175 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== 176 | 177 | call-bind@^1.0.0: 178 | version "1.0.2" 179 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" 180 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== 181 | dependencies: 182 | function-bind "^1.1.1" 183 | get-intrinsic "^1.0.2" 184 | 185 | chalk@^4.1.0: 186 | version "4.1.2" 187 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 188 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 189 | dependencies: 190 | ansi-styles "^4.1.0" 191 | supports-color "^7.1.0" 192 | 193 | chokidar@^3.5.2: 194 | version "3.5.3" 195 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 196 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 197 | dependencies: 198 | anymatch "~3.1.2" 199 | braces "~3.0.2" 200 | glob-parent "~5.1.2" 201 | is-binary-path "~2.1.0" 202 | is-glob "~4.0.1" 203 | normalize-path "~3.0.0" 204 | readdirp "~3.6.0" 205 | optionalDependencies: 206 | fsevents "~2.3.2" 207 | 208 | cipher-base@^1.0.1: 209 | version "1.0.4" 210 | resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" 211 | integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== 212 | dependencies: 213 | inherits "^2.0.1" 214 | safe-buffer "^5.0.1" 215 | 216 | cliui@^7.0.2: 217 | version "7.0.4" 218 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 219 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 220 | dependencies: 221 | string-width "^4.2.0" 222 | strip-ansi "^6.0.0" 223 | wrap-ansi "^7.0.0" 224 | 225 | color-convert@^2.0.1: 226 | version "2.0.1" 227 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 228 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 229 | dependencies: 230 | color-name "~1.1.4" 231 | 232 | color-name@~1.1.4: 233 | version "1.1.4" 234 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 235 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 236 | 237 | colorette@2.0.19: 238 | version "2.0.19" 239 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" 240 | integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== 241 | 242 | commander@^9.1.0: 243 | version "9.4.0" 244 | resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c" 245 | integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw== 246 | 247 | concat-map@0.0.1: 248 | version "0.0.1" 249 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 250 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 251 | 252 | concurrently@7.3.0: 253 | version "7.3.0" 254 | resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.3.0.tgz#eb45cdbc8df43da195f619aba218a980cae49184" 255 | integrity sha512-IiDwm+8DOcFEInca494A8V402tNTQlJaYq78RF2rijOrKEk/AOHTxhN4U1cp7GYKYX5Q6Ymh1dLTBlzIMN0ikA== 256 | dependencies: 257 | chalk "^4.1.0" 258 | date-fns "^2.16.1" 259 | lodash "^4.17.21" 260 | rxjs "^7.0.0" 261 | shell-quote "^1.7.3" 262 | spawn-command "^0.0.2-1" 263 | supports-color "^8.1.0" 264 | tree-kill "^1.2.2" 265 | yargs "^17.3.1" 266 | 267 | content-disposition@0.5.4: 268 | version "0.5.4" 269 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" 270 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== 271 | dependencies: 272 | safe-buffer "5.2.1" 273 | 274 | content-type@~1.0.4: 275 | version "1.0.4" 276 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 277 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 278 | 279 | cookie-signature@1.0.6: 280 | version "1.0.6" 281 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 282 | integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== 283 | 284 | cookie@0.5.0: 285 | version "0.5.0" 286 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" 287 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== 288 | 289 | create-hash@1.2.0: 290 | version "1.2.0" 291 | resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" 292 | integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== 293 | dependencies: 294 | cipher-base "^1.0.1" 295 | inherits "^2.0.1" 296 | md5.js "^1.3.4" 297 | ripemd160 "^2.0.1" 298 | sha.js "^2.4.0" 299 | 300 | d@1, d@^1.0.1: 301 | version "1.0.1" 302 | resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" 303 | integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== 304 | dependencies: 305 | es5-ext "^0.10.50" 306 | type "^1.0.1" 307 | 308 | date-fns@^2.16.1: 309 | version "2.29.2" 310 | resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.2.tgz#0d4b3d0f3dff0f920820a070920f0d9662c51931" 311 | integrity sha512-0VNbwmWJDS/G3ySwFSJA3ayhbURMTJLtwM2DTxf9CWondCnh6DTNlO9JgRSq6ibf4eD0lfMJNBxUdEAHHix+bA== 312 | 313 | debug@2.6.9, debug@^2.2.0: 314 | version "2.6.9" 315 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 316 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 317 | dependencies: 318 | ms "2.0.0" 319 | 320 | debug@4.3.4: 321 | version "4.3.4" 322 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 323 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 324 | dependencies: 325 | ms "2.1.2" 326 | 327 | debug@^3.2.7: 328 | version "3.2.7" 329 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" 330 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== 331 | dependencies: 332 | ms "^2.1.1" 333 | 334 | depd@2.0.0: 335 | version "2.0.0" 336 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 337 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 338 | 339 | destroy@1.2.0: 340 | version "1.2.0" 341 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" 342 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 343 | 344 | dotenv@16.0.2: 345 | version "16.0.2" 346 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.2.tgz#0b0f8652c016a3858ef795024508cddc4bffc5bf" 347 | integrity sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA== 348 | 349 | ee-first@1.1.1: 350 | version "1.1.1" 351 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 352 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== 353 | 354 | emoji-regex@^8.0.0: 355 | version "8.0.0" 356 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 357 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 358 | 359 | encodeurl@~1.0.2: 360 | version "1.0.2" 361 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 362 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== 363 | 364 | es5-ext@^0.10.35, es5-ext@^0.10.50: 365 | version "0.10.62" 366 | resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" 367 | integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== 368 | dependencies: 369 | es6-iterator "^2.0.3" 370 | es6-symbol "^3.1.3" 371 | next-tick "^1.1.0" 372 | 373 | es6-iterator@^2.0.3: 374 | version "2.0.3" 375 | resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" 376 | integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== 377 | dependencies: 378 | d "1" 379 | es5-ext "^0.10.35" 380 | es6-symbol "^3.1.1" 381 | 382 | es6-symbol@^3.1.1, es6-symbol@^3.1.3: 383 | version "3.1.3" 384 | resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" 385 | integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== 386 | dependencies: 387 | d "^1.0.1" 388 | ext "^1.1.2" 389 | 390 | escalade@^3.1.1: 391 | version "3.1.1" 392 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 393 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 394 | 395 | escape-html@~1.0.3: 396 | version "1.0.3" 397 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 398 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 399 | 400 | esm@^3.2.25: 401 | version "3.2.25" 402 | resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" 403 | integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== 404 | 405 | etag@~1.8.1: 406 | version "1.8.1" 407 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 408 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== 409 | 410 | express@4.18.1: 411 | version "4.18.1" 412 | resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" 413 | integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== 414 | dependencies: 415 | accepts "~1.3.8" 416 | array-flatten "1.1.1" 417 | body-parser "1.20.0" 418 | content-disposition "0.5.4" 419 | content-type "~1.0.4" 420 | cookie "0.5.0" 421 | cookie-signature "1.0.6" 422 | debug "2.6.9" 423 | depd "2.0.0" 424 | encodeurl "~1.0.2" 425 | escape-html "~1.0.3" 426 | etag "~1.8.1" 427 | finalhandler "1.2.0" 428 | fresh "0.5.2" 429 | http-errors "2.0.0" 430 | merge-descriptors "1.0.1" 431 | methods "~1.1.2" 432 | on-finished "2.4.1" 433 | parseurl "~1.3.3" 434 | path-to-regexp "0.1.7" 435 | proxy-addr "~2.0.7" 436 | qs "6.10.3" 437 | range-parser "~1.2.1" 438 | safe-buffer "5.2.1" 439 | send "0.18.0" 440 | serve-static "1.15.0" 441 | setprototypeof "1.2.0" 442 | statuses "2.0.1" 443 | type-is "~1.6.18" 444 | utils-merge "1.0.1" 445 | vary "~1.1.2" 446 | 447 | ext@^1.1.2: 448 | version "1.7.0" 449 | resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" 450 | integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== 451 | dependencies: 452 | type "^2.7.2" 453 | 454 | fill-range@^7.0.1: 455 | version "7.0.1" 456 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 457 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 458 | dependencies: 459 | to-regex-range "^5.0.1" 460 | 461 | finalhandler@1.2.0: 462 | version "1.2.0" 463 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" 464 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== 465 | dependencies: 466 | debug "2.6.9" 467 | encodeurl "~1.0.2" 468 | escape-html "~1.0.3" 469 | on-finished "2.4.1" 470 | parseurl "~1.3.3" 471 | statuses "2.0.1" 472 | unpipe "~1.0.0" 473 | 474 | forwarded@0.2.0: 475 | version "0.2.0" 476 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" 477 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== 478 | 479 | fresh@0.5.2: 480 | version "0.5.2" 481 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 482 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== 483 | 484 | fsevents@~2.3.2: 485 | version "2.3.2" 486 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 487 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 488 | 489 | function-bind@^1.1.1: 490 | version "1.1.1" 491 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 492 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 493 | 494 | get-caller-file@^2.0.5: 495 | version "2.0.5" 496 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 497 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 498 | 499 | get-intrinsic@^1.0.2: 500 | version "1.1.2" 501 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" 502 | integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== 503 | dependencies: 504 | function-bind "^1.1.1" 505 | has "^1.0.3" 506 | has-symbols "^1.0.3" 507 | 508 | get-package-type@^0.1.0: 509 | version "0.1.0" 510 | resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" 511 | integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== 512 | 513 | getopts@2.3.0: 514 | version "2.3.0" 515 | resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" 516 | integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== 517 | 518 | glob-parent@~5.1.2: 519 | version "5.1.2" 520 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 521 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 522 | dependencies: 523 | is-glob "^4.0.1" 524 | 525 | has-flag@^3.0.0: 526 | version "3.0.0" 527 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 528 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 529 | 530 | has-flag@^4.0.0: 531 | version "4.0.0" 532 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 533 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 534 | 535 | has-symbols@^1.0.3: 536 | version "1.0.3" 537 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 538 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 539 | 540 | has@^1.0.3: 541 | version "1.0.3" 542 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 543 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 544 | dependencies: 545 | function-bind "^1.1.1" 546 | 547 | hash-base@^3.0.0: 548 | version "3.1.0" 549 | resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" 550 | integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== 551 | dependencies: 552 | inherits "^2.0.4" 553 | readable-stream "^3.6.0" 554 | safe-buffer "^5.2.0" 555 | 556 | http-errors@2.0.0: 557 | version "2.0.0" 558 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" 559 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 560 | dependencies: 561 | depd "2.0.0" 562 | inherits "2.0.4" 563 | setprototypeof "1.2.0" 564 | statuses "2.0.1" 565 | toidentifier "1.0.1" 566 | 567 | iconv-lite@0.4.24: 568 | version "0.4.24" 569 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 570 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 571 | dependencies: 572 | safer-buffer ">= 2.1.2 < 3" 573 | 574 | ignore-by-default@^1.0.1: 575 | version "1.0.1" 576 | resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" 577 | integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== 578 | 579 | inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: 580 | version "2.0.4" 581 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 582 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 583 | 584 | interpret@^2.2.0: 585 | version "2.2.0" 586 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" 587 | integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== 588 | 589 | ipaddr.js@1.9.1: 590 | version "1.9.1" 591 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 592 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 593 | 594 | is-binary-path@~2.1.0: 595 | version "2.1.0" 596 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 597 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 598 | dependencies: 599 | binary-extensions "^2.0.0" 600 | 601 | is-core-module@^2.9.0: 602 | version "2.10.0" 603 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" 604 | integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== 605 | dependencies: 606 | has "^1.0.3" 607 | 608 | is-extglob@^2.1.1: 609 | version "2.1.1" 610 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 611 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 612 | 613 | is-fullwidth-code-point@^3.0.0: 614 | version "3.0.0" 615 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 616 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 617 | 618 | is-glob@^4.0.1, is-glob@~4.0.1: 619 | version "4.0.3" 620 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 621 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 622 | dependencies: 623 | is-extglob "^2.1.1" 624 | 625 | is-number@^7.0.0: 626 | version "7.0.0" 627 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 628 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 629 | 630 | is-typedarray@^1.0.0: 631 | version "1.0.0" 632 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 633 | integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== 634 | 635 | knex@2.3.0: 636 | version "2.3.0" 637 | resolved "https://registry.yarnpkg.com/knex/-/knex-2.3.0.tgz#87fa2a9553d7cafb125d7a0645256fbe29ef5967" 638 | integrity sha512-WMizPaq9wRMkfnwKXKXgBZeZFOSHGdtoSz5SaLAVNs3WRDfawt9O89T4XyH52PETxjV8/kRk0Yf+8WBEP/zbYw== 639 | dependencies: 640 | colorette "2.0.19" 641 | commander "^9.1.0" 642 | debug "4.3.4" 643 | escalade "^3.1.1" 644 | esm "^3.2.25" 645 | get-package-type "^0.1.0" 646 | getopts "2.3.0" 647 | interpret "^2.2.0" 648 | lodash "^4.17.21" 649 | pg-connection-string "2.5.0" 650 | rechoir "^0.8.0" 651 | resolve-from "^5.0.0" 652 | tarn "^3.0.2" 653 | tildify "2.0.0" 654 | 655 | lodash@^4.17.21: 656 | version "4.17.21" 657 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 658 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 659 | 660 | md5.js@^1.3.4: 661 | version "1.3.5" 662 | resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" 663 | integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== 664 | dependencies: 665 | hash-base "^3.0.0" 666 | inherits "^2.0.1" 667 | safe-buffer "^5.1.2" 668 | 669 | media-typer@0.3.0: 670 | version "0.3.0" 671 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 672 | integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== 673 | 674 | merge-descriptors@1.0.1: 675 | version "1.0.1" 676 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 677 | integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== 678 | 679 | methods@~1.1.2: 680 | version "1.1.2" 681 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 682 | integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== 683 | 684 | mime-db@1.52.0: 685 | version "1.52.0" 686 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 687 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 688 | 689 | mime-types@~2.1.24, mime-types@~2.1.34: 690 | version "2.1.35" 691 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 692 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 693 | dependencies: 694 | mime-db "1.52.0" 695 | 696 | mime@1.6.0: 697 | version "1.6.0" 698 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 699 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 700 | 701 | minimatch@^3.0.4: 702 | version "3.1.2" 703 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 704 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 705 | dependencies: 706 | brace-expansion "^1.1.7" 707 | 708 | ms@2.0.0: 709 | version "2.0.0" 710 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 711 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== 712 | 713 | ms@2.1.2: 714 | version "2.1.2" 715 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 716 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 717 | 718 | ms@2.1.3, ms@^2.1.1: 719 | version "2.1.3" 720 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 721 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 722 | 723 | negotiator@0.6.3: 724 | version "0.6.3" 725 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" 726 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== 727 | 728 | next-tick@^1.1.0: 729 | version "1.1.0" 730 | resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" 731 | integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== 732 | 733 | node-gyp-build@^4.3.0: 734 | version "4.5.0" 735 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" 736 | integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== 737 | 738 | nodemon@2.0.19: 739 | version "2.0.19" 740 | resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.19.tgz#cac175f74b9cb8b57e770d47841995eebe4488bd" 741 | integrity sha512-4pv1f2bMDj0Eeg/MhGqxrtveeQ5/G/UVe9iO6uTZzjnRluSA4PVWf8CW99LUPwGB3eNIA7zUFoP77YuI7hOc0A== 742 | dependencies: 743 | chokidar "^3.5.2" 744 | debug "^3.2.7" 745 | ignore-by-default "^1.0.1" 746 | minimatch "^3.0.4" 747 | pstree.remy "^1.1.8" 748 | semver "^5.7.1" 749 | simple-update-notifier "^1.0.7" 750 | supports-color "^5.5.0" 751 | touch "^3.1.0" 752 | undefsafe "^2.0.5" 753 | 754 | nopt@~1.0.10: 755 | version "1.0.10" 756 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" 757 | integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== 758 | dependencies: 759 | abbrev "1" 760 | 761 | normalize-path@^3.0.0, normalize-path@~3.0.0: 762 | version "3.0.0" 763 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 764 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 765 | 766 | object-inspect@^1.9.0: 767 | version "1.12.2" 768 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" 769 | integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== 770 | 771 | on-finished@2.4.1: 772 | version "2.4.1" 773 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" 774 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 775 | dependencies: 776 | ee-first "1.1.1" 777 | 778 | packet-reader@1.0.0: 779 | version "1.0.0" 780 | resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" 781 | integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== 782 | 783 | parseurl@~1.3.3: 784 | version "1.3.3" 785 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 786 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 787 | 788 | path-parse@^1.0.7: 789 | version "1.0.7" 790 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 791 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 792 | 793 | path-to-regexp@0.1.7: 794 | version "0.1.7" 795 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 796 | integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== 797 | 798 | pg-connection-string@2.5.0, pg-connection-string@^2.5.0: 799 | version "2.5.0" 800 | resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" 801 | integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== 802 | 803 | pg-cursor@^2.7.4: 804 | version "2.7.4" 805 | resolved "https://registry.yarnpkg.com/pg-cursor/-/pg-cursor-2.7.4.tgz#e53ac24c7d227b1c3b5a7c5d4b4c64148c13d040" 806 | integrity sha512-CNWwOzTTZ9QvphoOL+Wg/7pmVr9GnAWBjPbuK2FRclrB4A/WRO/ssCJ9BlkzIGmmofK2M/LyokNHgsLSn+fMHA== 807 | 808 | pg-int8@1.0.1: 809 | version "1.0.1" 810 | resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" 811 | integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== 812 | 813 | pg-pool@^3.5.2: 814 | version "3.5.2" 815 | resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.5.2.tgz#ed1bed1fb8d79f1c6fd5fb1c99e990fbf9ddf178" 816 | integrity sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w== 817 | 818 | pg-protocol@^1.5.0: 819 | version "1.5.0" 820 | resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0" 821 | integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ== 822 | 823 | pg-query-stream@4.2.4: 824 | version "4.2.4" 825 | resolved "https://registry.yarnpkg.com/pg-query-stream/-/pg-query-stream-4.2.4.tgz#0e7ef4235586f8925b1d534d2d79b601b7cd9323" 826 | integrity sha512-Et3gTrWn4C2rj4LVioNq1QDd7aH/3mSJcBm79jZALv3wopvx9bWENtbOYZbHQ6KM+IkfFxs0JF1ZLjMDJ9/N6Q== 827 | dependencies: 828 | pg-cursor "^2.7.4" 829 | 830 | pg-types@^2.1.0: 831 | version "2.2.0" 832 | resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" 833 | integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== 834 | dependencies: 835 | pg-int8 "1.0.1" 836 | postgres-array "~2.0.0" 837 | postgres-bytea "~1.0.0" 838 | postgres-date "~1.0.4" 839 | postgres-interval "^1.1.0" 840 | 841 | pg@8.8.0: 842 | version "8.8.0" 843 | resolved "https://registry.yarnpkg.com/pg/-/pg-8.8.0.tgz#a77f41f9d9ede7009abfca54667c775a240da686" 844 | integrity sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw== 845 | dependencies: 846 | buffer-writer "2.0.0" 847 | packet-reader "1.0.0" 848 | pg-connection-string "^2.5.0" 849 | pg-pool "^3.5.2" 850 | pg-protocol "^1.5.0" 851 | pg-types "^2.1.0" 852 | pgpass "1.x" 853 | 854 | pgpass@1.x: 855 | version "1.0.5" 856 | resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" 857 | integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== 858 | dependencies: 859 | split2 "^4.1.0" 860 | 861 | picomatch@^2.0.4, picomatch@^2.2.1: 862 | version "2.3.1" 863 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 864 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 865 | 866 | postgres-array@~2.0.0: 867 | version "2.0.0" 868 | resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" 869 | integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== 870 | 871 | postgres-bytea@~1.0.0: 872 | version "1.0.0" 873 | resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" 874 | integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== 875 | 876 | postgres-date@~1.0.4: 877 | version "1.0.7" 878 | resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" 879 | integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== 880 | 881 | postgres-interval@^1.1.0: 882 | version "1.2.0" 883 | resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" 884 | integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== 885 | dependencies: 886 | xtend "^4.0.0" 887 | 888 | proxy-addr@~2.0.7: 889 | version "2.0.7" 890 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" 891 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== 892 | dependencies: 893 | forwarded "0.2.0" 894 | ipaddr.js "1.9.1" 895 | 896 | pstree.remy@^1.1.8: 897 | version "1.1.8" 898 | resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" 899 | integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== 900 | 901 | qs@6.10.3: 902 | version "6.10.3" 903 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" 904 | integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== 905 | dependencies: 906 | side-channel "^1.0.4" 907 | 908 | ramda@0.28.0: 909 | version "0.28.0" 910 | resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97" 911 | integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA== 912 | 913 | range-parser@~1.2.1: 914 | version "1.2.1" 915 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 916 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 917 | 918 | raw-body@2.5.1: 919 | version "2.5.1" 920 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" 921 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== 922 | dependencies: 923 | bytes "3.1.2" 924 | http-errors "2.0.0" 925 | iconv-lite "0.4.24" 926 | unpipe "1.0.0" 927 | 928 | readable-stream@^3.6.0: 929 | version "3.6.0" 930 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 931 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 932 | dependencies: 933 | inherits "^2.0.3" 934 | string_decoder "^1.1.1" 935 | util-deprecate "^1.0.1" 936 | 937 | readdirp@~3.6.0: 938 | version "3.6.0" 939 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 940 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 941 | dependencies: 942 | picomatch "^2.2.1" 943 | 944 | rechoir@^0.8.0: 945 | version "0.8.0" 946 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" 947 | integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== 948 | dependencies: 949 | resolve "^1.20.0" 950 | 951 | require-directory@^2.1.1: 952 | version "2.1.1" 953 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 954 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 955 | 956 | resolve-from@^5.0.0: 957 | version "5.0.0" 958 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" 959 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== 960 | 961 | resolve@^1.20.0: 962 | version "1.22.1" 963 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" 964 | integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== 965 | dependencies: 966 | is-core-module "^2.9.0" 967 | path-parse "^1.0.7" 968 | supports-preserve-symlinks-flag "^1.0.0" 969 | 970 | ripemd160@^2.0.1: 971 | version "2.0.2" 972 | resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" 973 | integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== 974 | dependencies: 975 | hash-base "^3.0.0" 976 | inherits "^2.0.1" 977 | 978 | rxjs@^7.0.0: 979 | version "7.5.6" 980 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" 981 | integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== 982 | dependencies: 983 | tslib "^2.1.0" 984 | 985 | safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: 986 | version "5.2.1" 987 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 988 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 989 | 990 | "safer-buffer@>= 2.1.2 < 3": 991 | version "2.1.2" 992 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 993 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 994 | 995 | semver@^5.7.1: 996 | version "5.7.1" 997 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 998 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 999 | 1000 | semver@~7.0.0: 1001 | version "7.0.0" 1002 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" 1003 | integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== 1004 | 1005 | send@0.18.0: 1006 | version "0.18.0" 1007 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" 1008 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== 1009 | dependencies: 1010 | debug "2.6.9" 1011 | depd "2.0.0" 1012 | destroy "1.2.0" 1013 | encodeurl "~1.0.2" 1014 | escape-html "~1.0.3" 1015 | etag "~1.8.1" 1016 | fresh "0.5.2" 1017 | http-errors "2.0.0" 1018 | mime "1.6.0" 1019 | ms "2.1.3" 1020 | on-finished "2.4.1" 1021 | range-parser "~1.2.1" 1022 | statuses "2.0.1" 1023 | 1024 | serve-static@1.15.0: 1025 | version "1.15.0" 1026 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" 1027 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== 1028 | dependencies: 1029 | encodeurl "~1.0.2" 1030 | escape-html "~1.0.3" 1031 | parseurl "~1.3.3" 1032 | send "0.18.0" 1033 | 1034 | setprototypeof@1.2.0: 1035 | version "1.2.0" 1036 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" 1037 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 1038 | 1039 | sha.js@^2.4.0: 1040 | version "2.4.11" 1041 | resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" 1042 | integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== 1043 | dependencies: 1044 | inherits "^2.0.1" 1045 | safe-buffer "^5.0.1" 1046 | 1047 | shell-quote@^1.7.3: 1048 | version "1.7.3" 1049 | resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" 1050 | integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== 1051 | 1052 | side-channel@^1.0.4: 1053 | version "1.0.4" 1054 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" 1055 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== 1056 | dependencies: 1057 | call-bind "^1.0.0" 1058 | get-intrinsic "^1.0.2" 1059 | object-inspect "^1.9.0" 1060 | 1061 | simple-update-notifier@^1.0.7: 1062 | version "1.0.7" 1063 | resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" 1064 | integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== 1065 | dependencies: 1066 | semver "~7.0.0" 1067 | 1068 | spawn-command@^0.0.2-1: 1069 | version "0.0.2-1" 1070 | resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" 1071 | integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== 1072 | 1073 | split2@^4.1.0: 1074 | version "4.1.0" 1075 | resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809" 1076 | integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ== 1077 | 1078 | statuses@2.0.1: 1079 | version "2.0.1" 1080 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" 1081 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 1082 | 1083 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 1084 | version "4.2.3" 1085 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1086 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1087 | dependencies: 1088 | emoji-regex "^8.0.0" 1089 | is-fullwidth-code-point "^3.0.0" 1090 | strip-ansi "^6.0.1" 1091 | 1092 | string_decoder@^1.1.1: 1093 | version "1.3.0" 1094 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1095 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1096 | dependencies: 1097 | safe-buffer "~5.2.0" 1098 | 1099 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1100 | version "6.0.1" 1101 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1102 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1103 | dependencies: 1104 | ansi-regex "^5.0.1" 1105 | 1106 | supports-color@^5.5.0: 1107 | version "5.5.0" 1108 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1109 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1110 | dependencies: 1111 | has-flag "^3.0.0" 1112 | 1113 | supports-color@^7.1.0: 1114 | version "7.2.0" 1115 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1116 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1117 | dependencies: 1118 | has-flag "^4.0.0" 1119 | 1120 | supports-color@^8.1.0: 1121 | version "8.1.1" 1122 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1123 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1124 | dependencies: 1125 | has-flag "^4.0.0" 1126 | 1127 | supports-preserve-symlinks-flag@^1.0.0: 1128 | version "1.0.0" 1129 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1130 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1131 | 1132 | tarn@^3.0.2: 1133 | version "3.0.2" 1134 | resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" 1135 | integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== 1136 | 1137 | tildify@2.0.0: 1138 | version "2.0.0" 1139 | resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a" 1140 | integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw== 1141 | 1142 | to-regex-range@^5.0.1: 1143 | version "5.0.1" 1144 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1145 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1146 | dependencies: 1147 | is-number "^7.0.0" 1148 | 1149 | toidentifier@1.0.1: 1150 | version "1.0.1" 1151 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" 1152 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 1153 | 1154 | touch@^3.1.0: 1155 | version "3.1.0" 1156 | resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" 1157 | integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== 1158 | dependencies: 1159 | nopt "~1.0.10" 1160 | 1161 | tree-kill@^1.2.2: 1162 | version "1.2.2" 1163 | resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" 1164 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 1165 | 1166 | ts-toolbelt@^6.15.1: 1167 | version "6.15.5" 1168 | resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz#cb3b43ed725cb63644782c64fbcad7d8f28c0a83" 1169 | integrity sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A== 1170 | 1171 | tslib@^2.1.0: 1172 | version "2.4.0" 1173 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" 1174 | integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== 1175 | 1176 | tstl@^2.0.7: 1177 | version "2.5.8" 1178 | resolved "https://registry.yarnpkg.com/tstl/-/tstl-2.5.8.tgz#8d5eb81573bb01eb4f1603d0f7bb1668a2faa7e7" 1179 | integrity sha512-NtwB4wQA0QQOqVYq+AEx9d8BlKGjFKHTf24XJlWmUkIQ4o7QOl4ecwrfWzx+bAbUu2KdNb/2iNgCyHJKvEuwXw== 1180 | 1181 | type-is@~1.6.18: 1182 | version "1.6.18" 1183 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 1184 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 1185 | dependencies: 1186 | media-typer "0.3.0" 1187 | mime-types "~2.1.24" 1188 | 1189 | type@^1.0.1: 1190 | version "1.2.0" 1191 | resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" 1192 | integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== 1193 | 1194 | type@^2.7.2: 1195 | version "2.7.2" 1196 | resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" 1197 | integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== 1198 | 1199 | typedarray-to-buffer@^3.1.5: 1200 | version "3.1.5" 1201 | resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" 1202 | integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== 1203 | dependencies: 1204 | is-typedarray "^1.0.0" 1205 | 1206 | typescript@4.8.2: 1207 | version "4.8.2" 1208 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790" 1209 | integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw== 1210 | 1211 | undefsafe@^2.0.5: 1212 | version "2.0.5" 1213 | resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" 1214 | integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== 1215 | 1216 | unpipe@1.0.0, unpipe@~1.0.0: 1217 | version "1.0.0" 1218 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 1219 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== 1220 | 1221 | utf-8-validate@^5.0.2: 1222 | version "5.0.9" 1223 | resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3" 1224 | integrity sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q== 1225 | dependencies: 1226 | node-gyp-build "^4.3.0" 1227 | 1228 | util-deprecate@^1.0.1: 1229 | version "1.0.2" 1230 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1231 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1232 | 1233 | utils-merge@1.0.1: 1234 | version "1.0.1" 1235 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 1236 | integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== 1237 | 1238 | uuid@8.3.2: 1239 | version "8.3.2" 1240 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 1241 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 1242 | 1243 | vary@~1.1.2: 1244 | version "1.1.2" 1245 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 1246 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== 1247 | 1248 | websocket-polyfill@0.0.3: 1249 | version "0.0.3" 1250 | resolved "https://registry.yarnpkg.com/websocket-polyfill/-/websocket-polyfill-0.0.3.tgz#7321ada0f5f17516290ba1cb587ac111b74ce6a5" 1251 | integrity sha512-pF3kR8Uaoau78MpUmFfzbIRxXj9PeQrCuPepGE6JIsfsJ/o/iXr07Q2iQNzKSSblQJ0FiGWlS64N4pVSm+O3Dg== 1252 | dependencies: 1253 | tstl "^2.0.7" 1254 | websocket "^1.0.28" 1255 | 1256 | websocket@^1.0.28: 1257 | version "1.0.34" 1258 | resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" 1259 | integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== 1260 | dependencies: 1261 | bufferutil "^4.0.1" 1262 | debug "^2.2.0" 1263 | es5-ext "^0.10.50" 1264 | typedarray-to-buffer "^3.1.5" 1265 | utf-8-validate "^5.0.2" 1266 | yaeti "^0.0.6" 1267 | 1268 | wrap-ansi@^7.0.0: 1269 | version "7.0.0" 1270 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1271 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1272 | dependencies: 1273 | ansi-styles "^4.0.0" 1274 | string-width "^4.1.0" 1275 | strip-ansi "^6.0.0" 1276 | 1277 | xtend@^4.0.0: 1278 | version "4.0.2" 1279 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 1280 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 1281 | 1282 | y18n@^5.0.5: 1283 | version "5.0.8" 1284 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1285 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1286 | 1287 | yaeti@^0.0.6: 1288 | version "0.0.6" 1289 | resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" 1290 | integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== 1291 | 1292 | yargs-parser@^21.0.0: 1293 | version "21.1.1" 1294 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" 1295 | integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== 1296 | 1297 | yargs@^17.3.1: 1298 | version "17.5.1" 1299 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" 1300 | integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== 1301 | dependencies: 1302 | cliui "^7.0.2" 1303 | escalade "^3.1.1" 1304 | get-caller-file "^2.0.5" 1305 | require-directory "^2.1.1" 1306 | string-width "^4.2.3" 1307 | y18n "^5.0.5" 1308 | yargs-parser "^21.0.0" 1309 | --------------------------------------------------------------------------------