From 138bb6a82691000cf9b7307df43297aa180a006e Mon Sep 17 00:00:00 2001 From: Hubert Walczak Date: Tue, 14 May 2024 13:36:16 +0200 Subject: [PATCH] updated rollup --- .eslintignore | 2 - __tests__/index.ts | 30 +- eslint.config.js | 25 + jest.config.js | 6 + jest.config.ts => jest.confisg.ts | 5 +- lib/cjs/csgo.d.ts | 185 -- lib/cjs/events.d.ts | 38 - lib/cjs/index.d.ts | 131 -- lib/cjs/index.js | 387 ---- lib/cjs/interfaces.d.ts | 23 - lib/cjs/mirv.d.ts | 54 - lib/cjs/package.json | 1 - lib/cjs/parsed.d.ts | 190 -- lib/cjs/utils.d.ts | 55 - lib/cjs/utils.js | 123 -- lib/esm/csgo.d.ts | 185 -- lib/esm/events.d.ts | 38 - lib/esm/index.d.ts | 131 -- lib/esm/index.js | 379 ---- lib/esm/interfaces.d.ts | 23 - lib/esm/mirv.d.ts | 54 - lib/esm/parsed.d.ts | 190 -- lib/esm/utils.d.ts | 55 - lib/esm/utils.js | 114 -- lib/index.d.mts | 541 ++++++ lib/index.d.ts | 541 ++++++ lib/index.js | 545 ++++++ lib/index.mjs | 514 ++++++ package-lock.json | 2806 +++++++++++++++++++++++++---- package.json | 34 +- tsc/index.ts | 32 +- tsc/utils.ts | 8 +- tsconfig.esm.json | 17 - tsconfig.json | 34 +- types/csgo.d.ts | 151 -- types/events.d.ts | 38 - types/index.d.ts | 120 -- types/interfaces.d.ts | 23 - types/mirv.d.ts | 54 - types/parsed.d.ts | 153 -- types/utils.d.ts | 46 - 41 files changed, 4680 insertions(+), 3401 deletions(-) delete mode 100644 .eslintignore create mode 100644 eslint.config.js create mode 100644 jest.config.js rename jest.config.ts => jest.confisg.ts (68%) delete mode 100644 lib/cjs/csgo.d.ts delete mode 100644 lib/cjs/events.d.ts delete mode 100644 lib/cjs/index.d.ts delete mode 100644 lib/cjs/index.js delete mode 100644 lib/cjs/interfaces.d.ts delete mode 100644 lib/cjs/mirv.d.ts delete mode 100644 lib/cjs/package.json delete mode 100644 lib/cjs/parsed.d.ts delete mode 100644 lib/cjs/utils.d.ts delete mode 100644 lib/cjs/utils.js delete mode 100644 lib/esm/csgo.d.ts delete mode 100644 lib/esm/events.d.ts delete mode 100644 lib/esm/index.d.ts delete mode 100644 lib/esm/index.js delete mode 100644 lib/esm/interfaces.d.ts delete mode 100644 lib/esm/mirv.d.ts delete mode 100644 lib/esm/parsed.d.ts delete mode 100644 lib/esm/utils.d.ts delete mode 100644 lib/esm/utils.js create mode 100644 lib/index.d.mts create mode 100644 lib/index.d.ts create mode 100644 lib/index.js create mode 100644 lib/index.mjs delete mode 100644 tsconfig.esm.json delete mode 100644 types/csgo.d.ts delete mode 100644 types/events.d.ts delete mode 100644 types/index.d.ts delete mode 100644 types/interfaces.d.ts delete mode 100644 types/mirv.d.ts delete mode 100644 types/parsed.d.ts delete mode 100644 types/utils.d.ts diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 9a357a0..0000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.github \ No newline at end of file diff --git a/__tests__/index.ts b/__tests__/index.ts index 7f1facd..3ff4cd5 100644 --- a/__tests__/index.ts +++ b/__tests__/index.ts @@ -1,5 +1,4 @@ -import { - CSGOGSI, +import type { CSGORaw, DecoySmokeGrenade, Events, @@ -10,7 +9,8 @@ import { PlayerRaw, TeamExtension } from '../tsc'; -import { Callback } from '../tsc/events'; +import { CSGOGSI } from '../tsc'; +import type { Callback } from '../tsc/events'; import { createGSIPacket, createHurtPacket, createKillPacket } from './data'; import { testCases } from './data/bombSites'; @@ -331,9 +331,9 @@ test('data > rounds: proper parser in 1st half', () => { expect(data).not.toBeNull(); expect(data?.map.rounds.length).toBe(3); - expect(data?.map.rounds[0].round).toBe(1); - expect(data?.map.rounds[1].side).toBe('CT'); - expect(data?.map.rounds[2].team.side).toBe('T'); + expect(data?.map.rounds[0]?.round).toBe(1); + expect(data?.map.rounds[1]?.side).toBe('CT'); + expect(data?.map.rounds[2]?.team.side).toBe('T'); }); test('data > rounds: proper parser in 2nd half', () => { @@ -378,12 +378,12 @@ test('data > rounds: proper parser in 2nd half', () => { expect(data).not.toBeNull(); expect(data?.map.rounds.length).toBe(23); - expect(data?.map.rounds[0].side).not.toBe(data?.map.rounds[0].team.side); - expect(data?.map.rounds[5].side).not.toBe(data?.map.rounds[5].team.side); - expect(data?.map.rounds[10].side).not.toBe(data?.map.rounds[10].team.side); - expect(data?.map.rounds[18].side).toBe(data?.map.rounds[18].team.side); - expect(data?.map.rounds[20].side).toBe(data?.map.rounds[20].team.side); - expect(data?.map.rounds[21].side).toBe(data?.map.rounds[21].team.side); + expect(data?.map.rounds[0]?.side).not.toBe(data?.map.rounds[0]?.team.side); + expect(data?.map.rounds[5]?.side).not.toBe(data?.map.rounds[5]?.team.side); + expect(data?.map.rounds[10]?.side).not.toBe(data?.map.rounds[10]?.team.side); + expect(data?.map.rounds[18]?.side).toBe(data?.map.rounds[18]?.team.side); + expect(data?.map.rounds[20]?.side).toBe(data?.map.rounds[20]?.team.side); + expect(data?.map.rounds[21]?.side).toBe(data?.map.rounds[21]?.team.side); }); test('data > rounds: parser doesnt throw on wrong round wins list', () => { @@ -430,9 +430,9 @@ test('data > rounds: parser correctly gets just ended round', () => { ); expect(data?.map.rounds.length).toBe(4); - expect(data?.map.rounds[3].side).toBe('T'); - expect(data?.map.rounds[3].round).toBe(4); - expect(data?.map.rounds[3].outcome).toBe('t_win_elimination'); + expect(data?.map.rounds[3]?.side).toBe('T'); + expect(data?.map.rounds[3]?.round).toBe(4); + expect(data?.map.rounds[3]?.outcome).toBe('t_win_elimination'); }); test('data > player: dont assign observer if cant find', () => { diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..4791af3 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,25 @@ +const eslint = require('@eslint/js'); +const tseslint = require('typescript-eslint'); + +module.exports = tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + files: ["tsc/*.ts"], + rules:{ + "no-console": 1, + "@typescript-eslint/explicit-module-boundary-types": 0, + "@typescript-eslint/ban-types": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-empty-function":0, + "no-empty": 0, + "@typescript-eslint/no-var-requires":0, + "no-mixed-spaces-and-tabs": ["warn", "smart-tabs"], + "@typescript-eslint/explicit-function-return-type":0, + "@typescript-eslint/camelcase":0 + }, + }, + { + ignores: ["types/*", "lib/*", "__tests__", "eslint.config.js"] + } +); \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..b0ce9fc --- /dev/null +++ b/jest.config.js @@ -0,0 +1,6 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + modulePathIgnorePatterns: ['/__tests__/data/'], +}; \ No newline at end of file diff --git a/jest.config.ts b/jest.confisg.ts similarity index 68% rename from jest.config.ts rename to jest.confisg.ts index 98782b2..e27397c 100644 --- a/jest.config.ts +++ b/jest.confisg.ts @@ -1,7 +1,8 @@ -export default { +module.exports = { preset: 'ts-jest', testEnvironment: 'node', modulePathIgnorePatterns: ['/__tests__/data/'], coverageReporters: ['json-summary', 'text', 'lcov'], - resolver: 'jest-ts-webcompat-resolver' + resolver: 'jest-ts-webcompat-resolver', + useESM: true }; diff --git a/lib/cjs/csgo.d.ts b/lib/cjs/csgo.d.ts deleted file mode 100644 index 6f05e53..0000000 --- a/lib/cjs/csgo.d.ts +++ /dev/null @@ -1,185 +0,0 @@ -export type Side = 'CT' | 'T'; -export type RoundOutcome = 'ct_win_elimination' | 't_win_elimination' | 'ct_win_time' | 'ct_win_defuse' | 't_win_bomb'; - -export type WeaponType = - | 'Knife' - | 'Pistol' - | 'Grenade' - | 'Rifle' - | 'SniperRifle' - | 'C4' - | 'Submachine Gun' - | 'Shotgun' - | 'Machine Gun'; - -export interface WeaponRaw { - name: string; - paintkit: string; - type?: WeaponType; - ammo_clip?: number; - ammo_clip_max?: number; - ammo_reserve?: number; - state: 'active' | 'holstered'; -} - -export interface TeamRaw { - score: number; - consecutive_round_losses: number; - timeouts_remaining: number; - matches_won_this_series: number; - name?: string; - flag?: string; -} - -export interface PlayerRaw { - steamid?: string; - name: string; - clan?: string; - observer_slot?: number; - team: Side; - match_stats: { - kills: number; - assists: number; - deaths: number; - mvps: number; - score: number; - }; - weapons: { - [key: string]: WeaponRaw; - }; - state: { - health: number; - armor: number; - helmet: boolean; - defusekit?: boolean; - flashed: number; - smoked?: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - }; - position: string; - forward: string; -} - -export interface PlayerObservedRaw { - steamid: string; - clan?: string; - name: string; - observer_slot?: number; - team?: Side; - activity: 'playing' | 'textinput' | 'menu'; - state: { - health: number; - armor: number; - helmet: boolean; - flashed: number; - smoked: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - }; - spectarget: 'free' | string; - position: string; - forward: string; -} - -export interface PlayersRaw { - [key: string]: PlayerRaw; -} - -export interface Provider { - name: 'Counter-Strike: Global Offensive'; - appid: 730; - version: number; - steamid: string; - timestamp: number; -} - -export interface MapRaw { - mode: 'competitive'; - name: string; - phase: 'warmup' | 'live' | 'intermission' | 'gameover'; - round: number; - team_ct: TeamRaw; - team_t: TeamRaw; - num_matches_to_win_series: number; - current_spectators: number; - souvenirs_total: number; - round_wins: { - [key: string]: RoundOutcome; - }; -} - -export interface RoundRaw { - phase: 'freezetime' | 'live' | 'over'; - bomb?: 'planted' | 'exploded' | 'defused'; - win_team?: Side; -} - -export interface BombRaw { - state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; - countdown?: string; - player?: string; - position: string; -} -export interface PhaseRaw { - phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; - phase_ends_in: string; -} - -export interface GrenadeBaseRaw { - owner: string; - lifetime: string; -} - -export interface DecoySmokeGrenadeRaw extends GrenadeBaseRaw { - position: string; - velocity: string; - type: 'decoy' | 'smoke'; - effecttime: string; -} - -export interface FragOrFireBombOrFlashbandGrenadeRaw extends GrenadeBaseRaw { - position: string; - type: 'frag' | 'firebomb' | 'flashbang'; - velocity: string; -} - -export interface InfernoGrenadeRaw extends GrenadeBaseRaw { - type: 'inferno'; - flames: { [key: string]: string }; -} - -export type GrenadeRaw = DecoySmokeGrenadeRaw | FragOrFireBombOrFlashbandGrenadeRaw | InfernoGrenadeRaw; - -export interface CSGORaw { - provider: Provider; - map?: MapRaw; - round?: RoundRaw; - player?: PlayerObservedRaw; - allplayers?: PlayersRaw; - bomb?: BombRaw; - grenades?: { - [key: string]: GrenadeRaw; - /*{ - owner:number, - position:string, - velocity:string, - lifetime:string, - type:string, - effecttime?:string - }*/ - }; - previously?: any; - phase_countdowns?: PhaseRaw; - auth?: { - token: string; - }; -} diff --git a/lib/cjs/events.d.ts b/lib/cjs/events.d.ts deleted file mode 100644 index 1e83240..0000000 --- a/lib/cjs/events.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as I from './interfaces'; - -export interface Events { - raw: (data: I.CSGORaw) => void; - data: (data: I.CSGO) => void; - roundEnd: (team: I.Score) => void; - matchEnd: (score: I.Score) => void; - kill: (kill: I.KillEvent) => void; - hurt: (kill: I.HurtEvent) => void; - timeoutStart: (team: any) => void; - timeoutEnd: () => void; - /*roundStart: (round: number) => void, - warmupStart: () => void, - warmupEnd: () => void,*/ - mvp: (player: I.Player) => void; - freezetimeStart: () => void; - freezetimeEnd: () => void; - intermissionStart: () => void; - intermissionEnd: () => void; - defuseStart: (player: I.Player) => void; - defuseStop: (player: I.Player) => void; - bombPlantStart: (player: I.Player) => void; - bombPlant: (player: I.Player) => void; - bombExplode: () => void; - bombDefuse: (player: I.Player) => void; - newListener: (eventName: K, listener: Events[K]) => void; - removeListener: (eventName: K, listener: Events[K]) => void; -} - -export type AnyEventName = T | (string & {}); - -export type BaseEvents = keyof Events; - -export type EventNames = AnyEventName; - -export type EmptyListener = () => void; - -export type Callback = K extends BaseEvents ? Events[K] | EmptyListener : EmptyListener; diff --git a/lib/cjs/index.d.ts b/lib/cjs/index.d.ts deleted file mode 100644 index 62883e3..0000000 --- a/lib/cjs/index.d.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { - CSGO, - CSGORaw, - Events, - KillEvent, - PlayerExtension, - RawKill, - Score, - TeamExtension, - Callback, - EventNames, - BaseEvents -} from './interfaces'; -import { RawHurt } from './mirv'; -import { DigestMirvType, HurtEvent } from './parsed'; -import { mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound } from './utils.js'; -interface EventDescriptor { - listener: Events[BaseEvents]; - once: boolean; -} -declare type RoundPlayerDamage = { - steamid: string; - damage: number; -}; -declare type RoundDamage = { - round: number; - players: RoundPlayerDamage[]; -}; -declare class CSGOGSI { - private descriptors; - private maxListeners; - teams: { - left: TeamExtension | null; - right: TeamExtension | null; - }; - damage: RoundDamage[]; - players: PlayerExtension[]; - overtimeMR: number; - regulationMR: number; - last?: CSGO; - current?: CSGO; - constructor(); - eventNames: () => EventNames[]; - getMaxListeners: () => number; - listenerCount: (eventName: EventNames) => number; - listeners: ( - eventName: EventNames - ) => ( - | ((data: CSGORaw) => void) - | ((data: CSGO) => void) - | ((team: Score) => void) - | ((score: Score) => void) - | ((kill: KillEvent) => void) - | ((kill: HurtEvent) => void) - | ((team: any) => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | (() => void) - | (() => void) - | (() => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | ((eventName: K, listener: Events[K]) => void) - | ((eventName: K_1, listener: Events[K_1]) => void) - )[]; - removeListener: (eventName: K, listener: Callback) => this; - off: (eventName: K, listener: Callback) => this; - addListener: (eventName: K, listener: Callback) => this; - on: (eventName: K, listener: Callback) => this; - once: (eventName: K, listener: Callback) => this; - prependListener: (eventName: K, listener: Callback) => this; - emit: (eventName: EventNames, arg?: any, arg2?: any) => boolean; - prependOnceListener: (eventName: K, listener: Callback) => this; - removeAllListeners: (eventName: EventNames) => this; - setMaxListeners: (n: number) => this; - rawListeners: (eventName: EventNames) => EventDescriptor[]; - digest: (raw: CSGORaw) => CSGO | null; - digestMIRV: (raw: RawKill | RawHurt, eventType?: string) => DigestMirvType; - static findSite(mapName: string, position: number[]): 'A' | 'B' | null; -} -export { CSGOGSI, mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound, RoundDamage }; -export { - CSGO, - CSGORaw, - Side, - RoundOutcome, - WeaponType, - Observer, - RawHurt, - WeaponRaw, - TeamRaw, - PlayerRaw, - PlayerObservedRaw, - PlayersRaw, - Provider, - HurtEvent, - RoundWins, - MapRaw, - RoundRaw, - BombRaw, - PhaseRaw, - Events, - Team, - Player, - Bomb, - Map, - Round, - Score, - KillEvent, - RawKill, - TeamExtension, - RoundInfo, - PlayerExtension, - Orientation, - Grenade, - GrenadeBaseRaw, - GrenadeBase, - DecoySmokeGrenade, - DecoySmokeGrenadeRaw, - InfernoGrenade, - InfernoGrenadeRaw, - FragOrFireBombOrFlashbandGrenade, - FragOrFireBombOrFlashbandGrenadeRaw, - Weapon, - GrenadeRaw -} from './interfaces'; diff --git a/lib/cjs/index.js b/lib/cjs/index.js deleted file mode 100644 index 46af22d..0000000 --- a/lib/cjs/index.js +++ /dev/null @@ -1,387 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.didTeamWinThatRound = exports.getHalfFromRound = exports.parseTeam = exports.mapSteamIDToPlayer = exports.CSGOGSI = void 0; -const utils_js_1 = require("./utils.js"); -Object.defineProperty(exports, "mapSteamIDToPlayer", { enumerable: true, get: function () { return utils_js_1.mapSteamIDToPlayer; } }); -Object.defineProperty(exports, "parseTeam", { enumerable: true, get: function () { return utils_js_1.parseTeam; } }); -Object.defineProperty(exports, "getHalfFromRound", { enumerable: true, get: function () { return utils_js_1.getHalfFromRound; } }); -Object.defineProperty(exports, "didTeamWinThatRound", { enumerable: true, get: function () { return utils_js_1.didTeamWinThatRound; } }); -class CSGOGSI { - constructor() { - this.eventNames = () => { - const listeners = this.descriptors.entries(); - const nonEmptyEvents = []; - for (const entry of listeners) { - if (entry[1] && entry[1].length > 0) { - nonEmptyEvents.push(entry[0]); - } - } - return nonEmptyEvents; - }; - this.getMaxListeners = () => this.maxListeners; - this.listenerCount = (eventName) => { - const listeners = this.listeners(eventName); - return listeners.length; - }; - this.listeners = (eventName) => { - const descriptors = this.descriptors.get(eventName) || []; - return descriptors.map(descriptor => descriptor.listener); - }; - this.removeListener = (eventName, listener) => { - return this.off(eventName, listener); - }; - this.off = (eventName, listener) => { - const descriptors = this.descriptors.get(eventName) || []; - this.descriptors.set(eventName, descriptors.filter(descriptor => descriptor.listener !== listener)); - this.emit('removeListener', eventName, listener); - return this; - }; - this.addListener = (eventName, listener) => { - return this.on(eventName, listener); - }; - this.on = (eventName, listener) => { - this.emit('newListener', eventName, listener); - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.push({ listener, once: false }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.once = (eventName, listener) => { - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.push({ listener, once: true }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.prependListener = (eventName, listener) => { - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.unshift({ listener, once: false }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.emit = (eventName, arg, arg2) => { - const listeners = this.descriptors.get(eventName); - if (!listeners || listeners.length === 0) - return false; - listeners.forEach(listener => { - if (listener.once) { - this.descriptors.set(eventName, listeners.filter(listenerInArray => listenerInArray !== listener)); - } - listener.listener(arg, arg2); - }); - return true; - }; - this.prependOnceListener = (eventName, listener) => { - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.unshift({ listener, once: true }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.removeAllListeners = (eventName) => { - this.descriptors.set(eventName, []); - return this; - }; - this.setMaxListeners = (n) => { - this.maxListeners = n; - return this; - }; - this.rawListeners = (eventName) => { - return this.descriptors.get(eventName) || []; - }; - this.digest = (raw) => { - var _a, _b, _c, _d; - if (!raw.allplayers || !raw.map || !raw.phase_countdowns) { - return null; - } - this.emit('raw', raw); - let isCTLeft = true; - const examplePlayerT = Object.values(raw.allplayers).find(({ observer_slot, team }) => observer_slot !== undefined && team === 'T'); - const examplePlayerCT = Object.values(raw.allplayers).find(({ observer_slot, team }) => observer_slot !== undefined && team === 'CT'); - if (examplePlayerCT && - examplePlayerCT.observer_slot !== undefined && - examplePlayerT && - examplePlayerT.observer_slot !== undefined) { - if ((examplePlayerCT.observer_slot || 10) > (examplePlayerT.observer_slot || 10)) { - isCTLeft = false; - } - } - const bomb = raw.bomb; - const teamCT = (0, utils_js_1.parseTeam)(raw.map.team_ct, isCTLeft ? 'left' : 'right', 'CT', isCTLeft ? this.teams.left : this.teams.right); - const teamT = (0, utils_js_1.parseTeam)(raw.map.team_t, isCTLeft ? 'right' : 'left', 'T', isCTLeft ? this.teams.right : this.teams.left); - const playerMapper = (0, utils_js_1.mapSteamIDToPlayer)(raw.allplayers, { CT: teamCT, T: teamT }, this.players); - const players = Object.keys(raw.allplayers).map(playerMapper); - const observed = players.find(player => raw.player && player.steamid === raw.player.steamid) || null; - const observer = { - activity: (_a = raw.player) === null || _a === void 0 ? void 0 : _a.activity, - spectarget: (_b = raw.player) === null || _b === void 0 ? void 0 : _b.spectarget, - position: (_c = raw.player) === null || _c === void 0 ? void 0 : _c.position.split(', ').map(n => Number(n)), - forward: (_d = raw.player) === null || _d === void 0 ? void 0 : _d.forward.split(', ').map(n => Number(n)) - }; - const rounds = []; - if (raw.round && raw.map && raw.map.round_wins) { - let currentRound = raw.map.round + 1; - if (raw.round && raw.round.phase === 'over') { - currentRound = raw.map.round; - } - for (let i = 1; i <= currentRound; i++) { - const result = (0, utils_js_1.getRoundWin)(currentRound, { ct: teamCT, t: teamT }, raw.map.round_wins, i, this.regulationMR, this.overtimeMR); - if (!result) - continue; - rounds.push(result); - } - } - if (this.last && this.last.map.name !== raw.map.name) { - this.damage = []; - } - let currentRoundForDamage = raw.map.round + 1; - if (raw.round && raw.round.phase === 'over') { - currentRoundForDamage = raw.map.round; - } - let currentRoundDamage = this.damage.find(damage => damage.round === currentRoundForDamage); - if (!currentRoundDamage) { - currentRoundDamage = { - round: currentRoundForDamage, - players: [] - }; - this.damage.push(currentRoundDamage); - } - if ((raw.map.round === 0 && raw.phase_countdowns.phase === 'freezetime') || - raw.phase_countdowns.phase === 'warmup') { - this.damage = []; - } - currentRoundDamage.players = players.map(player => ({ - steamid: player.steamid, - damage: player.state.round_totaldmg - })); - for (const player of players) { - const { current, damage } = this; - if (!current) - continue; - const damageForRound = damage.filter(damageEntry => damageEntry.round < currentRoundForDamage); - if (damageForRound.length === 0) - continue; - //damagex.players.find(player => player.steamid === steamid).damage - const damageEntries = damageForRound.map(damageEntry => { - const playerDamageEntry = damageEntry.players.find(playerDamage => playerDamage.steamid === player.steamid); - return playerDamageEntry ? playerDamageEntry.damage : 0; - }); - const adr = damageEntries.reduce((a, b) => a + b, 0) / (raw.map.round || 1); - player.state.adr = Math.floor(adr); - } - const data = { - provider: raw.provider, - observer, - round: raw.round - ? { - phase: raw.round.phase, - bomb: raw.round.bomb, - win_team: raw.round.win_team - } - : null, - player: observed, - players: players, - bomb: bomb - ? { - state: bomb.state, - countdown: bomb.countdown ? parseFloat(bomb.countdown) : undefined, - position: bomb.position.split(', ').map(pos => parseFloat(pos)), - player: players.find(player => player.steamid === bomb.player) || undefined, - site: bomb.state === 'planted' || - bomb.state === 'defused' || - bomb.state === 'defusing' || - bomb.state === 'planting' - ? CSGOGSI.findSite(raw.map.name, bomb.position.split(', ').map(n => parseFloat(n))) - : null - } - : null, - grenades: (0, utils_js_1.parseGrenades)(raw.grenades), - phase_countdowns: { - phase: raw.phase_countdowns.phase, - phase_ends_in: parseFloat(raw.phase_countdowns.phase_ends_in) - }, - auth: raw.auth, - map: { - mode: raw.map.mode, - name: raw.map.name, - phase: raw.map.phase, - round: raw.map.round, - team_ct: teamCT, - team_t: teamT, - num_matches_to_win_series: raw.map.num_matches_to_win_series, - current_spectators: raw.map.current_spectators, - souvenirs_total: raw.map.souvenirs_total, - round_wins: raw.map.round_wins, - rounds - } - }; - this.current = data; - if (!this.last) { - this.last = data; - this.emit('data', data); - return data; - } - const last = this.last; - // Round end - if (last.round && data.round && data.round.win_team && !last.round.win_team) { - const winner = data.round.win_team === 'CT' ? data.map.team_ct : data.map.team_t; - const loser = data.round.win_team === 'CT' ? data.map.team_t : data.map.team_ct; - const oldWinner = data.round.win_team === 'CT' ? last.map.team_ct : last.map.team_t; - if (winner.score === oldWinner.score) { - winner.score += 1; - } - const roundScore = { - winner, - loser, - map: data.map, - mapEnd: data.map.phase === 'gameover' - }; - this.emit('roundEnd', roundScore); - // Match end - if (roundScore.mapEnd && last.map.phase !== 'gameover') { - this.emit('matchEnd', roundScore); - } - } - //Bomb actions - if (last.bomb && data.bomb) { - if (last.bomb.state === 'planting' && data.bomb.state === 'planted') { - this.emit('bombPlant', last.bomb.player); - } - else if (last.bomb.state !== 'exploded' && data.bomb.state === 'exploded') { - this.emit('bombExplode'); - } - else if (last.bomb.state !== 'defused' && data.bomb.state === 'defused') { - this.emit('bombDefuse', last.bomb.player); - } - else if (last.bomb.state !== 'defusing' && data.bomb.state === 'defusing') { - this.emit('defuseStart', data.bomb.player); - } - else if (last.bomb.state === 'defusing' && data.bomb.state !== 'defusing') { - this.emit('defuseStop', last.bomb.player); - } - else if (last.bomb.state !== 'planting' && data.bomb.state === 'planting') { - this.emit('bombPlantStart', last.bomb.player); - } - } - // Intermission (between halfs) - if (data.map.phase === 'intermission' && last.map.phase !== 'intermission') { - this.emit('intermissionStart'); - } - else if (data.map.phase !== 'intermission' && last.map.phase === 'intermission') { - this.emit('intermissionEnd'); - } - const { phase } = data.phase_countdowns; - // Freezetime (between round end & start) - if (phase === 'freezetime' && last.phase_countdowns.phase !== 'freezetime') { - this.emit('freezetimeStart'); - } - else if (phase !== 'freezetime' && last.phase_countdowns.phase === 'freezetime') { - this.emit('freezetimeEnd'); - } - // Timeouts - if (phase && last.phase_countdowns.phase) { - if (phase.startsWith('timeout') && !last.phase_countdowns.phase.startsWith('timeout')) { - const team = phase === 'timeout_ct' ? teamCT : teamT; - this.emit('timeoutStart', team); - } - else if (last.phase_countdowns.phase.startsWith('timeout') && !phase.startsWith('timeout')) { - this.emit('timeoutEnd'); - } - } - const mvp = data.players.find(player => { - const previousData = last.players.find(previousPlayer => previousPlayer.steamid === player.steamid); - if (!previousData) - return false; - if (player.stats.mvps > previousData.stats.mvps) - return true; - return false; - }) || null; - if (mvp) { - this.emit('mvp', mvp); - } - this.emit('data', data); - this.last = data; - return data; - }; - this.digestMIRV = (raw, eventType = 'player_death') => { - if (eventType === 'player_death') { - const rawKill = raw; - if (!this.last) { - return null; - } - const data = rawKill.keys; - const killer = this.last.players.find(player => player.steamid === data.attacker.xuid); - const victim = this.last.players.find(player => player.steamid === data.userid.xuid); - const assister = this.last.players.find(player => player.steamid === data.assister.xuid && data.assister.xuid !== '0'); - if (!victim) { - return null; - } - const kill = { - killer: killer || (data.weapon === 'trigger_hurt' || data.weapon === 'worldspawn' ? victim : null), - victim, - assister: assister || null, - flashed: data.assistedflash, - headshot: data.headshot, - weapon: data.weapon, - wallbang: data.penetrated > 0, - attackerblind: data.attackerblind, - thrusmoke: data.thrusmoke, - noscope: data.noscope, - attackerinair: data.attackerinair - }; - this.emit('kill', kill); - return kill; - } - const rawHurt = raw; - if (!this.last) { - return null; - } - const data = rawHurt.keys; - const attacker = this.last.players.find(player => player.steamid === data.attacker.xuid); - const victim = this.last.players.find(player => player.steamid === data.userid.xuid); - if (!attacker || !victim) { - return null; - } - const kill = { - attacker, - victim, - health: data.health, - armor: data.armor, - weapon: data.weapon, - dmg_health: data.dmg_health, - dmg_armor: data.dmg_armor, - hitgroup: data.hitgroup - }; - this.emit('hurt', kill); - return kill; - }; - this.descriptors = new Map(); - this.teams = { - left: null, - right: null - }; - this.maxListeners = 10; - this.players = []; - this.overtimeMR = 3; - this.regulationMR = 15; - this.damage = []; - } - static findSite(mapName, position) { - const realMapName = mapName.substr(mapName.lastIndexOf('/') + 1); - const mapReference = { - de_mirage: position => (position[1] < -600 ? 'A' : 'B'), - de_cache: position => (position[1] > 0 ? 'A' : 'B'), - de_overpass: position => (position[2] > 400 ? 'A' : 'B'), - de_nuke: position => (position[2] > -500 ? 'A' : 'B'), - de_dust2: position => (position[0] > -500 ? 'A' : 'B'), - de_inferno: position => (position[0] > 1400 ? 'A' : 'B'), - de_vertigo: position => (position[0] > -1400 ? 'A' : 'B'), - de_train: position => (position[1] > -450 ? 'A' : 'B'), - de_ancient: position => (position[0] < -500 ? 'A' : 'B'), - de_anubis: position => (position[0] > 0 ? 'A' : 'B') - }; - if (realMapName in mapReference) { - return mapReference[realMapName](position); - } - return null; - } -} -exports.CSGOGSI = CSGOGSI; diff --git a/lib/cjs/interfaces.d.ts b/lib/cjs/interfaces.d.ts deleted file mode 100644 index 432580a..0000000 --- a/lib/cjs/interfaces.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -export * from './csgo'; -export * from './events'; -export * from './parsed'; -export * from './mirv'; - -export interface TeamExtension { - id: string; - name: string; - country: string | null; - logo: string | null; - map_score: number; - extra: Record; -} - -export interface PlayerExtension { - id: string; - name: string; - steamid: string; - realName: string | null; - country: string | null; - avatar: string | null; - extra: Record; -} diff --git a/lib/cjs/mirv.d.ts b/lib/cjs/mirv.d.ts deleted file mode 100644 index 96018b7..0000000 --- a/lib/cjs/mirv.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -export interface RawKill { - name: 'player_death'; - clientTime: number; - keys: { - userid: { - value: number; - xuid: string; - }; - attacker: { - value: number; - xuid: string; - }; - assister: { - value: number; - xuid: string; - }; - assistedflash: boolean; - weapon: string; - weapon_itemid: string; - weapon_fauxitemid: string; - weapon_originalowner_xuid: string; - headshot: boolean; - dominated: number; - revenge: number; - wipe: number; - attackerblind: boolean; - thrusmoke: boolean; - noscope: boolean; - penetrated: number; - noreplay: boolean; - attackerinair: boolean; - }; -} - -export interface RawHurt { - name: 'player_hurt'; - clientTime: number; - keys: { - userid: { - value: number; - xuid: string; - }; - attacker: { - value: number; - xuid: string; - }; - health: number; - armor: number; - weapon: string; - dmg_health: number; - dmg_armor: number; - hitgroup: number; - }; -} diff --git a/lib/cjs/package.json b/lib/cjs/package.json deleted file mode 100644 index 7156107..0000000 --- a/lib/cjs/package.json +++ /dev/null @@ -1 +0,0 @@ -{"type": "commonjs"} \ No newline at end of file diff --git a/lib/cjs/parsed.d.ts b/lib/cjs/parsed.d.ts deleted file mode 100644 index f694d76..0000000 --- a/lib/cjs/parsed.d.ts +++ /dev/null @@ -1,190 +0,0 @@ -import * as I from './interfaces'; - -export type Orientation = 'left' | 'right'; - -export interface Team { - logo: string | null; - score: number; - consecutive_round_losses: number; - timeouts_remaining: number; - matches_won_this_series: number; - side: I.Side; - name: string; - country: string | null; - id: string | null; - orientation: Orientation; - extra: Record; -} - -export interface RoundInfo { - team: Team; - round: number; - side: I.Side; - outcome: I.RoundOutcome; -} -export interface Weapon { - name: string; - paintkit: string; - type?: I.WeaponType; - ammo_clip?: number; - ammo_clip_max?: number; - ammo_reserve?: number; - state: 'active' | 'holstered'; - id: string; -} - -export interface Player { - steamid: string; - name: string; - defaultName: string; - clan?: string; - observer_slot?: number; - team: Team; - stats: { - kills: number; - assists: number; - deaths: number; - mvps: number; - score: number; - }; - weapons: Weapon[]; - state: { - health: number; - armor: number; - helmet: boolean; - defusekit?: boolean; - flashed: number; - smoked: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - adr: number; - }; - position: number[]; - forward: number[]; - avatar: string | null; - country: string | null; - realName: string | null; - extra: Record; -} - -export type RoundWins = { - [key: string]: I.RoundOutcome; -}; -export interface Bomb { - state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; - countdown?: number; - player?: Player; - site: 'A' | 'B' | null; - position: number[]; -} - -export interface Map { - mode: string; - name: string; - phase: 'warmup' | 'live' | 'intermission' | 'gameover'; - round: number; - team_ct: Team; - team_t: Team; - num_matches_to_win_series: number; - current_spectators: number; - souvenirs_total: number; - round_wins: RoundWins; - rounds: I.RoundInfo[]; -} - -export interface Round { - phase: 'freezetime' | 'live' | 'over'; - bomb?: 'planted' | 'exploded' | 'defused'; - win_team?: I.Side; -} - -export interface Observer { - activity?: 'playing' | 'textinput' | 'menu'; - spectarget?: 'free' | (string & {}); - position?: number[]; - forward?: number[]; -} - -export interface GrenadeBase { - id: string; - owner: string; - lifetime: number; -} - -export interface DecoySmokeGrenade extends GrenadeBase { - position: number[]; - velocity: number[]; - type: 'decoy' | 'smoke'; - effecttime: number; -} - -export interface FragOrFireBombOrFlashbandGrenade extends GrenadeBase { - position: number[]; - type: 'frag' | 'firebomb' | 'flashbang'; - velocity: number[]; -} - -export interface InfernoGrenade extends GrenadeBase { - type: 'inferno'; - flames: { id: string; position: number[] }[]; -} - -export type Grenade = DecoySmokeGrenade | FragOrFireBombOrFlashbandGrenade | InfernoGrenade; - -export interface Phase { - phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; - phase_ends_in: number; -} -export interface CSGO { - provider: I.Provider; - map: Map; - round: Round | null; - observer: Observer; - player: Player | null; - players: Player[]; - bomb: Bomb | null; - grenades: Grenade[]; - previously?: any; - phase_countdowns: I.Phase; - auth?: { - token: string; - }; -} -export interface Score { - winner: I.Team; - loser: I.Team; - map: Map; - mapEnd: boolean; -} - -export interface KillEvent { - killer: Player | null; - victim: Player; - assister: Player | null; - flashed: boolean; - headshot: boolean; - weapon: string; - wallbang: boolean; - attackerblind: boolean; - thrusmoke: boolean; - noscope: boolean; - attackerinair: boolean; -} - -export interface HurtEvent { - attacker: Player; - victim: Player; - health: number; - armor: number; - weapon: string; - dmg_health: number; - dmg_armor: number; - hitgroup: number; -} - -//export type DigestMirvType = ((kill: RawKill, eventType: 'player_death') => KillEvent | null) | ((hurt: RawHurt, eventType: 'player_hurt') => HurtEvent | null) -export type DigestMirvType = KillEvent | HurtEvent | null; diff --git a/lib/cjs/utils.d.ts b/lib/cjs/utils.d.ts deleted file mode 100644 index e8b9464..0000000 --- a/lib/cjs/utils.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - Team, - PlayerExtension, - Player, - PlayersRaw, - Side, - Orientation, - TeamExtension, - TeamRaw, - RoundInfo, - RoundWins -} from '.'; -import { GrenadeRaw } from './csgo'; -import { Grenade } from './parsed'; -export declare const mapSteamIDToPlayer: ( - players: PlayersRaw, - teams: { - CT: Team; - T: Team; - }, - extensions: PlayerExtension[] -) => (steamid: string) => Player; -export declare const parseTeam: ( - team: TeamRaw, - orientation: Orientation, - side: Side, - extension: TeamExtension | null -) => Team; -export declare const getHalfFromRound: (round: number, regulationMR: number, mr: number) => number; -export declare const didTeamWinThatRound: ( - team: Team, - round: number, - wonBy: Side, - currentRound: number, - regulationMR: number, - mr: number -) => boolean; -export declare const parseGrenades: ( - grenades?: - | { - [key: string]: GrenadeRaw; - } - | undefined -) => Grenade[]; -export declare const getRoundWin: ( - mapRound: number, - teams: { - ct: Team; - t: Team; - }, - roundWins: RoundWins, - round: number, - regulationMR: number, - overtimeMR: number -) => RoundInfo | null; diff --git a/lib/cjs/utils.js b/lib/cjs/utils.js deleted file mode 100644 index 78b8b66..0000000 --- a/lib/cjs/utils.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getRoundWin = exports.parseGrenades = exports.didTeamWinThatRound = exports.getHalfFromRound = exports.parseTeam = exports.mapSteamIDToPlayer = void 0; -const parsePlayer = (basePlayer, steamid, team, extensions) => { - const extension = extensions.find(player => player.steamid === steamid); - const player = { - steamid, - name: (extension && extension.name) || basePlayer.name, - defaultName: basePlayer.name, - clan: basePlayer.clan, - observer_slot: basePlayer.observer_slot, - stats: basePlayer.match_stats, - weapons: Object.entries(basePlayer.weapons).map(([id, weapon]) => ({ ...weapon, id })), - state: { ...basePlayer.state, smoked: basePlayer.state.smoked || 0, adr: 0 }, - position: basePlayer.position.split(', ').map(pos => Number(pos)), - forward: basePlayer.forward.split(', ').map(pos => Number(pos)), - team, - avatar: (extension && extension.avatar) || null, - country: (extension && extension.country) || null, - realName: (extension && extension.realName) || null, - extra: (extension && extension.extra) || {} - }; - return player; -}; -const mapSteamIDToPlayer = (players, teams, extensions) => (steamid) => parsePlayer(players[steamid], steamid, teams[players[steamid].team], extensions); -exports.mapSteamIDToPlayer = mapSteamIDToPlayer; -const parseTeam = (team, orientation, side, extension) => ({ - score: team.score, - logo: (extension && extension.logo) || null, - consecutive_round_losses: team.consecutive_round_losses, - timeouts_remaining: team.timeouts_remaining, - matches_won_this_series: (extension && extension.map_score) || team.matches_won_this_series, - side, - name: (extension && extension.name) || team.name || (side === 'CT' ? 'Counter-Terrorists' : 'Terrorists'), - country: (extension && extension.country) || null, - id: (extension && extension.id) || null, - orientation, - extra: (extension && extension.extra) || {} -}); -exports.parseTeam = parseTeam; -const getHalfFromRound = (round, regulationMR, mr) => { - let currentRoundHalf = 1; - if (round <= 2 * regulationMR) { - currentRoundHalf = round <= regulationMR ? 1 : 2; - } - else { - const roundInOT = ((round - (2 * regulationMR + 1)) % (mr * 2)) + 1; - currentRoundHalf = roundInOT <= mr ? 1 : 2; - } - return currentRoundHalf; -}; -exports.getHalfFromRound = getHalfFromRound; -const didTeamWinThatRound = (team, round, wonBy, currentRound, regulationMR, mr) => { - // czy round i currentRound są w tej samej połowie === (czy team jest === wonBy) - const currentRoundHalf = (0, exports.getHalfFromRound)(currentRound, regulationMR, mr); - const roundToCheckHalf = (0, exports.getHalfFromRound)(round, regulationMR, mr); - return (team.side === wonBy) === (currentRoundHalf === roundToCheckHalf); -}; -exports.didTeamWinThatRound = didTeamWinThatRound; -const parseGrenade = (grenade, id) => { - if (grenade.type === 'inferno') { - return { - ...grenade, - id, - flames: Object.entries(grenade.flames).map(([id, position]) => ({ - id, - position: position.split(', ').map(parseFloat) - })), - lifetime: parseFloat(grenade.lifetime) - }; - } - if (grenade.type === 'smoke' || grenade.type === 'decoy') { - return { - ...grenade, - id, - velocity: grenade.velocity.split(', ').map(parseFloat), - position: grenade.position.split(', ').map(parseFloat), - lifetime: parseFloat(grenade.lifetime), - effecttime: parseFloat(grenade.effecttime) - }; - } - return { - type: grenade.type, - owner: grenade.owner, - id, - velocity: grenade.velocity.split(', ').map(parseFloat), - position: grenade.position.split(', ').map(parseFloat), - lifetime: parseFloat(grenade.lifetime) - }; -}; -const parseGrenades = (grenades) => { - if (!grenades) - return []; - return Object.entries(grenades).map(([id, grenade]) => parseGrenade(grenade, id)); -}; -exports.parseGrenades = parseGrenades; -const getRoundWin = (mapRound, teams, roundWins, round, regulationMR, overtimeMR) => { - let indexRound = round; - if (mapRound > 2 * regulationMR) { - const maxOvertimeRounds = 2 * overtimeMR * Math.floor((mapRound - (2 * regulationMR + 1)) / (2 * overtimeMR)) + 2 * regulationMR; - if (round <= maxOvertimeRounds) { - return null; - } - const roundInOT = ((round - (2 * regulationMR + 1)) % (overtimeMR * 2)) + 1; - indexRound = roundInOT; - } - const roundOutcome = roundWins[indexRound]; - if (!roundOutcome) - return null; - const winSide = roundOutcome.substr(0, roundOutcome.indexOf('_')).toUpperCase(); - const result = { - team: teams.ct, - round, - side: winSide, - outcome: roundOutcome - }; - if ((0, exports.didTeamWinThatRound)(teams.ct, round, winSide, mapRound, regulationMR, overtimeMR)) { - return result; - } - result.team = teams.t; - return result; -}; -exports.getRoundWin = getRoundWin; diff --git a/lib/esm/csgo.d.ts b/lib/esm/csgo.d.ts deleted file mode 100644 index 6f05e53..0000000 --- a/lib/esm/csgo.d.ts +++ /dev/null @@ -1,185 +0,0 @@ -export type Side = 'CT' | 'T'; -export type RoundOutcome = 'ct_win_elimination' | 't_win_elimination' | 'ct_win_time' | 'ct_win_defuse' | 't_win_bomb'; - -export type WeaponType = - | 'Knife' - | 'Pistol' - | 'Grenade' - | 'Rifle' - | 'SniperRifle' - | 'C4' - | 'Submachine Gun' - | 'Shotgun' - | 'Machine Gun'; - -export interface WeaponRaw { - name: string; - paintkit: string; - type?: WeaponType; - ammo_clip?: number; - ammo_clip_max?: number; - ammo_reserve?: number; - state: 'active' | 'holstered'; -} - -export interface TeamRaw { - score: number; - consecutive_round_losses: number; - timeouts_remaining: number; - matches_won_this_series: number; - name?: string; - flag?: string; -} - -export interface PlayerRaw { - steamid?: string; - name: string; - clan?: string; - observer_slot?: number; - team: Side; - match_stats: { - kills: number; - assists: number; - deaths: number; - mvps: number; - score: number; - }; - weapons: { - [key: string]: WeaponRaw; - }; - state: { - health: number; - armor: number; - helmet: boolean; - defusekit?: boolean; - flashed: number; - smoked?: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - }; - position: string; - forward: string; -} - -export interface PlayerObservedRaw { - steamid: string; - clan?: string; - name: string; - observer_slot?: number; - team?: Side; - activity: 'playing' | 'textinput' | 'menu'; - state: { - health: number; - armor: number; - helmet: boolean; - flashed: number; - smoked: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - }; - spectarget: 'free' | string; - position: string; - forward: string; -} - -export interface PlayersRaw { - [key: string]: PlayerRaw; -} - -export interface Provider { - name: 'Counter-Strike: Global Offensive'; - appid: 730; - version: number; - steamid: string; - timestamp: number; -} - -export interface MapRaw { - mode: 'competitive'; - name: string; - phase: 'warmup' | 'live' | 'intermission' | 'gameover'; - round: number; - team_ct: TeamRaw; - team_t: TeamRaw; - num_matches_to_win_series: number; - current_spectators: number; - souvenirs_total: number; - round_wins: { - [key: string]: RoundOutcome; - }; -} - -export interface RoundRaw { - phase: 'freezetime' | 'live' | 'over'; - bomb?: 'planted' | 'exploded' | 'defused'; - win_team?: Side; -} - -export interface BombRaw { - state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; - countdown?: string; - player?: string; - position: string; -} -export interface PhaseRaw { - phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; - phase_ends_in: string; -} - -export interface GrenadeBaseRaw { - owner: string; - lifetime: string; -} - -export interface DecoySmokeGrenadeRaw extends GrenadeBaseRaw { - position: string; - velocity: string; - type: 'decoy' | 'smoke'; - effecttime: string; -} - -export interface FragOrFireBombOrFlashbandGrenadeRaw extends GrenadeBaseRaw { - position: string; - type: 'frag' | 'firebomb' | 'flashbang'; - velocity: string; -} - -export interface InfernoGrenadeRaw extends GrenadeBaseRaw { - type: 'inferno'; - flames: { [key: string]: string }; -} - -export type GrenadeRaw = DecoySmokeGrenadeRaw | FragOrFireBombOrFlashbandGrenadeRaw | InfernoGrenadeRaw; - -export interface CSGORaw { - provider: Provider; - map?: MapRaw; - round?: RoundRaw; - player?: PlayerObservedRaw; - allplayers?: PlayersRaw; - bomb?: BombRaw; - grenades?: { - [key: string]: GrenadeRaw; - /*{ - owner:number, - position:string, - velocity:string, - lifetime:string, - type:string, - effecttime?:string - }*/ - }; - previously?: any; - phase_countdowns?: PhaseRaw; - auth?: { - token: string; - }; -} diff --git a/lib/esm/events.d.ts b/lib/esm/events.d.ts deleted file mode 100644 index 1e83240..0000000 --- a/lib/esm/events.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as I from './interfaces'; - -export interface Events { - raw: (data: I.CSGORaw) => void; - data: (data: I.CSGO) => void; - roundEnd: (team: I.Score) => void; - matchEnd: (score: I.Score) => void; - kill: (kill: I.KillEvent) => void; - hurt: (kill: I.HurtEvent) => void; - timeoutStart: (team: any) => void; - timeoutEnd: () => void; - /*roundStart: (round: number) => void, - warmupStart: () => void, - warmupEnd: () => void,*/ - mvp: (player: I.Player) => void; - freezetimeStart: () => void; - freezetimeEnd: () => void; - intermissionStart: () => void; - intermissionEnd: () => void; - defuseStart: (player: I.Player) => void; - defuseStop: (player: I.Player) => void; - bombPlantStart: (player: I.Player) => void; - bombPlant: (player: I.Player) => void; - bombExplode: () => void; - bombDefuse: (player: I.Player) => void; - newListener: (eventName: K, listener: Events[K]) => void; - removeListener: (eventName: K, listener: Events[K]) => void; -} - -export type AnyEventName = T | (string & {}); - -export type BaseEvents = keyof Events; - -export type EventNames = AnyEventName; - -export type EmptyListener = () => void; - -export type Callback = K extends BaseEvents ? Events[K] | EmptyListener : EmptyListener; diff --git a/lib/esm/index.d.ts b/lib/esm/index.d.ts deleted file mode 100644 index 62883e3..0000000 --- a/lib/esm/index.d.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { - CSGO, - CSGORaw, - Events, - KillEvent, - PlayerExtension, - RawKill, - Score, - TeamExtension, - Callback, - EventNames, - BaseEvents -} from './interfaces'; -import { RawHurt } from './mirv'; -import { DigestMirvType, HurtEvent } from './parsed'; -import { mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound } from './utils.js'; -interface EventDescriptor { - listener: Events[BaseEvents]; - once: boolean; -} -declare type RoundPlayerDamage = { - steamid: string; - damage: number; -}; -declare type RoundDamage = { - round: number; - players: RoundPlayerDamage[]; -}; -declare class CSGOGSI { - private descriptors; - private maxListeners; - teams: { - left: TeamExtension | null; - right: TeamExtension | null; - }; - damage: RoundDamage[]; - players: PlayerExtension[]; - overtimeMR: number; - regulationMR: number; - last?: CSGO; - current?: CSGO; - constructor(); - eventNames: () => EventNames[]; - getMaxListeners: () => number; - listenerCount: (eventName: EventNames) => number; - listeners: ( - eventName: EventNames - ) => ( - | ((data: CSGORaw) => void) - | ((data: CSGO) => void) - | ((team: Score) => void) - | ((score: Score) => void) - | ((kill: KillEvent) => void) - | ((kill: HurtEvent) => void) - | ((team: any) => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | (() => void) - | (() => void) - | (() => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | ((eventName: K, listener: Events[K]) => void) - | ((eventName: K_1, listener: Events[K_1]) => void) - )[]; - removeListener: (eventName: K, listener: Callback) => this; - off: (eventName: K, listener: Callback) => this; - addListener: (eventName: K, listener: Callback) => this; - on: (eventName: K, listener: Callback) => this; - once: (eventName: K, listener: Callback) => this; - prependListener: (eventName: K, listener: Callback) => this; - emit: (eventName: EventNames, arg?: any, arg2?: any) => boolean; - prependOnceListener: (eventName: K, listener: Callback) => this; - removeAllListeners: (eventName: EventNames) => this; - setMaxListeners: (n: number) => this; - rawListeners: (eventName: EventNames) => EventDescriptor[]; - digest: (raw: CSGORaw) => CSGO | null; - digestMIRV: (raw: RawKill | RawHurt, eventType?: string) => DigestMirvType; - static findSite(mapName: string, position: number[]): 'A' | 'B' | null; -} -export { CSGOGSI, mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound, RoundDamage }; -export { - CSGO, - CSGORaw, - Side, - RoundOutcome, - WeaponType, - Observer, - RawHurt, - WeaponRaw, - TeamRaw, - PlayerRaw, - PlayerObservedRaw, - PlayersRaw, - Provider, - HurtEvent, - RoundWins, - MapRaw, - RoundRaw, - BombRaw, - PhaseRaw, - Events, - Team, - Player, - Bomb, - Map, - Round, - Score, - KillEvent, - RawKill, - TeamExtension, - RoundInfo, - PlayerExtension, - Orientation, - Grenade, - GrenadeBaseRaw, - GrenadeBase, - DecoySmokeGrenade, - DecoySmokeGrenadeRaw, - InfernoGrenade, - InfernoGrenadeRaw, - FragOrFireBombOrFlashbandGrenade, - FragOrFireBombOrFlashbandGrenadeRaw, - Weapon, - GrenadeRaw -} from './interfaces'; diff --git a/lib/esm/index.js b/lib/esm/index.js deleted file mode 100644 index a9725e4..0000000 --- a/lib/esm/index.js +++ /dev/null @@ -1,379 +0,0 @@ -import { getRoundWin, mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound, parseGrenades } from './utils.js'; -class CSGOGSI { - constructor() { - this.eventNames = () => { - const listeners = this.descriptors.entries(); - const nonEmptyEvents = []; - for (const entry of listeners) { - if (entry[1] && entry[1].length > 0) { - nonEmptyEvents.push(entry[0]); - } - } - return nonEmptyEvents; - }; - this.getMaxListeners = () => this.maxListeners; - this.listenerCount = (eventName) => { - const listeners = this.listeners(eventName); - return listeners.length; - }; - this.listeners = (eventName) => { - const descriptors = this.descriptors.get(eventName) || []; - return descriptors.map(descriptor => descriptor.listener); - }; - this.removeListener = (eventName, listener) => { - return this.off(eventName, listener); - }; - this.off = (eventName, listener) => { - const descriptors = this.descriptors.get(eventName) || []; - this.descriptors.set(eventName, descriptors.filter(descriptor => descriptor.listener !== listener)); - this.emit('removeListener', eventName, listener); - return this; - }; - this.addListener = (eventName, listener) => { - return this.on(eventName, listener); - }; - this.on = (eventName, listener) => { - this.emit('newListener', eventName, listener); - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.push({ listener, once: false }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.once = (eventName, listener) => { - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.push({ listener, once: true }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.prependListener = (eventName, listener) => { - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.unshift({ listener, once: false }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.emit = (eventName, arg, arg2) => { - const listeners = this.descriptors.get(eventName); - if (!listeners || listeners.length === 0) - return false; - listeners.forEach(listener => { - if (listener.once) { - this.descriptors.set(eventName, listeners.filter(listenerInArray => listenerInArray !== listener)); - } - listener.listener(arg, arg2); - }); - return true; - }; - this.prependOnceListener = (eventName, listener) => { - const listOfListeners = [...(this.descriptors.get(eventName) || [])]; - listOfListeners.unshift({ listener, once: true }); - this.descriptors.set(eventName, listOfListeners); - return this; - }; - this.removeAllListeners = (eventName) => { - this.descriptors.set(eventName, []); - return this; - }; - this.setMaxListeners = (n) => { - this.maxListeners = n; - return this; - }; - this.rawListeners = (eventName) => { - return this.descriptors.get(eventName) || []; - }; - this.digest = (raw) => { - if (!raw.allplayers || !raw.map || !raw.phase_countdowns) { - return null; - } - this.emit('raw', raw); - let isCTLeft = true; - const examplePlayerT = Object.values(raw.allplayers).find(({ observer_slot, team }) => observer_slot !== undefined && team === 'T'); - const examplePlayerCT = Object.values(raw.allplayers).find(({ observer_slot, team }) => observer_slot !== undefined && team === 'CT'); - if (examplePlayerCT && - examplePlayerCT.observer_slot !== undefined && - examplePlayerT && - examplePlayerT.observer_slot !== undefined) { - if ((examplePlayerCT.observer_slot || 10) > (examplePlayerT.observer_slot || 10)) { - isCTLeft = false; - } - } - const bomb = raw.bomb; - const teamCT = parseTeam(raw.map.team_ct, isCTLeft ? 'left' : 'right', 'CT', isCTLeft ? this.teams.left : this.teams.right); - const teamT = parseTeam(raw.map.team_t, isCTLeft ? 'right' : 'left', 'T', isCTLeft ? this.teams.right : this.teams.left); - const playerMapper = mapSteamIDToPlayer(raw.allplayers, { CT: teamCT, T: teamT }, this.players); - const players = Object.keys(raw.allplayers).map(playerMapper); - const observed = players.find(player => raw.player && player.steamid === raw.player.steamid) || null; - const observer = { - activity: raw.player?.activity, - spectarget: raw.player?.spectarget, - position: raw.player?.position.split(', ').map(n => Number(n)), - forward: raw.player?.forward.split(', ').map(n => Number(n)) - }; - const rounds = []; - if (raw.round && raw.map && raw.map.round_wins) { - let currentRound = raw.map.round + 1; - if (raw.round && raw.round.phase === 'over') { - currentRound = raw.map.round; - } - for (let i = 1; i <= currentRound; i++) { - const result = getRoundWin(currentRound, { ct: teamCT, t: teamT }, raw.map.round_wins, i, this.regulationMR, this.overtimeMR); - if (!result) - continue; - rounds.push(result); - } - } - if (this.last && this.last.map.name !== raw.map.name) { - this.damage = []; - } - let currentRoundForDamage = raw.map.round + 1; - if (raw.round && raw.round.phase === 'over') { - currentRoundForDamage = raw.map.round; - } - let currentRoundDamage = this.damage.find(damage => damage.round === currentRoundForDamage); - if (!currentRoundDamage) { - currentRoundDamage = { - round: currentRoundForDamage, - players: [] - }; - this.damage.push(currentRoundDamage); - } - if ((raw.map.round === 0 && raw.phase_countdowns.phase === 'freezetime') || - raw.phase_countdowns.phase === 'warmup') { - this.damage = []; - } - currentRoundDamage.players = players.map(player => ({ - steamid: player.steamid, - damage: player.state.round_totaldmg - })); - for (const player of players) { - const { current, damage } = this; - if (!current) - continue; - const damageForRound = damage.filter(damageEntry => damageEntry.round < currentRoundForDamage); - if (damageForRound.length === 0) - continue; - //damagex.players.find(player => player.steamid === steamid).damage - const damageEntries = damageForRound.map(damageEntry => { - const playerDamageEntry = damageEntry.players.find(playerDamage => playerDamage.steamid === player.steamid); - return playerDamageEntry ? playerDamageEntry.damage : 0; - }); - const adr = damageEntries.reduce((a, b) => a + b, 0) / (raw.map.round || 1); - player.state.adr = Math.floor(adr); - } - const data = { - provider: raw.provider, - observer, - round: raw.round - ? { - phase: raw.round.phase, - bomb: raw.round.bomb, - win_team: raw.round.win_team - } - : null, - player: observed, - players: players, - bomb: bomb - ? { - state: bomb.state, - countdown: bomb.countdown ? parseFloat(bomb.countdown) : undefined, - position: bomb.position.split(', ').map(pos => parseFloat(pos)), - player: players.find(player => player.steamid === bomb.player) || undefined, - site: bomb.state === 'planted' || - bomb.state === 'defused' || - bomb.state === 'defusing' || - bomb.state === 'planting' - ? CSGOGSI.findSite(raw.map.name, bomb.position.split(', ').map(n => parseFloat(n))) - : null - } - : null, - grenades: parseGrenades(raw.grenades), - phase_countdowns: { - phase: raw.phase_countdowns.phase, - phase_ends_in: parseFloat(raw.phase_countdowns.phase_ends_in) - }, - auth: raw.auth, - map: { - mode: raw.map.mode, - name: raw.map.name, - phase: raw.map.phase, - round: raw.map.round, - team_ct: teamCT, - team_t: teamT, - num_matches_to_win_series: raw.map.num_matches_to_win_series, - current_spectators: raw.map.current_spectators, - souvenirs_total: raw.map.souvenirs_total, - round_wins: raw.map.round_wins, - rounds - } - }; - this.current = data; - if (!this.last) { - this.last = data; - this.emit('data', data); - return data; - } - const last = this.last; - // Round end - if (last.round && data.round && data.round.win_team && !last.round.win_team) { - const winner = data.round.win_team === 'CT' ? data.map.team_ct : data.map.team_t; - const loser = data.round.win_team === 'CT' ? data.map.team_t : data.map.team_ct; - const oldWinner = data.round.win_team === 'CT' ? last.map.team_ct : last.map.team_t; - if (winner.score === oldWinner.score) { - winner.score += 1; - } - const roundScore = { - winner, - loser, - map: data.map, - mapEnd: data.map.phase === 'gameover' - }; - this.emit('roundEnd', roundScore); - // Match end - if (roundScore.mapEnd && last.map.phase !== 'gameover') { - this.emit('matchEnd', roundScore); - } - } - //Bomb actions - if (last.bomb && data.bomb) { - if (last.bomb.state === 'planting' && data.bomb.state === 'planted') { - this.emit('bombPlant', last.bomb.player); - } - else if (last.bomb.state !== 'exploded' && data.bomb.state === 'exploded') { - this.emit('bombExplode'); - } - else if (last.bomb.state !== 'defused' && data.bomb.state === 'defused') { - this.emit('bombDefuse', last.bomb.player); - } - else if (last.bomb.state !== 'defusing' && data.bomb.state === 'defusing') { - this.emit('defuseStart', data.bomb.player); - } - else if (last.bomb.state === 'defusing' && data.bomb.state !== 'defusing') { - this.emit('defuseStop', last.bomb.player); - } - else if (last.bomb.state !== 'planting' && data.bomb.state === 'planting') { - this.emit('bombPlantStart', last.bomb.player); - } - } - // Intermission (between halfs) - if (data.map.phase === 'intermission' && last.map.phase !== 'intermission') { - this.emit('intermissionStart'); - } - else if (data.map.phase !== 'intermission' && last.map.phase === 'intermission') { - this.emit('intermissionEnd'); - } - const { phase } = data.phase_countdowns; - // Freezetime (between round end & start) - if (phase === 'freezetime' && last.phase_countdowns.phase !== 'freezetime') { - this.emit('freezetimeStart'); - } - else if (phase !== 'freezetime' && last.phase_countdowns.phase === 'freezetime') { - this.emit('freezetimeEnd'); - } - // Timeouts - if (phase && last.phase_countdowns.phase) { - if (phase.startsWith('timeout') && !last.phase_countdowns.phase.startsWith('timeout')) { - const team = phase === 'timeout_ct' ? teamCT : teamT; - this.emit('timeoutStart', team); - } - else if (last.phase_countdowns.phase.startsWith('timeout') && !phase.startsWith('timeout')) { - this.emit('timeoutEnd'); - } - } - const mvp = data.players.find(player => { - const previousData = last.players.find(previousPlayer => previousPlayer.steamid === player.steamid); - if (!previousData) - return false; - if (player.stats.mvps > previousData.stats.mvps) - return true; - return false; - }) || null; - if (mvp) { - this.emit('mvp', mvp); - } - this.emit('data', data); - this.last = data; - return data; - }; - this.digestMIRV = (raw, eventType = 'player_death') => { - if (eventType === 'player_death') { - const rawKill = raw; - if (!this.last) { - return null; - } - const data = rawKill.keys; - const killer = this.last.players.find(player => player.steamid === data.attacker.xuid); - const victim = this.last.players.find(player => player.steamid === data.userid.xuid); - const assister = this.last.players.find(player => player.steamid === data.assister.xuid && data.assister.xuid !== '0'); - if (!victim) { - return null; - } - const kill = { - killer: killer || (data.weapon === 'trigger_hurt' || data.weapon === 'worldspawn' ? victim : null), - victim, - assister: assister || null, - flashed: data.assistedflash, - headshot: data.headshot, - weapon: data.weapon, - wallbang: data.penetrated > 0, - attackerblind: data.attackerblind, - thrusmoke: data.thrusmoke, - noscope: data.noscope, - attackerinair: data.attackerinair - }; - this.emit('kill', kill); - return kill; - } - const rawHurt = raw; - if (!this.last) { - return null; - } - const data = rawHurt.keys; - const attacker = this.last.players.find(player => player.steamid === data.attacker.xuid); - const victim = this.last.players.find(player => player.steamid === data.userid.xuid); - if (!attacker || !victim) { - return null; - } - const kill = { - attacker, - victim, - health: data.health, - armor: data.armor, - weapon: data.weapon, - dmg_health: data.dmg_health, - dmg_armor: data.dmg_armor, - hitgroup: data.hitgroup - }; - this.emit('hurt', kill); - return kill; - }; - this.descriptors = new Map(); - this.teams = { - left: null, - right: null - }; - this.maxListeners = 10; - this.players = []; - this.overtimeMR = 3; - this.regulationMR = 15; - this.damage = []; - } - static findSite(mapName, position) { - const realMapName = mapName.substr(mapName.lastIndexOf('/') + 1); - const mapReference = { - de_mirage: position => (position[1] < -600 ? 'A' : 'B'), - de_cache: position => (position[1] > 0 ? 'A' : 'B'), - de_overpass: position => (position[2] > 400 ? 'A' : 'B'), - de_nuke: position => (position[2] > -500 ? 'A' : 'B'), - de_dust2: position => (position[0] > -500 ? 'A' : 'B'), - de_inferno: position => (position[0] > 1400 ? 'A' : 'B'), - de_vertigo: position => (position[0] > -1400 ? 'A' : 'B'), - de_train: position => (position[1] > -450 ? 'A' : 'B'), - de_ancient: position => (position[0] < -500 ? 'A' : 'B'), - de_anubis: position => (position[0] > 0 ? 'A' : 'B') - }; - if (realMapName in mapReference) { - return mapReference[realMapName](position); - } - return null; - } -} -export { CSGOGSI, mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound }; diff --git a/lib/esm/interfaces.d.ts b/lib/esm/interfaces.d.ts deleted file mode 100644 index 432580a..0000000 --- a/lib/esm/interfaces.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -export * from './csgo'; -export * from './events'; -export * from './parsed'; -export * from './mirv'; - -export interface TeamExtension { - id: string; - name: string; - country: string | null; - logo: string | null; - map_score: number; - extra: Record; -} - -export interface PlayerExtension { - id: string; - name: string; - steamid: string; - realName: string | null; - country: string | null; - avatar: string | null; - extra: Record; -} diff --git a/lib/esm/mirv.d.ts b/lib/esm/mirv.d.ts deleted file mode 100644 index 96018b7..0000000 --- a/lib/esm/mirv.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -export interface RawKill { - name: 'player_death'; - clientTime: number; - keys: { - userid: { - value: number; - xuid: string; - }; - attacker: { - value: number; - xuid: string; - }; - assister: { - value: number; - xuid: string; - }; - assistedflash: boolean; - weapon: string; - weapon_itemid: string; - weapon_fauxitemid: string; - weapon_originalowner_xuid: string; - headshot: boolean; - dominated: number; - revenge: number; - wipe: number; - attackerblind: boolean; - thrusmoke: boolean; - noscope: boolean; - penetrated: number; - noreplay: boolean; - attackerinair: boolean; - }; -} - -export interface RawHurt { - name: 'player_hurt'; - clientTime: number; - keys: { - userid: { - value: number; - xuid: string; - }; - attacker: { - value: number; - xuid: string; - }; - health: number; - armor: number; - weapon: string; - dmg_health: number; - dmg_armor: number; - hitgroup: number; - }; -} diff --git a/lib/esm/parsed.d.ts b/lib/esm/parsed.d.ts deleted file mode 100644 index f694d76..0000000 --- a/lib/esm/parsed.d.ts +++ /dev/null @@ -1,190 +0,0 @@ -import * as I from './interfaces'; - -export type Orientation = 'left' | 'right'; - -export interface Team { - logo: string | null; - score: number; - consecutive_round_losses: number; - timeouts_remaining: number; - matches_won_this_series: number; - side: I.Side; - name: string; - country: string | null; - id: string | null; - orientation: Orientation; - extra: Record; -} - -export interface RoundInfo { - team: Team; - round: number; - side: I.Side; - outcome: I.RoundOutcome; -} -export interface Weapon { - name: string; - paintkit: string; - type?: I.WeaponType; - ammo_clip?: number; - ammo_clip_max?: number; - ammo_reserve?: number; - state: 'active' | 'holstered'; - id: string; -} - -export interface Player { - steamid: string; - name: string; - defaultName: string; - clan?: string; - observer_slot?: number; - team: Team; - stats: { - kills: number; - assists: number; - deaths: number; - mvps: number; - score: number; - }; - weapons: Weapon[]; - state: { - health: number; - armor: number; - helmet: boolean; - defusekit?: boolean; - flashed: number; - smoked: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - adr: number; - }; - position: number[]; - forward: number[]; - avatar: string | null; - country: string | null; - realName: string | null; - extra: Record; -} - -export type RoundWins = { - [key: string]: I.RoundOutcome; -}; -export interface Bomb { - state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; - countdown?: number; - player?: Player; - site: 'A' | 'B' | null; - position: number[]; -} - -export interface Map { - mode: string; - name: string; - phase: 'warmup' | 'live' | 'intermission' | 'gameover'; - round: number; - team_ct: Team; - team_t: Team; - num_matches_to_win_series: number; - current_spectators: number; - souvenirs_total: number; - round_wins: RoundWins; - rounds: I.RoundInfo[]; -} - -export interface Round { - phase: 'freezetime' | 'live' | 'over'; - bomb?: 'planted' | 'exploded' | 'defused'; - win_team?: I.Side; -} - -export interface Observer { - activity?: 'playing' | 'textinput' | 'menu'; - spectarget?: 'free' | (string & {}); - position?: number[]; - forward?: number[]; -} - -export interface GrenadeBase { - id: string; - owner: string; - lifetime: number; -} - -export interface DecoySmokeGrenade extends GrenadeBase { - position: number[]; - velocity: number[]; - type: 'decoy' | 'smoke'; - effecttime: number; -} - -export interface FragOrFireBombOrFlashbandGrenade extends GrenadeBase { - position: number[]; - type: 'frag' | 'firebomb' | 'flashbang'; - velocity: number[]; -} - -export interface InfernoGrenade extends GrenadeBase { - type: 'inferno'; - flames: { id: string; position: number[] }[]; -} - -export type Grenade = DecoySmokeGrenade | FragOrFireBombOrFlashbandGrenade | InfernoGrenade; - -export interface Phase { - phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; - phase_ends_in: number; -} -export interface CSGO { - provider: I.Provider; - map: Map; - round: Round | null; - observer: Observer; - player: Player | null; - players: Player[]; - bomb: Bomb | null; - grenades: Grenade[]; - previously?: any; - phase_countdowns: I.Phase; - auth?: { - token: string; - }; -} -export interface Score { - winner: I.Team; - loser: I.Team; - map: Map; - mapEnd: boolean; -} - -export interface KillEvent { - killer: Player | null; - victim: Player; - assister: Player | null; - flashed: boolean; - headshot: boolean; - weapon: string; - wallbang: boolean; - attackerblind: boolean; - thrusmoke: boolean; - noscope: boolean; - attackerinair: boolean; -} - -export interface HurtEvent { - attacker: Player; - victim: Player; - health: number; - armor: number; - weapon: string; - dmg_health: number; - dmg_armor: number; - hitgroup: number; -} - -//export type DigestMirvType = ((kill: RawKill, eventType: 'player_death') => KillEvent | null) | ((hurt: RawHurt, eventType: 'player_hurt') => HurtEvent | null) -export type DigestMirvType = KillEvent | HurtEvent | null; diff --git a/lib/esm/utils.d.ts b/lib/esm/utils.d.ts deleted file mode 100644 index e8b9464..0000000 --- a/lib/esm/utils.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - Team, - PlayerExtension, - Player, - PlayersRaw, - Side, - Orientation, - TeamExtension, - TeamRaw, - RoundInfo, - RoundWins -} from '.'; -import { GrenadeRaw } from './csgo'; -import { Grenade } from './parsed'; -export declare const mapSteamIDToPlayer: ( - players: PlayersRaw, - teams: { - CT: Team; - T: Team; - }, - extensions: PlayerExtension[] -) => (steamid: string) => Player; -export declare const parseTeam: ( - team: TeamRaw, - orientation: Orientation, - side: Side, - extension: TeamExtension | null -) => Team; -export declare const getHalfFromRound: (round: number, regulationMR: number, mr: number) => number; -export declare const didTeamWinThatRound: ( - team: Team, - round: number, - wonBy: Side, - currentRound: number, - regulationMR: number, - mr: number -) => boolean; -export declare const parseGrenades: ( - grenades?: - | { - [key: string]: GrenadeRaw; - } - | undefined -) => Grenade[]; -export declare const getRoundWin: ( - mapRound: number, - teams: { - ct: Team; - t: Team; - }, - roundWins: RoundWins, - round: number, - regulationMR: number, - overtimeMR: number -) => RoundInfo | null; diff --git a/lib/esm/utils.js b/lib/esm/utils.js deleted file mode 100644 index 31cc9a7..0000000 --- a/lib/esm/utils.js +++ /dev/null @@ -1,114 +0,0 @@ -const parsePlayer = (basePlayer, steamid, team, extensions) => { - const extension = extensions.find(player => player.steamid === steamid); - const player = { - steamid, - name: (extension && extension.name) || basePlayer.name, - defaultName: basePlayer.name, - clan: basePlayer.clan, - observer_slot: basePlayer.observer_slot, - stats: basePlayer.match_stats, - weapons: Object.entries(basePlayer.weapons).map(([id, weapon]) => ({ ...weapon, id })), - state: { ...basePlayer.state, smoked: basePlayer.state.smoked || 0, adr: 0 }, - position: basePlayer.position.split(', ').map(pos => Number(pos)), - forward: basePlayer.forward.split(', ').map(pos => Number(pos)), - team, - avatar: (extension && extension.avatar) || null, - country: (extension && extension.country) || null, - realName: (extension && extension.realName) || null, - extra: (extension && extension.extra) || {} - }; - return player; -}; -export const mapSteamIDToPlayer = (players, teams, extensions) => (steamid) => parsePlayer(players[steamid], steamid, teams[players[steamid].team], extensions); -export const parseTeam = (team, orientation, side, extension) => ({ - score: team.score, - logo: (extension && extension.logo) || null, - consecutive_round_losses: team.consecutive_round_losses, - timeouts_remaining: team.timeouts_remaining, - matches_won_this_series: (extension && extension.map_score) || team.matches_won_this_series, - side, - name: (extension && extension.name) || team.name || (side === 'CT' ? 'Counter-Terrorists' : 'Terrorists'), - country: (extension && extension.country) || null, - id: (extension && extension.id) || null, - orientation, - extra: (extension && extension.extra) || {} -}); -export const getHalfFromRound = (round, regulationMR, mr) => { - let currentRoundHalf = 1; - if (round <= 2 * regulationMR) { - currentRoundHalf = round <= regulationMR ? 1 : 2; - } - else { - const roundInOT = ((round - (2 * regulationMR + 1)) % (mr * 2)) + 1; - currentRoundHalf = roundInOT <= mr ? 1 : 2; - } - return currentRoundHalf; -}; -export const didTeamWinThatRound = (team, round, wonBy, currentRound, regulationMR, mr) => { - // czy round i currentRound są w tej samej połowie === (czy team jest === wonBy) - const currentRoundHalf = getHalfFromRound(currentRound, regulationMR, mr); - const roundToCheckHalf = getHalfFromRound(round, regulationMR, mr); - return (team.side === wonBy) === (currentRoundHalf === roundToCheckHalf); -}; -const parseGrenade = (grenade, id) => { - if (grenade.type === 'inferno') { - return { - ...grenade, - id, - flames: Object.entries(grenade.flames).map(([id, position]) => ({ - id, - position: position.split(', ').map(parseFloat) - })), - lifetime: parseFloat(grenade.lifetime) - }; - } - if (grenade.type === 'smoke' || grenade.type === 'decoy') { - return { - ...grenade, - id, - velocity: grenade.velocity.split(', ').map(parseFloat), - position: grenade.position.split(', ').map(parseFloat), - lifetime: parseFloat(grenade.lifetime), - effecttime: parseFloat(grenade.effecttime) - }; - } - return { - type: grenade.type, - owner: grenade.owner, - id, - velocity: grenade.velocity.split(', ').map(parseFloat), - position: grenade.position.split(', ').map(parseFloat), - lifetime: parseFloat(grenade.lifetime) - }; -}; -export const parseGrenades = (grenades) => { - if (!grenades) - return []; - return Object.entries(grenades).map(([id, grenade]) => parseGrenade(grenade, id)); -}; -export const getRoundWin = (mapRound, teams, roundWins, round, regulationMR, overtimeMR) => { - let indexRound = round; - if (mapRound > 2 * regulationMR) { - const maxOvertimeRounds = 2 * overtimeMR * Math.floor((mapRound - (2 * regulationMR + 1)) / (2 * overtimeMR)) + 2 * regulationMR; - if (round <= maxOvertimeRounds) { - return null; - } - const roundInOT = ((round - (2 * regulationMR + 1)) % (overtimeMR * 2)) + 1; - indexRound = roundInOT; - } - const roundOutcome = roundWins[indexRound]; - if (!roundOutcome) - return null; - const winSide = roundOutcome.substr(0, roundOutcome.indexOf('_')).toUpperCase(); - const result = { - team: teams.ct, - round, - side: winSide, - outcome: roundOutcome - }; - if (didTeamWinThatRound(teams.ct, round, winSide, mapRound, regulationMR, overtimeMR)) { - return result; - } - result.team = teams.t; - return result; -}; diff --git a/lib/index.d.mts b/lib/index.d.mts new file mode 100644 index 0000000..35cbbc2 --- /dev/null +++ b/lib/index.d.mts @@ -0,0 +1,541 @@ +type Side = 'CT' | 'T'; +type RoundOutcome = 'ct_win_elimination' | 't_win_elimination' | 'ct_win_time' | 'ct_win_defuse' | 't_win_bomb'; + +type WeaponType = + | 'Knife' + | 'Pistol' + | 'Grenade' + | 'Rifle' + | 'SniperRifle' + | 'C4' + | 'Submachine Gun' + | 'Shotgun' + | 'Machine Gun'; + +interface WeaponRaw { + name: string; + paintkit: string; + type?: WeaponType; + ammo_clip?: number; + ammo_clip_max?: number; + ammo_reserve?: number; + state: 'active' | 'holstered'; +} + +interface TeamRaw { + score: number; + consecutive_round_losses: number; + timeouts_remaining: number; + matches_won_this_series: number; + name?: string; + flag?: string; +} + +interface PlayerRaw { + steamid?: string; + name: string; + clan?: string; + observer_slot?: number; + team: Side; + match_stats: { + kills: number; + assists: number; + deaths: number; + mvps: number; + score: number; + }; + weapons: { + [key: string]: WeaponRaw; + }; + state: { + health: number; + armor: number; + helmet: boolean; + defusekit?: boolean; + flashed: number; + smoked?: number; + burning: number; + money: number; + round_kills: number; + round_killhs: number; + round_totaldmg: number; + equip_value: number; + }; + position: string; + forward: string; +} + +interface PlayerObservedRaw { + steamid: string; + clan?: string; + name: string; + observer_slot?: number; + team?: Side; + activity: 'playing' | 'textinput' | 'menu'; + state: { + health: number; + armor: number; + helmet: boolean; + flashed: number; + smoked: number; + burning: number; + money: number; + round_kills: number; + round_killhs: number; + round_totaldmg: number; + equip_value: number; + }; + spectarget: 'free' | string; + position: string; + forward: string; +} + +interface PlayersRaw { + [key: string]: PlayerRaw; +} + +interface Provider { + name: 'Counter-Strike: Global Offensive'; + appid: 730; + version: number; + steamid: string; + timestamp: number; +} + +interface MapRaw { + mode: 'competitive'; + name: string; + phase: 'warmup' | 'live' | 'intermission' | 'gameover'; + round: number; + team_ct: TeamRaw; + team_t: TeamRaw; + num_matches_to_win_series: number; + current_spectators: number; + souvenirs_total: number; + round_wins: { + [key: string]: RoundOutcome; + }; +} + +interface RoundRaw { + phase: 'freezetime' | 'live' | 'over'; + bomb?: 'planted' | 'exploded' | 'defused'; + win_team?: Side; +} + +interface BombRaw { + state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; + countdown?: string; + player?: string; + position: string; +} +interface PhaseRaw { + phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; + phase_ends_in: string; +} + +interface GrenadeBaseRaw { + owner: string; + lifetime: string; +} + +interface DecoySmokeGrenadeRaw extends GrenadeBaseRaw { + position: string; + velocity: string; + type: 'decoy' | 'smoke'; + effecttime: string; +} + +interface FragOrFireBombOrFlashbandGrenadeRaw extends GrenadeBaseRaw { + position: string; + type: 'frag' | 'firebomb' | 'flashbang'; + velocity: string; +} + +interface InfernoGrenadeRaw extends GrenadeBaseRaw { + type: 'inferno'; + flames: { [key: string]: string }; +} + +type GrenadeRaw = DecoySmokeGrenadeRaw | FragOrFireBombOrFlashbandGrenadeRaw | InfernoGrenadeRaw; + +interface CSGORaw { + provider: Provider; + map?: MapRaw; + round?: RoundRaw; + player?: PlayerObservedRaw; + allplayers?: PlayersRaw; + bomb?: BombRaw; + grenades?: { + [key: string]: GrenadeRaw; + /*{ + owner:number, + position:string, + velocity:string, + lifetime:string, + type:string, + effecttime?:string + }*/ + }; + previously?: any; + phase_countdowns?: PhaseRaw; + auth?: { + token: string; + }; +} + +interface Events { + raw: (data: CSGORaw) => void; + data: (data: CSGO) => void; + roundEnd: (team: Score) => void; + matchEnd: (score: Score) => void; + kill: (kill: KillEvent) => void; + hurt: (kill: HurtEvent) => void; + timeoutStart: (team: any) => void; + timeoutEnd: () => void; + /*roundStart: (round: number) => void, + warmupStart: () => void, + warmupEnd: () => void,*/ + mvp: (player: Player) => void; + freezetimeStart: () => void; + freezetimeEnd: () => void; + intermissionStart: () => void; + intermissionEnd: () => void; + defuseStart: (player: Player) => void; + defuseStop: (player: Player) => void; + bombPlantStart: (player: Player) => void; + bombPlant: (player: Player) => void; + bombExplode: () => void; + bombDefuse: (player: Player) => void; + newListener: (eventName: K, listener: Events[K]) => void; + removeListener: (eventName: K, listener: Events[K]) => void; +} + +type AnyEventName = T | (string & {}); + +type BaseEvents = keyof Events; + +type EventNames = AnyEventName; + +type EmptyListener = () => void; + +type Callback = K extends BaseEvents ? Events[K] | EmptyListener : EmptyListener; + +interface RawKill { + name: 'player_death'; + clientTime: number; + keys: { + userid: { + value: number; + xuid: string; + }; + attacker: { + value: number; + xuid: string; + }; + assister: { + value: number; + xuid: string; + }; + assistedflash: boolean; + weapon: string; + weapon_itemid: string; + weapon_fauxitemid: string; + weapon_originalowner_xuid: string; + headshot: boolean; + dominated: number; + revenge: number; + wipe: number; + attackerblind: boolean; + thrusmoke: boolean; + noscope: boolean; + penetrated: number; + noreplay: boolean; + attackerinair: boolean; + }; +} + +interface RawHurt { + name: 'player_hurt'; + clientTime: number; + keys: { + userid: { + value: number; + xuid: string; + }; + attacker: { + value: number; + xuid: string; + }; + health: number; + armor: number; + weapon: string; + dmg_health: number; + dmg_armor: number; + hitgroup: number; + }; +} + +interface TeamExtension { + id: string; + name: string; + country: string | null; + logo: string | null; + map_score: number; + extra: Record; +} + +interface PlayerExtension { + id: string; + name: string; + steamid: string; + realName: string | null; + country: string | null; + avatar: string | null; + extra: Record; +} + +type Orientation = 'left' | 'right'; + +interface Team { + logo: string | null; + score: number; + consecutive_round_losses: number; + timeouts_remaining: number; + matches_won_this_series: number; + side: Side; + name: string; + country: string | null; + id: string | null; + orientation: Orientation; + extra: Record; +} + +interface RoundInfo { + team: Team; + round: number; + side: Side; + outcome: RoundOutcome; +} +interface Weapon { + name: string; + paintkit: string; + type?: WeaponType; + ammo_clip?: number; + ammo_clip_max?: number; + ammo_reserve?: number; + state: 'active' | 'holstered'; + id: string; +} + +interface Player { + steamid: string; + name: string; + defaultName: string; + clan?: string; + observer_slot?: number; + team: Team; + stats: { + kills: number; + assists: number; + deaths: number; + mvps: number; + score: number; + }; + weapons: Weapon[]; + state: { + health: number; + armor: number; + helmet: boolean; + defusekit?: boolean; + flashed: number; + smoked: number; + burning: number; + money: number; + round_kills: number; + round_killhs: number; + round_totaldmg: number; + equip_value: number; + adr: number; + }; + position: number[]; + forward: number[]; + avatar: string | null; + country: string | null; + realName: string | null; + extra: Record; +} + +type RoundWins = { + [key: string]: RoundOutcome; +}; +interface Bomb { + state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; + countdown?: number; + player?: Player; + site: 'A' | 'B' | null; + position: number[]; +} + +interface Map { + mode: string; + name: string; + phase: 'warmup' | 'live' | 'intermission' | 'gameover'; + round: number; + team_ct: Team; + team_t: Team; + num_matches_to_win_series: number; + current_spectators: number; + souvenirs_total: number; + round_wins: RoundWins; + rounds: RoundInfo[]; +} + +interface Round { + phase: 'freezetime' | 'live' | 'over'; + bomb?: 'planted' | 'exploded' | 'defused'; + win_team?: Side; +} + +interface Observer { + activity?: 'playing' | 'textinput' | 'menu'; + spectarget?: 'free' | (string & {}); + position?: number[]; + forward?: number[]; +} + +interface GrenadeBase { + id: string; + owner: string; + lifetime: number; +} + +interface DecoySmokeGrenade extends GrenadeBase { + position: number[]; + velocity: number[]; + type: 'decoy' | 'smoke'; + effecttime: number; +} + +interface FragOrFireBombOrFlashbandGrenade extends GrenadeBase { + position: number[]; + type: 'frag' | 'firebomb' | 'flashbang'; + velocity: number[]; +} + +interface InfernoGrenade extends GrenadeBase { + type: 'inferno'; + flames: { id: string; position: number[] }[]; +} + +type Grenade = DecoySmokeGrenade | FragOrFireBombOrFlashbandGrenade | InfernoGrenade; + +interface Phase { + phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; + phase_ends_in: number; +} +interface CSGO { + provider: Provider; + map: Map; + round: Round | null; + observer: Observer; + player: Player | null; + players: Player[]; + bomb: Bomb | null; + grenades: Grenade[]; + previously?: any; + phase_countdowns: Phase; + auth?: { + token: string; + }; +} +interface Score { + winner: Team; + loser: Team; + map: Map; + mapEnd: boolean; +} + +interface KillEvent { + killer: Player | null; + victim: Player; + assister: Player | null; + flashed: boolean; + headshot: boolean; + weapon: string; + wallbang: boolean; + attackerblind: boolean; + thrusmoke: boolean; + noscope: boolean; + attackerinair: boolean; +} + +interface HurtEvent { + attacker: Player; + victim: Player; + health: number; + armor: number; + weapon: string; + dmg_health: number; + dmg_armor: number; + hitgroup: number; +} + +//export type DigestMirvType = ((kill: RawKill, eventType: 'player_death') => KillEvent | null) | ((hurt: RawHurt, eventType: 'player_hurt') => HurtEvent | null) +type DigestMirvType = KillEvent | HurtEvent | null; + +declare const mapSteamIDToPlayer: (players: PlayersRaw, teams: { + CT: Team; + T: Team; +}, extensions: PlayerExtension[]) => (steamid: string) => Player; +declare const parseTeam: (team: TeamRaw, orientation: Orientation, side: Side, extension: TeamExtension | null) => Team; +declare const getHalfFromRound: (round: number, regulationMR: number, mr: number) => number; +declare const didTeamWinThatRound: (team: Team, round: number, wonBy: Side, currentRound: number, regulationMR: number, mr: number) => boolean; + +interface EventDescriptor { + listener: Events[BaseEvents]; + once: boolean; +} +type RoundPlayerDamage = { + steamid: string; + damage: number; +}; +type RoundDamage = { + round: number; + players: RoundPlayerDamage[]; +}; +declare class CSGOGSI { + private descriptors; + private maxListeners; + teams: { + left: TeamExtension | null; + right: TeamExtension | null; + }; + damage: RoundDamage[]; + players: PlayerExtension[]; + overtimeMR: number; + regulationMR: number; + last?: CSGO; + current?: CSGO; + constructor(); + eventNames: () => EventNames[]; + getMaxListeners: () => number; + listenerCount: (eventName: EventNames) => number; + listeners: (eventName: EventNames) => (((data: CSGORaw) => void) | ((data: CSGO) => void) | ((team: Score) => void) | ((score: Score) => void) | ((kill: KillEvent) => void) | ((kill: HurtEvent) => void) | ((team: any) => void) | (() => void) | ((player: Player) => void) | (() => void) | (() => void) | (() => void) | (() => void) | ((player: Player) => void) | ((player: Player) => void) | ((player: Player) => void) | ((player: Player) => void) | (() => void) | ((player: Player) => void) | ((eventName: K, listener: Events[K]) => void) | ((eventName: K_1, listener: Events[K_1]) => void))[]; + removeListener: (eventName: K, listener: Callback) => this; + off: (eventName: K, listener: Callback) => this; + addListener: (eventName: K, listener: Callback) => this; + on: (eventName: K, listener: Callback) => this; + once: (eventName: K, listener: Callback) => this; + prependListener: (eventName: K, listener: Callback) => this; + emit: (eventName: EventNames, arg?: any, arg2?: any) => boolean; + prependOnceListener: (eventName: K, listener: Callback) => this; + removeAllListeners: (eventName: EventNames) => this; + setMaxListeners: (n: number) => this; + rawListeners: (eventName: EventNames) => EventDescriptor[]; + digest: (raw: CSGORaw) => CSGO | null; + digestMIRV: (raw: RawKill | RawHurt, eventType?: string) => DigestMirvType; + static findSite(mapName: string, position: number[]): "A" | "B" | null; +} + +export { type Bomb, type BombRaw, type CSGO, CSGOGSI, type CSGORaw, type DecoySmokeGrenade, type DecoySmokeGrenadeRaw, type Events, type FragOrFireBombOrFlashbandGrenade, type FragOrFireBombOrFlashbandGrenadeRaw, type Grenade, type GrenadeBase, type GrenadeBaseRaw, type GrenadeRaw, type HurtEvent, type InfernoGrenade, type InfernoGrenadeRaw, type KillEvent, type Map, type MapRaw, type Observer, type Orientation, type PhaseRaw, type Player, type PlayerExtension, type PlayerObservedRaw, type PlayerRaw, type PlayersRaw, type Provider, type RawHurt, type RawKill, type Round, type RoundDamage, type RoundInfo, type RoundOutcome, type RoundRaw, type RoundWins, type Score, type Side, type Team, type TeamExtension, type TeamRaw, type Weapon, type WeaponRaw, type WeaponType, didTeamWinThatRound, getHalfFromRound, mapSteamIDToPlayer, parseTeam }; diff --git a/lib/index.d.ts b/lib/index.d.ts new file mode 100644 index 0000000..35cbbc2 --- /dev/null +++ b/lib/index.d.ts @@ -0,0 +1,541 @@ +type Side = 'CT' | 'T'; +type RoundOutcome = 'ct_win_elimination' | 't_win_elimination' | 'ct_win_time' | 'ct_win_defuse' | 't_win_bomb'; + +type WeaponType = + | 'Knife' + | 'Pistol' + | 'Grenade' + | 'Rifle' + | 'SniperRifle' + | 'C4' + | 'Submachine Gun' + | 'Shotgun' + | 'Machine Gun'; + +interface WeaponRaw { + name: string; + paintkit: string; + type?: WeaponType; + ammo_clip?: number; + ammo_clip_max?: number; + ammo_reserve?: number; + state: 'active' | 'holstered'; +} + +interface TeamRaw { + score: number; + consecutive_round_losses: number; + timeouts_remaining: number; + matches_won_this_series: number; + name?: string; + flag?: string; +} + +interface PlayerRaw { + steamid?: string; + name: string; + clan?: string; + observer_slot?: number; + team: Side; + match_stats: { + kills: number; + assists: number; + deaths: number; + mvps: number; + score: number; + }; + weapons: { + [key: string]: WeaponRaw; + }; + state: { + health: number; + armor: number; + helmet: boolean; + defusekit?: boolean; + flashed: number; + smoked?: number; + burning: number; + money: number; + round_kills: number; + round_killhs: number; + round_totaldmg: number; + equip_value: number; + }; + position: string; + forward: string; +} + +interface PlayerObservedRaw { + steamid: string; + clan?: string; + name: string; + observer_slot?: number; + team?: Side; + activity: 'playing' | 'textinput' | 'menu'; + state: { + health: number; + armor: number; + helmet: boolean; + flashed: number; + smoked: number; + burning: number; + money: number; + round_kills: number; + round_killhs: number; + round_totaldmg: number; + equip_value: number; + }; + spectarget: 'free' | string; + position: string; + forward: string; +} + +interface PlayersRaw { + [key: string]: PlayerRaw; +} + +interface Provider { + name: 'Counter-Strike: Global Offensive'; + appid: 730; + version: number; + steamid: string; + timestamp: number; +} + +interface MapRaw { + mode: 'competitive'; + name: string; + phase: 'warmup' | 'live' | 'intermission' | 'gameover'; + round: number; + team_ct: TeamRaw; + team_t: TeamRaw; + num_matches_to_win_series: number; + current_spectators: number; + souvenirs_total: number; + round_wins: { + [key: string]: RoundOutcome; + }; +} + +interface RoundRaw { + phase: 'freezetime' | 'live' | 'over'; + bomb?: 'planted' | 'exploded' | 'defused'; + win_team?: Side; +} + +interface BombRaw { + state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; + countdown?: string; + player?: string; + position: string; +} +interface PhaseRaw { + phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; + phase_ends_in: string; +} + +interface GrenadeBaseRaw { + owner: string; + lifetime: string; +} + +interface DecoySmokeGrenadeRaw extends GrenadeBaseRaw { + position: string; + velocity: string; + type: 'decoy' | 'smoke'; + effecttime: string; +} + +interface FragOrFireBombOrFlashbandGrenadeRaw extends GrenadeBaseRaw { + position: string; + type: 'frag' | 'firebomb' | 'flashbang'; + velocity: string; +} + +interface InfernoGrenadeRaw extends GrenadeBaseRaw { + type: 'inferno'; + flames: { [key: string]: string }; +} + +type GrenadeRaw = DecoySmokeGrenadeRaw | FragOrFireBombOrFlashbandGrenadeRaw | InfernoGrenadeRaw; + +interface CSGORaw { + provider: Provider; + map?: MapRaw; + round?: RoundRaw; + player?: PlayerObservedRaw; + allplayers?: PlayersRaw; + bomb?: BombRaw; + grenades?: { + [key: string]: GrenadeRaw; + /*{ + owner:number, + position:string, + velocity:string, + lifetime:string, + type:string, + effecttime?:string + }*/ + }; + previously?: any; + phase_countdowns?: PhaseRaw; + auth?: { + token: string; + }; +} + +interface Events { + raw: (data: CSGORaw) => void; + data: (data: CSGO) => void; + roundEnd: (team: Score) => void; + matchEnd: (score: Score) => void; + kill: (kill: KillEvent) => void; + hurt: (kill: HurtEvent) => void; + timeoutStart: (team: any) => void; + timeoutEnd: () => void; + /*roundStart: (round: number) => void, + warmupStart: () => void, + warmupEnd: () => void,*/ + mvp: (player: Player) => void; + freezetimeStart: () => void; + freezetimeEnd: () => void; + intermissionStart: () => void; + intermissionEnd: () => void; + defuseStart: (player: Player) => void; + defuseStop: (player: Player) => void; + bombPlantStart: (player: Player) => void; + bombPlant: (player: Player) => void; + bombExplode: () => void; + bombDefuse: (player: Player) => void; + newListener: (eventName: K, listener: Events[K]) => void; + removeListener: (eventName: K, listener: Events[K]) => void; +} + +type AnyEventName = T | (string & {}); + +type BaseEvents = keyof Events; + +type EventNames = AnyEventName; + +type EmptyListener = () => void; + +type Callback = K extends BaseEvents ? Events[K] | EmptyListener : EmptyListener; + +interface RawKill { + name: 'player_death'; + clientTime: number; + keys: { + userid: { + value: number; + xuid: string; + }; + attacker: { + value: number; + xuid: string; + }; + assister: { + value: number; + xuid: string; + }; + assistedflash: boolean; + weapon: string; + weapon_itemid: string; + weapon_fauxitemid: string; + weapon_originalowner_xuid: string; + headshot: boolean; + dominated: number; + revenge: number; + wipe: number; + attackerblind: boolean; + thrusmoke: boolean; + noscope: boolean; + penetrated: number; + noreplay: boolean; + attackerinair: boolean; + }; +} + +interface RawHurt { + name: 'player_hurt'; + clientTime: number; + keys: { + userid: { + value: number; + xuid: string; + }; + attacker: { + value: number; + xuid: string; + }; + health: number; + armor: number; + weapon: string; + dmg_health: number; + dmg_armor: number; + hitgroup: number; + }; +} + +interface TeamExtension { + id: string; + name: string; + country: string | null; + logo: string | null; + map_score: number; + extra: Record; +} + +interface PlayerExtension { + id: string; + name: string; + steamid: string; + realName: string | null; + country: string | null; + avatar: string | null; + extra: Record; +} + +type Orientation = 'left' | 'right'; + +interface Team { + logo: string | null; + score: number; + consecutive_round_losses: number; + timeouts_remaining: number; + matches_won_this_series: number; + side: Side; + name: string; + country: string | null; + id: string | null; + orientation: Orientation; + extra: Record; +} + +interface RoundInfo { + team: Team; + round: number; + side: Side; + outcome: RoundOutcome; +} +interface Weapon { + name: string; + paintkit: string; + type?: WeaponType; + ammo_clip?: number; + ammo_clip_max?: number; + ammo_reserve?: number; + state: 'active' | 'holstered'; + id: string; +} + +interface Player { + steamid: string; + name: string; + defaultName: string; + clan?: string; + observer_slot?: number; + team: Team; + stats: { + kills: number; + assists: number; + deaths: number; + mvps: number; + score: number; + }; + weapons: Weapon[]; + state: { + health: number; + armor: number; + helmet: boolean; + defusekit?: boolean; + flashed: number; + smoked: number; + burning: number; + money: number; + round_kills: number; + round_killhs: number; + round_totaldmg: number; + equip_value: number; + adr: number; + }; + position: number[]; + forward: number[]; + avatar: string | null; + country: string | null; + realName: string | null; + extra: Record; +} + +type RoundWins = { + [key: string]: RoundOutcome; +}; +interface Bomb { + state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; + countdown?: number; + player?: Player; + site: 'A' | 'B' | null; + position: number[]; +} + +interface Map { + mode: string; + name: string; + phase: 'warmup' | 'live' | 'intermission' | 'gameover'; + round: number; + team_ct: Team; + team_t: Team; + num_matches_to_win_series: number; + current_spectators: number; + souvenirs_total: number; + round_wins: RoundWins; + rounds: RoundInfo[]; +} + +interface Round { + phase: 'freezetime' | 'live' | 'over'; + bomb?: 'planted' | 'exploded' | 'defused'; + win_team?: Side; +} + +interface Observer { + activity?: 'playing' | 'textinput' | 'menu'; + spectarget?: 'free' | (string & {}); + position?: number[]; + forward?: number[]; +} + +interface GrenadeBase { + id: string; + owner: string; + lifetime: number; +} + +interface DecoySmokeGrenade extends GrenadeBase { + position: number[]; + velocity: number[]; + type: 'decoy' | 'smoke'; + effecttime: number; +} + +interface FragOrFireBombOrFlashbandGrenade extends GrenadeBase { + position: number[]; + type: 'frag' | 'firebomb' | 'flashbang'; + velocity: number[]; +} + +interface InfernoGrenade extends GrenadeBase { + type: 'inferno'; + flames: { id: string; position: number[] }[]; +} + +type Grenade = DecoySmokeGrenade | FragOrFireBombOrFlashbandGrenade | InfernoGrenade; + +interface Phase { + phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; + phase_ends_in: number; +} +interface CSGO { + provider: Provider; + map: Map; + round: Round | null; + observer: Observer; + player: Player | null; + players: Player[]; + bomb: Bomb | null; + grenades: Grenade[]; + previously?: any; + phase_countdowns: Phase; + auth?: { + token: string; + }; +} +interface Score { + winner: Team; + loser: Team; + map: Map; + mapEnd: boolean; +} + +interface KillEvent { + killer: Player | null; + victim: Player; + assister: Player | null; + flashed: boolean; + headshot: boolean; + weapon: string; + wallbang: boolean; + attackerblind: boolean; + thrusmoke: boolean; + noscope: boolean; + attackerinair: boolean; +} + +interface HurtEvent { + attacker: Player; + victim: Player; + health: number; + armor: number; + weapon: string; + dmg_health: number; + dmg_armor: number; + hitgroup: number; +} + +//export type DigestMirvType = ((kill: RawKill, eventType: 'player_death') => KillEvent | null) | ((hurt: RawHurt, eventType: 'player_hurt') => HurtEvent | null) +type DigestMirvType = KillEvent | HurtEvent | null; + +declare const mapSteamIDToPlayer: (players: PlayersRaw, teams: { + CT: Team; + T: Team; +}, extensions: PlayerExtension[]) => (steamid: string) => Player; +declare const parseTeam: (team: TeamRaw, orientation: Orientation, side: Side, extension: TeamExtension | null) => Team; +declare const getHalfFromRound: (round: number, regulationMR: number, mr: number) => number; +declare const didTeamWinThatRound: (team: Team, round: number, wonBy: Side, currentRound: number, regulationMR: number, mr: number) => boolean; + +interface EventDescriptor { + listener: Events[BaseEvents]; + once: boolean; +} +type RoundPlayerDamage = { + steamid: string; + damage: number; +}; +type RoundDamage = { + round: number; + players: RoundPlayerDamage[]; +}; +declare class CSGOGSI { + private descriptors; + private maxListeners; + teams: { + left: TeamExtension | null; + right: TeamExtension | null; + }; + damage: RoundDamage[]; + players: PlayerExtension[]; + overtimeMR: number; + regulationMR: number; + last?: CSGO; + current?: CSGO; + constructor(); + eventNames: () => EventNames[]; + getMaxListeners: () => number; + listenerCount: (eventName: EventNames) => number; + listeners: (eventName: EventNames) => (((data: CSGORaw) => void) | ((data: CSGO) => void) | ((team: Score) => void) | ((score: Score) => void) | ((kill: KillEvent) => void) | ((kill: HurtEvent) => void) | ((team: any) => void) | (() => void) | ((player: Player) => void) | (() => void) | (() => void) | (() => void) | (() => void) | ((player: Player) => void) | ((player: Player) => void) | ((player: Player) => void) | ((player: Player) => void) | (() => void) | ((player: Player) => void) | ((eventName: K, listener: Events[K]) => void) | ((eventName: K_1, listener: Events[K_1]) => void))[]; + removeListener: (eventName: K, listener: Callback) => this; + off: (eventName: K, listener: Callback) => this; + addListener: (eventName: K, listener: Callback) => this; + on: (eventName: K, listener: Callback) => this; + once: (eventName: K, listener: Callback) => this; + prependListener: (eventName: K, listener: Callback) => this; + emit: (eventName: EventNames, arg?: any, arg2?: any) => boolean; + prependOnceListener: (eventName: K, listener: Callback) => this; + removeAllListeners: (eventName: EventNames) => this; + setMaxListeners: (n: number) => this; + rawListeners: (eventName: EventNames) => EventDescriptor[]; + digest: (raw: CSGORaw) => CSGO | null; + digestMIRV: (raw: RawKill | RawHurt, eventType?: string) => DigestMirvType; + static findSite(mapName: string, position: number[]): "A" | "B" | null; +} + +export { type Bomb, type BombRaw, type CSGO, CSGOGSI, type CSGORaw, type DecoySmokeGrenade, type DecoySmokeGrenadeRaw, type Events, type FragOrFireBombOrFlashbandGrenade, type FragOrFireBombOrFlashbandGrenadeRaw, type Grenade, type GrenadeBase, type GrenadeBaseRaw, type GrenadeRaw, type HurtEvent, type InfernoGrenade, type InfernoGrenadeRaw, type KillEvent, type Map, type MapRaw, type Observer, type Orientation, type PhaseRaw, type Player, type PlayerExtension, type PlayerObservedRaw, type PlayerRaw, type PlayersRaw, type Provider, type RawHurt, type RawKill, type Round, type RoundDamage, type RoundInfo, type RoundOutcome, type RoundRaw, type RoundWins, type Score, type Side, type Team, type TeamExtension, type TeamRaw, type Weapon, type WeaponRaw, type WeaponType, didTeamWinThatRound, getHalfFromRound, mapSteamIDToPlayer, parseTeam }; diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..084f673 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,545 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// tsc/index.ts +var tsc_exports = {}; +__export(tsc_exports, { + CSGOGSI: () => CSGOGSI, + didTeamWinThatRound: () => didTeamWinThatRound, + getHalfFromRound: () => getHalfFromRound, + mapSteamIDToPlayer: () => mapSteamIDToPlayer, + parseTeam: () => parseTeam +}); +module.exports = __toCommonJS(tsc_exports); + +// tsc/utils.ts +var parsePlayer = (basePlayer, steamid, team, extensions) => { + const extension = extensions.find((player2) => player2.steamid === steamid); + const player = { + steamid, + name: extension && extension.name || basePlayer.name, + defaultName: basePlayer.name, + clan: basePlayer.clan, + observer_slot: basePlayer.observer_slot, + stats: basePlayer.match_stats, + weapons: Object.entries(basePlayer.weapons).map(([id, weapon]) => ({ ...weapon, id })), + state: { ...basePlayer.state, smoked: basePlayer.state.smoked || 0, adr: 0 }, + position: basePlayer.position.split(", ").map((pos) => Number(pos)), + forward: basePlayer.forward.split(", ").map((pos) => Number(pos)), + team, + avatar: extension && extension.avatar || null, + country: extension && extension.country || null, + realName: extension && extension.realName || null, + extra: extension && extension.extra || {} + }; + return player; +}; +var mapSteamIDToPlayer = (players, teams, extensions) => (steamid) => parsePlayer(players[steamid], steamid, teams[players[steamid].team], extensions); +var parseTeam = (team, orientation, side, extension) => ({ + score: team.score, + logo: extension && extension.logo || null, + consecutive_round_losses: team.consecutive_round_losses, + timeouts_remaining: team.timeouts_remaining, + matches_won_this_series: extension && extension.map_score || team.matches_won_this_series, + side, + name: extension && extension.name || team.name || (side === "CT" ? "Counter-Terrorists" : "Terrorists"), + country: extension && extension.country || null, + id: extension && extension.id || null, + orientation, + extra: extension && extension.extra || {} +}); +var getHalfFromRound = (round, regulationMR, mr) => { + let currentRoundHalf = 1; + if (round <= 2 * regulationMR) { + currentRoundHalf = round <= regulationMR ? 1 : 2; + } else { + const roundInOT = (round - (2 * regulationMR + 1)) % (mr * 2) + 1; + currentRoundHalf = roundInOT <= mr ? 1 : 2; + } + return currentRoundHalf; +}; +var didTeamWinThatRound = (team, round, wonBy, currentRound, regulationMR, mr) => { + const currentRoundHalf = getHalfFromRound(currentRound, regulationMR, mr); + const roundToCheckHalf = getHalfFromRound(round, regulationMR, mr); + return team.side === wonBy === (currentRoundHalf === roundToCheckHalf); +}; +var parseGrenade = (grenade, id) => { + if (grenade.type === "inferno") { + return { + ...grenade, + id, + flames: Object.entries(grenade.flames).map(([id2, position]) => ({ + id: id2, + position: position.split(", ").map(parseFloat) + })), + lifetime: parseFloat(grenade.lifetime) + }; + } + if (grenade.type === "smoke" || grenade.type === "decoy") { + return { + ...grenade, + id, + velocity: grenade.velocity.split(", ").map(parseFloat), + position: grenade.position.split(", ").map(parseFloat), + lifetime: parseFloat(grenade.lifetime), + effecttime: parseFloat(grenade.effecttime) + }; + } + return { + type: grenade.type, + owner: grenade.owner, + id, + velocity: grenade.velocity.split(", ").map(parseFloat), + position: grenade.position.split(", ").map(parseFloat), + lifetime: parseFloat(grenade.lifetime) + }; +}; +var parseGrenades = (grenades) => { + if (!grenades) + return []; + return Object.entries(grenades).map(([id, grenade]) => parseGrenade(grenade, id)); +}; +var getRoundWin = (mapRound, teams, roundWins, round, regulationMR, overtimeMR) => { + let indexRound = round; + if (mapRound > 2 * regulationMR) { + const maxOvertimeRounds = 2 * overtimeMR * Math.floor((mapRound - (2 * regulationMR + 1)) / (2 * overtimeMR)) + 2 * regulationMR; + if (round <= maxOvertimeRounds) { + return null; + } + const roundInOT = (round - (2 * regulationMR + 1)) % (overtimeMR * 2) + 1; + indexRound = roundInOT; + } + const roundOutcome = roundWins[indexRound]; + if (!roundOutcome) + return null; + const winSide = roundOutcome.substr(0, roundOutcome.indexOf("_")).toUpperCase(); + const result = { + team: teams.ct, + round, + side: winSide, + outcome: roundOutcome + }; + if (didTeamWinThatRound(teams.ct, round, winSide, mapRound, regulationMR, overtimeMR)) { + return result; + } + result.team = teams.t; + return result; +}; + +// tsc/index.ts +var CSGOGSI = class _CSGOGSI { + descriptors; + maxListeners; + teams; + damage; + players; + overtimeMR; + regulationMR; + last; + current; + constructor() { + this.descriptors = /* @__PURE__ */ new Map(); + this.teams = { + left: null, + right: null + }; + this.maxListeners = 10; + this.players = []; + this.overtimeMR = 3; + this.regulationMR = 15; + this.damage = []; + } + eventNames = () => { + const listeners = this.descriptors.entries(); + const nonEmptyEvents = []; + for (const entry of listeners) { + if (entry[1] && entry[1].length > 0) { + nonEmptyEvents.push(entry[0]); + } + } + return nonEmptyEvents; + }; + getMaxListeners = () => this.maxListeners; + listenerCount = (eventName) => { + const listeners = this.listeners(eventName); + return listeners.length; + }; + listeners = (eventName) => { + const descriptors = this.descriptors.get(eventName) || []; + return descriptors.map((descriptor) => descriptor.listener); + }; + removeListener = (eventName, listener) => { + return this.off(eventName, listener); + }; + off = (eventName, listener) => { + const descriptors = this.descriptors.get(eventName) || []; + this.descriptors.set( + eventName, + descriptors.filter((descriptor) => descriptor.listener !== listener) + ); + this.emit("removeListener", eventName, listener); + return this; + }; + addListener = (eventName, listener) => { + return this.on(eventName, listener); + }; + on = (eventName, listener) => { + this.emit("newListener", eventName, listener); + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.push({ listener, once: false }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + once = (eventName, listener) => { + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.push({ listener, once: true }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + prependListener = (eventName, listener) => { + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.unshift({ listener, once: false }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + emit = (eventName, arg, arg2) => { + const listeners = this.descriptors.get(eventName); + if (!listeners || listeners.length === 0) + return false; + listeners.forEach((listener) => { + if (listener.once) { + this.descriptors.set( + eventName, + listeners.filter((listenerInArray) => listenerInArray !== listener) + ); + } + listener.listener(arg, arg2); + }); + return true; + }; + prependOnceListener = (eventName, listener) => { + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.unshift({ listener, once: true }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + removeAllListeners = (eventName) => { + this.descriptors.set(eventName, []); + return this; + }; + setMaxListeners = (n) => { + this.maxListeners = n; + return this; + }; + rawListeners = (eventName) => { + return this.descriptors.get(eventName) || []; + }; + digest = (raw) => { + if (!raw.allplayers || !raw.map || !raw.phase_countdowns) { + return null; + } + this.emit("raw", raw); + let isCTLeft = true; + const examplePlayerT = Object.values(raw.allplayers).find( + ({ observer_slot, team }) => observer_slot !== void 0 && team === "T" + ); + const examplePlayerCT = Object.values(raw.allplayers).find( + ({ observer_slot, team }) => observer_slot !== void 0 && team === "CT" + ); + if (examplePlayerCT && examplePlayerCT.observer_slot !== void 0 && examplePlayerT && examplePlayerT.observer_slot !== void 0) { + if ((examplePlayerCT.observer_slot || 10) > (examplePlayerT.observer_slot || 10)) { + isCTLeft = false; + } + } + const bomb = raw.bomb; + const teamCT = parseTeam( + raw.map.team_ct, + isCTLeft ? "left" : "right", + "CT", + isCTLeft ? this.teams.left : this.teams.right + ); + const teamT = parseTeam( + raw.map.team_t, + isCTLeft ? "right" : "left", + "T", + isCTLeft ? this.teams.right : this.teams.left + ); + const playerMapper = mapSteamIDToPlayer(raw.allplayers, { CT: teamCT, T: teamT }, this.players); + const players = Object.keys(raw.allplayers).map(playerMapper); + const observed = players.find((player) => raw.player && player.steamid === raw.player.steamid) || null; + const observer = { + activity: raw.player?.activity, + spectarget: raw.player?.spectarget, + position: raw.player?.position.split(", ").map((n) => Number(n)), + forward: raw.player?.forward.split(", ").map((n) => Number(n)) + }; + const rounds = []; + if (raw.round && raw.map && raw.map.round_wins) { + let currentRound = raw.map.round + 1; + if (raw.round && raw.round.phase === "over") { + currentRound = raw.map.round; + } + for (let i = 1; i <= currentRound; i++) { + const result = getRoundWin( + currentRound, + { ct: teamCT, t: teamT }, + raw.map.round_wins, + i, + this.regulationMR, + this.overtimeMR + ); + if (!result) + continue; + rounds.push(result); + } + } + if (this.last && this.last.map.name !== raw.map.name) { + this.damage = []; + } + let currentRoundForDamage = raw.map.round + 1; + if (raw.round && raw.round.phase === "over") { + currentRoundForDamage = raw.map.round; + } + let currentRoundDamage = this.damage.find((damage) => damage.round === currentRoundForDamage); + if (!currentRoundDamage) { + currentRoundDamage = { + round: currentRoundForDamage, + players: [] + }; + this.damage.push(currentRoundDamage); + } + if (raw.map.round === 0 && raw.phase_countdowns.phase === "freezetime" || raw.phase_countdowns.phase === "warmup") { + this.damage = []; + } + currentRoundDamage.players = players.map((player) => ({ + steamid: player.steamid, + damage: player.state.round_totaldmg + })); + for (const player of players) { + const { current, damage } = this; + if (!current) + continue; + const damageForRound = damage.filter((damageEntry) => damageEntry.round < currentRoundForDamage); + if (damageForRound.length === 0) + continue; + const damageEntries = damageForRound.map((damageEntry) => { + const playerDamageEntry = damageEntry.players.find( + (playerDamage) => playerDamage.steamid === player.steamid + ); + return playerDamageEntry ? playerDamageEntry.damage : 0; + }); + const adr = damageEntries.reduce((a, b) => a + b, 0) / (raw.map.round || 1); + player.state.adr = Math.floor(adr); + } + const data = { + provider: raw.provider, + observer, + round: raw.round ? { + phase: raw.round.phase, + bomb: raw.round.bomb, + win_team: raw.round.win_team + } : null, + player: observed, + players, + bomb: bomb ? { + state: bomb.state, + countdown: bomb.countdown ? parseFloat(bomb.countdown) : void 0, + position: bomb.position.split(", ").map((pos) => parseFloat(pos)), + player: players.find((player) => player.steamid === bomb.player) || void 0, + site: bomb.state === "planted" || bomb.state === "defused" || bomb.state === "defusing" || bomb.state === "planting" ? _CSGOGSI.findSite( + raw.map.name, + bomb.position.split(", ").map((n) => parseFloat(n)) + ) : null + } : null, + grenades: parseGrenades(raw.grenades), + phase_countdowns: { + phase: raw.phase_countdowns.phase, + phase_ends_in: parseFloat(raw.phase_countdowns.phase_ends_in) + }, + auth: raw.auth, + map: { + mode: raw.map.mode, + name: raw.map.name, + phase: raw.map.phase, + round: raw.map.round, + team_ct: teamCT, + team_t: teamT, + num_matches_to_win_series: raw.map.num_matches_to_win_series, + current_spectators: raw.map.current_spectators, + souvenirs_total: raw.map.souvenirs_total, + round_wins: raw.map.round_wins, + rounds + } + }; + this.current = data; + if (!this.last) { + this.last = data; + this.emit("data", data); + return data; + } + const last = this.last; + if (last.round && data.round && data.round.win_team && !last.round.win_team) { + const winner = data.round.win_team === "CT" ? data.map.team_ct : data.map.team_t; + const loser = data.round.win_team === "CT" ? data.map.team_t : data.map.team_ct; + const oldWinner = data.round.win_team === "CT" ? last.map.team_ct : last.map.team_t; + if (winner.score === oldWinner.score) { + winner.score += 1; + } + const roundScore = { + winner, + loser, + map: data.map, + mapEnd: data.map.phase === "gameover" + }; + this.emit("roundEnd", roundScore); + if (roundScore.mapEnd && last.map.phase !== "gameover") { + this.emit("matchEnd", roundScore); + } + } + if (last.bomb && data.bomb) { + if (last.bomb.state === "planting" && data.bomb.state === "planted") { + this.emit("bombPlant", last.bomb.player); + } else if (last.bomb.state !== "exploded" && data.bomb.state === "exploded") { + this.emit("bombExplode"); + } else if (last.bomb.state !== "defused" && data.bomb.state === "defused") { + this.emit("bombDefuse", last.bomb.player); + } else if (last.bomb.state !== "defusing" && data.bomb.state === "defusing") { + this.emit("defuseStart", data.bomb.player); + } else if (last.bomb.state === "defusing" && data.bomb.state !== "defusing") { + this.emit("defuseStop", last.bomb.player); + } else if (last.bomb.state !== "planting" && data.bomb.state === "planting") { + this.emit("bombPlantStart", last.bomb.player); + } + } + if (data.map.phase === "intermission" && last.map.phase !== "intermission") { + this.emit("intermissionStart"); + } else if (data.map.phase !== "intermission" && last.map.phase === "intermission") { + this.emit("intermissionEnd"); + } + const { phase } = data.phase_countdowns; + if (phase === "freezetime" && last.phase_countdowns.phase !== "freezetime") { + this.emit("freezetimeStart"); + } else if (phase !== "freezetime" && last.phase_countdowns.phase === "freezetime") { + this.emit("freezetimeEnd"); + } + if (phase && last.phase_countdowns.phase) { + if (phase.startsWith("timeout") && !last.phase_countdowns.phase.startsWith("timeout")) { + const team = phase === "timeout_ct" ? teamCT : teamT; + this.emit("timeoutStart", team); + } else if (last.phase_countdowns.phase.startsWith("timeout") && !phase.startsWith("timeout")) { + this.emit("timeoutEnd"); + } + } + const mvp = data.players.find((player) => { + const previousData = last.players.find((previousPlayer) => previousPlayer.steamid === player.steamid); + if (!previousData) + return false; + if (player.stats.mvps > previousData.stats.mvps) + return true; + return false; + }) || null; + if (mvp) { + this.emit("mvp", mvp); + } + this.emit("data", data); + this.last = data; + return data; + }; + digestMIRV = (raw, eventType = "player_death") => { + if (eventType === "player_death") { + const rawKill = raw; + if (!this.last) { + return null; + } + const data2 = rawKill.keys; + const killer = this.last.players.find((player) => player.steamid === data2.attacker.xuid); + const victim2 = this.last.players.find((player) => player.steamid === data2.userid.xuid); + const assister = this.last.players.find( + (player) => player.steamid === data2.assister.xuid && data2.assister.xuid !== "0" + ); + if (!victim2) { + return null; + } + const kill2 = { + killer: killer || (data2.weapon === "trigger_hurt" || data2.weapon === "worldspawn" ? victim2 : null), + victim: victim2, + assister: assister || null, + flashed: data2.assistedflash, + headshot: data2.headshot, + weapon: data2.weapon, + wallbang: data2.penetrated > 0, + attackerblind: data2.attackerblind, + thrusmoke: data2.thrusmoke, + noscope: data2.noscope, + attackerinair: data2.attackerinair + }; + this.emit("kill", kill2); + return kill2; + } + const rawHurt = raw; + if (!this.last) { + return null; + } + const data = rawHurt.keys; + const attacker = this.last.players.find((player) => player.steamid === data.attacker.xuid); + const victim = this.last.players.find((player) => player.steamid === data.userid.xuid); + if (!attacker || !victim) { + return null; + } + const kill = { + attacker, + victim, + health: data.health, + armor: data.armor, + weapon: data.weapon, + dmg_health: data.dmg_health, + dmg_armor: data.dmg_armor, + hitgroup: data.hitgroup + }; + this.emit("hurt", kill); + return kill; + }; + static findSite(mapName, position) { + const realMapName = mapName.substr(mapName.lastIndexOf("/") + 1); + const mapReference = { + de_mirage: (position2) => position2[1] < -600 ? "A" : "B", + de_cache: (position2) => position2[1] > 0 ? "A" : "B", + de_overpass: (position2) => position2[2] > 400 ? "A" : "B", + de_nuke: (position2) => position2[2] > -500 ? "A" : "B", + de_dust2: (position2) => position2[0] > -500 ? "A" : "B", + de_inferno: (position2) => position2[0] > 1400 ? "A" : "B", + de_vertigo: (position2) => position2[0] > -1400 ? "A" : "B", + de_train: (position2) => position2[1] > -450 ? "A" : "B", + de_ancient: (position2) => position2[0] < -500 ? "A" : "B", + de_anubis: (position2) => position2[0] > 0 ? "A" : "B" + }; + if (realMapName in mapReference) { + return mapReference[realMapName](position); + } + return null; + } +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + CSGOGSI, + didTeamWinThatRound, + getHalfFromRound, + mapSteamIDToPlayer, + parseTeam +}); diff --git a/lib/index.mjs b/lib/index.mjs new file mode 100644 index 0000000..9efb80b --- /dev/null +++ b/lib/index.mjs @@ -0,0 +1,514 @@ +// tsc/utils.ts +var parsePlayer = (basePlayer, steamid, team, extensions) => { + const extension = extensions.find((player2) => player2.steamid === steamid); + const player = { + steamid, + name: extension && extension.name || basePlayer.name, + defaultName: basePlayer.name, + clan: basePlayer.clan, + observer_slot: basePlayer.observer_slot, + stats: basePlayer.match_stats, + weapons: Object.entries(basePlayer.weapons).map(([id, weapon]) => ({ ...weapon, id })), + state: { ...basePlayer.state, smoked: basePlayer.state.smoked || 0, adr: 0 }, + position: basePlayer.position.split(", ").map((pos) => Number(pos)), + forward: basePlayer.forward.split(", ").map((pos) => Number(pos)), + team, + avatar: extension && extension.avatar || null, + country: extension && extension.country || null, + realName: extension && extension.realName || null, + extra: extension && extension.extra || {} + }; + return player; +}; +var mapSteamIDToPlayer = (players, teams, extensions) => (steamid) => parsePlayer(players[steamid], steamid, teams[players[steamid].team], extensions); +var parseTeam = (team, orientation, side, extension) => ({ + score: team.score, + logo: extension && extension.logo || null, + consecutive_round_losses: team.consecutive_round_losses, + timeouts_remaining: team.timeouts_remaining, + matches_won_this_series: extension && extension.map_score || team.matches_won_this_series, + side, + name: extension && extension.name || team.name || (side === "CT" ? "Counter-Terrorists" : "Terrorists"), + country: extension && extension.country || null, + id: extension && extension.id || null, + orientation, + extra: extension && extension.extra || {} +}); +var getHalfFromRound = (round, regulationMR, mr) => { + let currentRoundHalf = 1; + if (round <= 2 * regulationMR) { + currentRoundHalf = round <= regulationMR ? 1 : 2; + } else { + const roundInOT = (round - (2 * regulationMR + 1)) % (mr * 2) + 1; + currentRoundHalf = roundInOT <= mr ? 1 : 2; + } + return currentRoundHalf; +}; +var didTeamWinThatRound = (team, round, wonBy, currentRound, regulationMR, mr) => { + const currentRoundHalf = getHalfFromRound(currentRound, regulationMR, mr); + const roundToCheckHalf = getHalfFromRound(round, regulationMR, mr); + return team.side === wonBy === (currentRoundHalf === roundToCheckHalf); +}; +var parseGrenade = (grenade, id) => { + if (grenade.type === "inferno") { + return { + ...grenade, + id, + flames: Object.entries(grenade.flames).map(([id2, position]) => ({ + id: id2, + position: position.split(", ").map(parseFloat) + })), + lifetime: parseFloat(grenade.lifetime) + }; + } + if (grenade.type === "smoke" || grenade.type === "decoy") { + return { + ...grenade, + id, + velocity: grenade.velocity.split(", ").map(parseFloat), + position: grenade.position.split(", ").map(parseFloat), + lifetime: parseFloat(grenade.lifetime), + effecttime: parseFloat(grenade.effecttime) + }; + } + return { + type: grenade.type, + owner: grenade.owner, + id, + velocity: grenade.velocity.split(", ").map(parseFloat), + position: grenade.position.split(", ").map(parseFloat), + lifetime: parseFloat(grenade.lifetime) + }; +}; +var parseGrenades = (grenades) => { + if (!grenades) + return []; + return Object.entries(grenades).map(([id, grenade]) => parseGrenade(grenade, id)); +}; +var getRoundWin = (mapRound, teams, roundWins, round, regulationMR, overtimeMR) => { + let indexRound = round; + if (mapRound > 2 * regulationMR) { + const maxOvertimeRounds = 2 * overtimeMR * Math.floor((mapRound - (2 * regulationMR + 1)) / (2 * overtimeMR)) + 2 * regulationMR; + if (round <= maxOvertimeRounds) { + return null; + } + const roundInOT = (round - (2 * regulationMR + 1)) % (overtimeMR * 2) + 1; + indexRound = roundInOT; + } + const roundOutcome = roundWins[indexRound]; + if (!roundOutcome) + return null; + const winSide = roundOutcome.substr(0, roundOutcome.indexOf("_")).toUpperCase(); + const result = { + team: teams.ct, + round, + side: winSide, + outcome: roundOutcome + }; + if (didTeamWinThatRound(teams.ct, round, winSide, mapRound, regulationMR, overtimeMR)) { + return result; + } + result.team = teams.t; + return result; +}; + +// tsc/index.ts +var CSGOGSI = class _CSGOGSI { + descriptors; + maxListeners; + teams; + damage; + players; + overtimeMR; + regulationMR; + last; + current; + constructor() { + this.descriptors = /* @__PURE__ */ new Map(); + this.teams = { + left: null, + right: null + }; + this.maxListeners = 10; + this.players = []; + this.overtimeMR = 3; + this.regulationMR = 15; + this.damage = []; + } + eventNames = () => { + const listeners = this.descriptors.entries(); + const nonEmptyEvents = []; + for (const entry of listeners) { + if (entry[1] && entry[1].length > 0) { + nonEmptyEvents.push(entry[0]); + } + } + return nonEmptyEvents; + }; + getMaxListeners = () => this.maxListeners; + listenerCount = (eventName) => { + const listeners = this.listeners(eventName); + return listeners.length; + }; + listeners = (eventName) => { + const descriptors = this.descriptors.get(eventName) || []; + return descriptors.map((descriptor) => descriptor.listener); + }; + removeListener = (eventName, listener) => { + return this.off(eventName, listener); + }; + off = (eventName, listener) => { + const descriptors = this.descriptors.get(eventName) || []; + this.descriptors.set( + eventName, + descriptors.filter((descriptor) => descriptor.listener !== listener) + ); + this.emit("removeListener", eventName, listener); + return this; + }; + addListener = (eventName, listener) => { + return this.on(eventName, listener); + }; + on = (eventName, listener) => { + this.emit("newListener", eventName, listener); + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.push({ listener, once: false }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + once = (eventName, listener) => { + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.push({ listener, once: true }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + prependListener = (eventName, listener) => { + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.unshift({ listener, once: false }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + emit = (eventName, arg, arg2) => { + const listeners = this.descriptors.get(eventName); + if (!listeners || listeners.length === 0) + return false; + listeners.forEach((listener) => { + if (listener.once) { + this.descriptors.set( + eventName, + listeners.filter((listenerInArray) => listenerInArray !== listener) + ); + } + listener.listener(arg, arg2); + }); + return true; + }; + prependOnceListener = (eventName, listener) => { + const listOfListeners = [...this.descriptors.get(eventName) || []]; + listOfListeners.unshift({ listener, once: true }); + this.descriptors.set(eventName, listOfListeners); + return this; + }; + removeAllListeners = (eventName) => { + this.descriptors.set(eventName, []); + return this; + }; + setMaxListeners = (n) => { + this.maxListeners = n; + return this; + }; + rawListeners = (eventName) => { + return this.descriptors.get(eventName) || []; + }; + digest = (raw) => { + if (!raw.allplayers || !raw.map || !raw.phase_countdowns) { + return null; + } + this.emit("raw", raw); + let isCTLeft = true; + const examplePlayerT = Object.values(raw.allplayers).find( + ({ observer_slot, team }) => observer_slot !== void 0 && team === "T" + ); + const examplePlayerCT = Object.values(raw.allplayers).find( + ({ observer_slot, team }) => observer_slot !== void 0 && team === "CT" + ); + if (examplePlayerCT && examplePlayerCT.observer_slot !== void 0 && examplePlayerT && examplePlayerT.observer_slot !== void 0) { + if ((examplePlayerCT.observer_slot || 10) > (examplePlayerT.observer_slot || 10)) { + isCTLeft = false; + } + } + const bomb = raw.bomb; + const teamCT = parseTeam( + raw.map.team_ct, + isCTLeft ? "left" : "right", + "CT", + isCTLeft ? this.teams.left : this.teams.right + ); + const teamT = parseTeam( + raw.map.team_t, + isCTLeft ? "right" : "left", + "T", + isCTLeft ? this.teams.right : this.teams.left + ); + const playerMapper = mapSteamIDToPlayer(raw.allplayers, { CT: teamCT, T: teamT }, this.players); + const players = Object.keys(raw.allplayers).map(playerMapper); + const observed = players.find((player) => raw.player && player.steamid === raw.player.steamid) || null; + const observer = { + activity: raw.player?.activity, + spectarget: raw.player?.spectarget, + position: raw.player?.position.split(", ").map((n) => Number(n)), + forward: raw.player?.forward.split(", ").map((n) => Number(n)) + }; + const rounds = []; + if (raw.round && raw.map && raw.map.round_wins) { + let currentRound = raw.map.round + 1; + if (raw.round && raw.round.phase === "over") { + currentRound = raw.map.round; + } + for (let i = 1; i <= currentRound; i++) { + const result = getRoundWin( + currentRound, + { ct: teamCT, t: teamT }, + raw.map.round_wins, + i, + this.regulationMR, + this.overtimeMR + ); + if (!result) + continue; + rounds.push(result); + } + } + if (this.last && this.last.map.name !== raw.map.name) { + this.damage = []; + } + let currentRoundForDamage = raw.map.round + 1; + if (raw.round && raw.round.phase === "over") { + currentRoundForDamage = raw.map.round; + } + let currentRoundDamage = this.damage.find((damage) => damage.round === currentRoundForDamage); + if (!currentRoundDamage) { + currentRoundDamage = { + round: currentRoundForDamage, + players: [] + }; + this.damage.push(currentRoundDamage); + } + if (raw.map.round === 0 && raw.phase_countdowns.phase === "freezetime" || raw.phase_countdowns.phase === "warmup") { + this.damage = []; + } + currentRoundDamage.players = players.map((player) => ({ + steamid: player.steamid, + damage: player.state.round_totaldmg + })); + for (const player of players) { + const { current, damage } = this; + if (!current) + continue; + const damageForRound = damage.filter((damageEntry) => damageEntry.round < currentRoundForDamage); + if (damageForRound.length === 0) + continue; + const damageEntries = damageForRound.map((damageEntry) => { + const playerDamageEntry = damageEntry.players.find( + (playerDamage) => playerDamage.steamid === player.steamid + ); + return playerDamageEntry ? playerDamageEntry.damage : 0; + }); + const adr = damageEntries.reduce((a, b) => a + b, 0) / (raw.map.round || 1); + player.state.adr = Math.floor(adr); + } + const data = { + provider: raw.provider, + observer, + round: raw.round ? { + phase: raw.round.phase, + bomb: raw.round.bomb, + win_team: raw.round.win_team + } : null, + player: observed, + players, + bomb: bomb ? { + state: bomb.state, + countdown: bomb.countdown ? parseFloat(bomb.countdown) : void 0, + position: bomb.position.split(", ").map((pos) => parseFloat(pos)), + player: players.find((player) => player.steamid === bomb.player) || void 0, + site: bomb.state === "planted" || bomb.state === "defused" || bomb.state === "defusing" || bomb.state === "planting" ? _CSGOGSI.findSite( + raw.map.name, + bomb.position.split(", ").map((n) => parseFloat(n)) + ) : null + } : null, + grenades: parseGrenades(raw.grenades), + phase_countdowns: { + phase: raw.phase_countdowns.phase, + phase_ends_in: parseFloat(raw.phase_countdowns.phase_ends_in) + }, + auth: raw.auth, + map: { + mode: raw.map.mode, + name: raw.map.name, + phase: raw.map.phase, + round: raw.map.round, + team_ct: teamCT, + team_t: teamT, + num_matches_to_win_series: raw.map.num_matches_to_win_series, + current_spectators: raw.map.current_spectators, + souvenirs_total: raw.map.souvenirs_total, + round_wins: raw.map.round_wins, + rounds + } + }; + this.current = data; + if (!this.last) { + this.last = data; + this.emit("data", data); + return data; + } + const last = this.last; + if (last.round && data.round && data.round.win_team && !last.round.win_team) { + const winner = data.round.win_team === "CT" ? data.map.team_ct : data.map.team_t; + const loser = data.round.win_team === "CT" ? data.map.team_t : data.map.team_ct; + const oldWinner = data.round.win_team === "CT" ? last.map.team_ct : last.map.team_t; + if (winner.score === oldWinner.score) { + winner.score += 1; + } + const roundScore = { + winner, + loser, + map: data.map, + mapEnd: data.map.phase === "gameover" + }; + this.emit("roundEnd", roundScore); + if (roundScore.mapEnd && last.map.phase !== "gameover") { + this.emit("matchEnd", roundScore); + } + } + if (last.bomb && data.bomb) { + if (last.bomb.state === "planting" && data.bomb.state === "planted") { + this.emit("bombPlant", last.bomb.player); + } else if (last.bomb.state !== "exploded" && data.bomb.state === "exploded") { + this.emit("bombExplode"); + } else if (last.bomb.state !== "defused" && data.bomb.state === "defused") { + this.emit("bombDefuse", last.bomb.player); + } else if (last.bomb.state !== "defusing" && data.bomb.state === "defusing") { + this.emit("defuseStart", data.bomb.player); + } else if (last.bomb.state === "defusing" && data.bomb.state !== "defusing") { + this.emit("defuseStop", last.bomb.player); + } else if (last.bomb.state !== "planting" && data.bomb.state === "planting") { + this.emit("bombPlantStart", last.bomb.player); + } + } + if (data.map.phase === "intermission" && last.map.phase !== "intermission") { + this.emit("intermissionStart"); + } else if (data.map.phase !== "intermission" && last.map.phase === "intermission") { + this.emit("intermissionEnd"); + } + const { phase } = data.phase_countdowns; + if (phase === "freezetime" && last.phase_countdowns.phase !== "freezetime") { + this.emit("freezetimeStart"); + } else if (phase !== "freezetime" && last.phase_countdowns.phase === "freezetime") { + this.emit("freezetimeEnd"); + } + if (phase && last.phase_countdowns.phase) { + if (phase.startsWith("timeout") && !last.phase_countdowns.phase.startsWith("timeout")) { + const team = phase === "timeout_ct" ? teamCT : teamT; + this.emit("timeoutStart", team); + } else if (last.phase_countdowns.phase.startsWith("timeout") && !phase.startsWith("timeout")) { + this.emit("timeoutEnd"); + } + } + const mvp = data.players.find((player) => { + const previousData = last.players.find((previousPlayer) => previousPlayer.steamid === player.steamid); + if (!previousData) + return false; + if (player.stats.mvps > previousData.stats.mvps) + return true; + return false; + }) || null; + if (mvp) { + this.emit("mvp", mvp); + } + this.emit("data", data); + this.last = data; + return data; + }; + digestMIRV = (raw, eventType = "player_death") => { + if (eventType === "player_death") { + const rawKill = raw; + if (!this.last) { + return null; + } + const data2 = rawKill.keys; + const killer = this.last.players.find((player) => player.steamid === data2.attacker.xuid); + const victim2 = this.last.players.find((player) => player.steamid === data2.userid.xuid); + const assister = this.last.players.find( + (player) => player.steamid === data2.assister.xuid && data2.assister.xuid !== "0" + ); + if (!victim2) { + return null; + } + const kill2 = { + killer: killer || (data2.weapon === "trigger_hurt" || data2.weapon === "worldspawn" ? victim2 : null), + victim: victim2, + assister: assister || null, + flashed: data2.assistedflash, + headshot: data2.headshot, + weapon: data2.weapon, + wallbang: data2.penetrated > 0, + attackerblind: data2.attackerblind, + thrusmoke: data2.thrusmoke, + noscope: data2.noscope, + attackerinair: data2.attackerinair + }; + this.emit("kill", kill2); + return kill2; + } + const rawHurt = raw; + if (!this.last) { + return null; + } + const data = rawHurt.keys; + const attacker = this.last.players.find((player) => player.steamid === data.attacker.xuid); + const victim = this.last.players.find((player) => player.steamid === data.userid.xuid); + if (!attacker || !victim) { + return null; + } + const kill = { + attacker, + victim, + health: data.health, + armor: data.armor, + weapon: data.weapon, + dmg_health: data.dmg_health, + dmg_armor: data.dmg_armor, + hitgroup: data.hitgroup + }; + this.emit("hurt", kill); + return kill; + }; + static findSite(mapName, position) { + const realMapName = mapName.substr(mapName.lastIndexOf("/") + 1); + const mapReference = { + de_mirage: (position2) => position2[1] < -600 ? "A" : "B", + de_cache: (position2) => position2[1] > 0 ? "A" : "B", + de_overpass: (position2) => position2[2] > 400 ? "A" : "B", + de_nuke: (position2) => position2[2] > -500 ? "A" : "B", + de_dust2: (position2) => position2[0] > -500 ? "A" : "B", + de_inferno: (position2) => position2[0] > 1400 ? "A" : "B", + de_vertigo: (position2) => position2[0] > -1400 ? "A" : "B", + de_train: (position2) => position2[1] > -450 ? "A" : "B", + de_ancient: (position2) => position2[0] < -500 ? "A" : "B", + de_anubis: (position2) => position2[0] > 0 ? "A" : "B" + }; + if (realMapName in mapReference) { + return mapReference[realMapName](position); + } + return null; + } +}; +export { + CSGOGSI, + didTeamWinThatRound, + getHalfFromRound, + mapSteamIDToPlayer, + parseTeam +}; diff --git a/package-lock.json b/package-lock.json index 8adc374..ab52d32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,19 @@ { "name": "csgogsi", - "version": "3.0.1", + "version": "3.0.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "csgogsi", - "version": "3.0.1", + "version": "3.0.3", "license": "MIT", "devDependencies": { + "@eslint/js": "^9.2.0", "@types/jest": "^29.5.6", "@types/lodash.merge": "^4.6.6", "@types/node": "^18.18.6", - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", - "eslint": "^8.52.0", + "eslint": "^8.57.0", "istanbul-badges-readme": "^1.2.1", "jest": "^29.7.0", "jest-ts-webcompat-resolver": "^1.0.0", @@ -23,16 +22,9 @@ "ts-jest": "^29.1.1", "ts-node": "^9.1.1", "ts-toolbelt": "^9.6.0", - "typescript": "^4.5.2" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "tsup": "^8.0.2", + "typescript": "^5.4.5", + "typescript-eslint": "^7.9.0" } }, "node_modules/@ampproject/remapping": { @@ -667,6 +659,374 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -683,18 +1043,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -721,9 +1081,9 @@ "dev": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -748,22 +1108,22 @@ } }, "node_modules/@eslint/js": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", - "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.2.0.tgz", + "integrity": "sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -784,11 +1144,107 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1175,6 +1631,224 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1240,6 +1914,12 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.8.tgz", @@ -1283,12 +1963,6 @@ "pretty-format": "^29.0.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", - "dev": true - }, "node_modules/@types/lodash": { "version": "4.14.168", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", @@ -1310,12 +1984,6 @@ "integrity": "sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", - "dev": true - }, "node_modules/@types/stack-utils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.2.tgz", @@ -1338,33 +2006,31 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", - "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", + "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/type-utils": "6.9.0", - "@typescript-eslint/utils": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/type-utils": "7.9.0", + "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -1372,42 +2038,27 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", - "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -1416,16 +2067,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1433,25 +2084,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", - "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", + "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/utils": "7.9.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -1460,12 +2111,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1473,21 +2124,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1499,14 +2151,35 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -1515,56 +2188,38 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", - "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", + "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.9.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1578,9 +2233,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1665,6 +2320,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -1815,6 +2476,18 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1896,6 +2569,30 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "node_modules/bundle-require": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.1.0.tgz", + "integrity": "sha512-FeArRFM+ziGkRViKRnSTbHZc35dgmR9yNog05Kn0+ItI59pOAISGvnnIwW1WgFZQW59IxD9QpJnUPkdIPfZuXg==", + "dev": true, + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.17" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1940,23 +2637,59 @@ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=10" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=10" + "node": ">= 6" } }, "node_modules/ci-info": { @@ -2028,6 +2761,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2178,6 +2920,12 @@ "node": ">=6.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/electron-to-chromium": { "version": "1.4.565", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.565.tgz", @@ -2211,6 +2959,44 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2230,16 +3016,16 @@ } }, "node_modules/eslint": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", - "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.52.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -2312,6 +3098,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2347,9 +3142,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2625,9 +3420,9 @@ } }, "node_modules/flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", @@ -2635,15 +3430,43 @@ "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2822,9 +3645,9 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -2905,6 +3728,18 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -3082,6 +3917,24 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -3671,6 +4524,15 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3778,12 +4640,33 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -3808,6 +4691,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3914,12 +4803,32 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", + "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3959,6 +4868,15 @@ "node": ">=8" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3984,17 +4902,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -4114,6 +5032,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -4162,6 +5105,41 @@ "node": ">=8" } }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4276,6 +5254,18 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4357,6 +5347,41 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4504,6 +5529,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4516,6 +5556,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -4546,6 +5599,74 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.3.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.15.tgz", + "integrity": "sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.11.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4590,6 +5711,27 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -4610,25 +5752,49 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" } }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, "node_modules/ts-jest": { "version": "29.1.1", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", @@ -4719,6 +5885,67 @@ "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", "dev": true }, + "node_modules/tsup": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.0.2.tgz", + "integrity": "sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==", + "dev": true, + "dependencies": { + "bundle-require": "^4.0.0", + "cac": "^6.7.12", + "chokidar": "^3.5.1", + "debug": "^4.3.1", + "esbuild": "^0.19.2", + "execa": "^5.0.0", + "globby": "^11.0.3", + "joycon": "^3.0.1", + "postcss-load-config": "^4.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.0.2", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.20.3", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tsup/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4753,16 +5980,42 @@ } }, "node_modules/typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.9.0.tgz", + "integrity": "sha512-7iTn9c10teHHCys5Ud/yaJntXZrjt3h2mrx3feJGBOLgQkF3TB1X89Xs3aVQ/GgdXRAXpk2bPTdpRwHP4YkUow==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.9.0", + "@typescript-eslint/parser": "7.9.0", + "@typescript-eslint/utils": "7.9.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/update-browserslist-db": { @@ -4827,6 +6080,23 @@ "makeerror": "1.0.12" } }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4842,6 +6112,15 @@ "node": ">= 8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4859,6 +6138,24 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4893,6 +6190,18 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -4943,12 +6252,6 @@ } }, "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, "@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -5433,6 +6736,167 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "dev": true, + "optional": true + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -5443,15 +6907,15 @@ } }, "@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -5472,9 +6936,9 @@ "dev": true }, "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -5492,19 +6956,19 @@ } }, "@eslint/js": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", - "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.2.0.tgz", + "integrity": "sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" } }, @@ -5515,11 +6979,76 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -5803,26 +7332,145 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "dev": true, + "optional": true }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "dev": true, + "optional": true }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "@rollup/rollup-win32-x64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } + "optional": true }, "@sinclair/typebox": { "version": "0.27.8", @@ -5889,6 +7537,12 @@ "@babel/types": "^7.20.7" } }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.8.tgz", @@ -5932,12 +7586,6 @@ "pretty-format": "^29.0.0" } }, - "@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", - "dev": true - }, "@types/lodash": { "version": "4.14.168", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", @@ -5959,12 +7607,6 @@ "integrity": "sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==", "dev": true }, - "@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", - "dev": true - }, "@types/stack-utils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.2.tgz", @@ -5987,136 +7629,125 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", - "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", + "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/type-utils": "6.9.0", - "@typescript-eslint/utils": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/type-utils": "7.9.0", + "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/parser": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", - "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" } }, "@typescript-eslint/type-utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", - "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", + "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/utils": "7.9.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "dependencies": { - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "balanced-match": "^1.0.0" } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true } } }, "@typescript-eslint/utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", - "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", + "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", - "semver": "^7.5.4" - }, - "dependencies": { - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0" } }, "@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.9.0", + "eslint-visitor-keys": "^3.4.3" } }, "@ungap/structured-clone": { @@ -6126,9 +7757,9 @@ "dev": true }, "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { @@ -6182,6 +7813,12 @@ "color-convert": "^2.0.1" } }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -6304,6 +7941,12 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -6359,6 +8002,21 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "bundle-require": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.1.0.tgz", + "integrity": "sha512-FeArRFM+ziGkRViKRnSTbHZc35dgmR9yNog05Kn0+ItI59pOAISGvnnIwW1WgFZQW59IxD9QpJnUPkdIPfZuXg==", + "dev": true, + "requires": { + "load-tsconfig": "^0.2.3" + } + }, + "cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -6393,6 +8051,33 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -6443,6 +8128,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6551,6 +8242,12 @@ "esutils": "^2.0.2" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "electron-to-chromium": { "version": "1.4.565", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.565.tgz", @@ -6578,6 +8275,37 @@ "is-arrayish": "^0.2.1" } }, + "esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -6591,16 +8319,16 @@ "dev": true }, "eslint": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", - "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.52.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -6636,6 +8364,12 @@ "text-table": "^0.2.0" }, "dependencies": { + "@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -6659,9 +8393,9 @@ } }, "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -6884,9 +8618,9 @@ } }, "flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { "flatted": "^3.2.9", @@ -6895,11 +8629,29 @@ } }, "flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7026,9 +8778,9 @@ "dev": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "import-fresh": { @@ -7087,6 +8839,15 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -7215,6 +8976,16 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -7671,6 +9442,12 @@ } } }, + "joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7754,12 +9531,24 @@ "type-check": "~0.4.0" } }, + "lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -7781,6 +9570,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7862,12 +9657,29 @@ "brace-expansion": "^1.1.7" } }, + "minipass": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", + "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7901,6 +9713,12 @@ "path-key": "^3.0.0" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -7920,17 +9738,17 @@ } }, "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" } }, "p-limit": { @@ -8013,6 +9831,24 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true + } + } + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -8046,6 +9882,16 @@ "find-up": "^4.0.0" } }, + "postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "requires": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8111,6 +9957,15 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8164,6 +10019,32 @@ "glob": "^7.1.3" } }, + "rollup": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", + "@types/estree": "1.0.5", + "fsevents": "~2.3.2" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -8272,6 +10153,17 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -8281,6 +10173,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -8299,6 +10200,54 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.3.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.15.tgz", + "integrity": "sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.11.0" + } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8331,6 +10280,24 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -8352,13 +10319,34 @@ "is-number": "^7.0.0" } }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, "ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "requires": {} }, + "ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, "ts-jest": { "version": "29.1.1", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", @@ -8406,6 +10394,39 @@ "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", "dev": true }, + "tsup": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.0.2.tgz", + "integrity": "sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==", + "dev": true, + "requires": { + "bundle-require": "^4.0.0", + "cac": "^6.7.12", + "chokidar": "^3.5.1", + "debug": "^4.3.1", + "esbuild": "^0.19.2", + "execa": "^5.0.0", + "globby": "^11.0.3", + "joycon": "^3.0.1", + "postcss-load-config": "^4.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.0.2", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.20.3", + "tree-kill": "^1.2.2" + }, + "dependencies": { + "source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "requires": { + "whatwg-url": "^7.0.0" + } + } + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8428,11 +10449,22 @@ "dev": true }, "typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true }, + "typescript-eslint": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.9.0.tgz", + "integrity": "sha512-7iTn9c10teHHCys5Ud/yaJntXZrjt3h2mrx3feJGBOLgQkF3TB1X89Xs3aVQ/GgdXRAXpk2bPTdpRwHP4YkUow==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "7.9.0", + "@typescript-eslint/parser": "7.9.0", + "@typescript-eslint/utils": "7.9.0" + } + }, "update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -8472,6 +10504,23 @@ "makeerror": "1.0.12" } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8481,6 +10530,12 @@ "isexe": "^2.0.0" } }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -8492,6 +10547,17 @@ "strip-ansi": "^6.0.0" } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8520,6 +10586,12 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "yaml": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "dev": true + }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 953e151..9148597 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,16 @@ { "name": "csgogsi", - "version": "3.0.3", + "version": "3.0.4", "description": "", - "type": "module", - "main": "./lib/cjs/index.js", - "module": "./lib/esm/index.js", - "exports": { - "import": "./lib/esm/index.js", - "default": "./lib/cjs/index.js" - }, + "main": "lib/index.js", + "module": "lib/index.mjs", + "types": "lib/index.d.ts", "devDependencies": { + "@eslint/js": "^9.2.0", "@types/jest": "^29.5.6", "@types/lodash.merge": "^4.6.6", "@types/node": "^18.18.6", - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", - "eslint": "^8.52.0", + "eslint": "^8.57.0", "istanbul-badges-readme": "^1.2.1", "jest": "^29.7.0", "jest-ts-webcompat-resolver": "^1.0.0", @@ -24,19 +19,18 @@ "ts-jest": "^29.1.1", "ts-node": "^9.1.1", "ts-toolbelt": "^9.6.0", - "typescript": "^4.5.2" + "tsup": "^8.0.2", + "typescript": "^5.4.5", + "typescript-eslint": "^7.9.0" }, "scripts": { "test": "jest --coverage", "make-badges": "istanbul-badges-readme", - "transpile:cjs": "tsc -p tsconfig.json", - "transpile:esm": "tsc -p tsconfig.esm.json", - "transpile:all": "npm run transpile:cjs && npm run transpile:esm", - "transpile": "npm run transpile:all && npm run post-compile && npm run move-build", - "move-build": "cp tsc/*.d.ts lib/cjs && cp lib/cjs/*.d.ts lib/esm", - "lint": "eslint . --ext .ts", - "prettier-format": "prettier --config .prettierrc --write **/*.ts", - "post-compile": "npm run prettier-format && npm run lint && npm test && npm run make-badges" + "rollup": "tsup tsc/index.ts --format cjs,esm --dts -d lib", + "build": "npm run pre-compile && npm run rollup", + "lint": "eslint .", + "prettier-format": "prettier --config .prettierrc --write tsc/*.ts", + "pre-compile": "npm run prettier-format && npm run lint && npm test && npm run make-badges" }, "repository": { "type": "git", diff --git a/tsc/index.ts b/tsc/index.ts index 6f4f7a5..0f9c443 100644 --- a/tsc/index.ts +++ b/tsc/index.ts @@ -1,4 +1,4 @@ -import { +import type { CSGO, CSGORaw, Events, @@ -13,8 +13,8 @@ import { EventNames, BaseEvents } from './interfaces'; -import { RawHurt } from './mirv'; -import { DigestMirvType, HurtEvent } from './parsed'; +import type { RawHurt } from './mirv'; +import type { DigestMirvType, HurtEvent } from './parsed'; import { getRoundWin, mapSteamIDToPlayer, @@ -504,27 +504,27 @@ class CSGOGSI { static findSite(mapName: string, position: number[]) { const realMapName = mapName.substr(mapName.lastIndexOf('/') + 1); const mapReference: { [mapName: string]: (position: number[]) => 'A' | 'B' } = { - de_mirage: position => (position[1] < -600 ? 'A' : 'B'), - de_cache: position => (position[1] > 0 ? 'A' : 'B'), - de_overpass: position => (position[2] > 400 ? 'A' : 'B'), - de_nuke: position => (position[2] > -500 ? 'A' : 'B'), - de_dust2: position => (position[0] > -500 ? 'A' : 'B'), - de_inferno: position => (position[0] > 1400 ? 'A' : 'B'), - de_vertigo: position => (position[0] > -1400 ? 'A' : 'B'), - de_train: position => (position[1] > -450 ? 'A' : 'B'), - de_ancient: position => (position[0] < -500 ? 'A' : 'B'), - de_anubis: position => (position[0] > 0 ? 'A' : 'B') + de_mirage: position => (position[1]! < -600 ? 'A' : 'B'), + de_cache: position => (position[1]! > 0 ? 'A' : 'B'), + de_overpass: position => (position[2]! > 400 ? 'A' : 'B'), + de_nuke: position => (position[2]! > -500 ? 'A' : 'B'), + de_dust2: position => (position[0]! > -500 ? 'A' : 'B'), + de_inferno: position => (position[0]! > 1400 ? 'A' : 'B'), + de_vertigo: position => (position[0]! > -1400 ? 'A' : 'B'), + de_train: position => (position[1]! > -450 ? 'A' : 'B'), + de_ancient: position => (position[0]! < -500 ? 'A' : 'B'), + de_anubis: position => (position[0]! > 0 ? 'A' : 'B') }; if (realMapName in mapReference) { - return mapReference[realMapName](position); + return mapReference[realMapName]!(position); } return null; } } -export { CSGOGSI, mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound, RoundDamage }; +export { CSGOGSI, mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound, type RoundDamage }; -export { +export type { CSGO, CSGORaw, Side, diff --git a/tsc/utils.ts b/tsc/utils.ts index fcbab2e..6262272 100644 --- a/tsc/utils.ts +++ b/tsc/utils.ts @@ -1,4 +1,4 @@ -import { +import type { PlayerRaw, Team, PlayerExtension, @@ -11,8 +11,8 @@ import { RoundInfo, RoundWins } from '.'; -import { GrenadeRaw } from './csgo'; -import { Grenade } from './parsed'; +import type { GrenadeRaw } from './csgo'; +import type { Grenade } from './parsed'; const parsePlayer = (basePlayer: PlayerRaw, steamid: string, team: Team, extensions: PlayerExtension[]) => { const extension = extensions.find(player => player.steamid === steamid); @@ -39,7 +39,7 @@ const parsePlayer = (basePlayer: PlayerRaw, steamid: string, team: Team, extensi export const mapSteamIDToPlayer = (players: PlayersRaw, teams: { CT: Team; T: Team }, extensions: PlayerExtension[]) => (steamid: string) => - parsePlayer(players[steamid], steamid, teams[players[steamid].team], extensions); + parsePlayer(players[steamid]!, steamid, teams[players[steamid]!.team], extensions); export const parseTeam = ( team: TeamRaw, diff --git a/tsconfig.esm.json b/tsconfig.esm.json deleted file mode 100644 index e1c208d..0000000 --- a/tsconfig.esm.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "outDir": "./lib/esm", - "rootDir": "./tsc", - "strict": true, - "esModuleInterop": true, - "moduleResolution": "node" - }, - "exclude": [ - "__tests__/**/*.ts", - "compiled/**/*.ts", - "lib/**/*.ts", - "./jest.config.ts" - ], -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 7057b2b..32ffe4c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,21 @@ { "compilerOptions": { - "target": "ES2019", - "module": "commonjs", - "lib": [ - "es2019" - ], - "declaration": true, - "outDir": "./lib/cjs", - "rootDir": "./tsc", + /* Base Options: */ + "esModuleInterop": true, + "skipLibCheck": true, + "target": "es2022", + "verbatimModuleSyntax": true, + "allowJs": true, + "resolveJsonModule": true, + "moduleDetection": "force", + /* Strictness */ "strict": true, - "moduleResolution": "node", - "esModuleInterop": true - }, - "exclude": [ - "__tests__/**/*.ts", - "compiled/**/*.ts", - "lib/**/*.ts", - "./jest.config.ts" - ], + "noUncheckedIndexedAccess": true, + /* If NOT transpiling with TypeScript: */ + "moduleResolution": "Bundler", + "module": "ESNext", + "noEmit": true, + /* If your code runs in the DOM: */ + "lib": ["es2022", "dom", "dom.iterable"], + } } \ No newline at end of file diff --git a/types/csgo.d.ts b/types/csgo.d.ts deleted file mode 100644 index c185744..0000000 --- a/types/csgo.d.ts +++ /dev/null @@ -1,151 +0,0 @@ -export type Side = 'CT' | 'T'; -export type RoundOutcome = 'ct_win_elimination' | 't_win_elimination' | 'ct_win_time' | 'ct_win_defuse' | 't_win_bomb'; - -export type WeaponType = 'Knife' | 'Pistol' | 'Grenade' | 'Rifle' | 'SniperRifle' | 'C4' | 'Submachine Gun'; - -export interface WeaponRaw { - name: string; - paintkit: string; - type?: WeaponType; - ammo_clip?: number; - ammo_clip_max?: number; - ammo_reserve?: number; - state: 'active' | 'holstered'; -} - -export interface TeamRaw { - score: number; - consecutive_round_losses: number; - timeouts_remaining: number; - matches_won_this_series: number; - name?: string; - flag?: string; -} - -export interface PlayerRaw { - steamid?: string; - name: string; - clan?: string; - observer_slot?: number; - team: Side; - match_stats: { - kills: number; - assists: number; - deaths: number; - mvps: number; - score: number; - }; - weapons: { - [key: string]: WeaponRaw; - }; - state: { - health: number; - armor: number; - helmet: boolean; - defusekit?: boolean; - flashed: number; - smoked?: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - }; - position: string; - forward: string; -} - -export interface PlayerObservedRaw { - steamid: string; - clan?: string; - name: string; - observer_slot?: number; - team?: Side; - activity: 'playing' | 'textinput' | 'menu'; - state: { - health: number; - armor: number; - helmet: boolean; - flashed: number; - smoked: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - }; - spectarget: 'free' | string; - position: string; - forward: string; -} - -export interface PlayersRaw { - [key: string]: PlayerRaw; -} - -export interface Provider { - name: 'Counter-Strike: Global Offensive'; - appid: 730; - version: number; - steamid: string; - timestamp: number; -} - -export interface MapRaw { - mode: 'competitive'; - name: string; - phase: 'warmup' | 'live' | 'intermission' | 'gameover'; - round: number; - team_ct: TeamRaw; - team_t: TeamRaw; - num_matches_to_win_series: number; - current_spectators: number; - souvenirs_total: number; - round_wins: { - [key: string]: RoundOutcome; - }; -} - -export interface RoundRaw { - phase: 'freezetime' | 'live' | 'over'; - bomb?: 'planted' | 'exploded' | 'defused'; - win_team?: Side; -} - -export interface BombRaw { - state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; - countdown?: string; - player?: string; - position: string; -} -export interface PhaseRaw { - phase?: 'freezetime' | 'bomb' | 'warmup' | 'live' | 'over' | 'defuse' | 'paused' | 'timeout_ct' | 'timeout_t'; - phase_ends_in: string; -} - -export interface CSGORaw { - provider: Provider; - map?: MapRaw; - round?: RoundRaw; - player?: PlayerObservedRaw; - allplayers?: PlayersRaw; - bomb?: BombRaw; - grenades?: { - [key: string]: any; - /*{ - owner:number, - position:string, - velocity:string, - lifetime:string, - type:string, - effecttime?:string - }*/ - }; - previously?: any; - phase_countdowns?: PhaseRaw; - auth?: { - token: string; - }; -} diff --git a/types/events.d.ts b/types/events.d.ts deleted file mode 100644 index 1e83240..0000000 --- a/types/events.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as I from './interfaces'; - -export interface Events { - raw: (data: I.CSGORaw) => void; - data: (data: I.CSGO) => void; - roundEnd: (team: I.Score) => void; - matchEnd: (score: I.Score) => void; - kill: (kill: I.KillEvent) => void; - hurt: (kill: I.HurtEvent) => void; - timeoutStart: (team: any) => void; - timeoutEnd: () => void; - /*roundStart: (round: number) => void, - warmupStart: () => void, - warmupEnd: () => void,*/ - mvp: (player: I.Player) => void; - freezetimeStart: () => void; - freezetimeEnd: () => void; - intermissionStart: () => void; - intermissionEnd: () => void; - defuseStart: (player: I.Player) => void; - defuseStop: (player: I.Player) => void; - bombPlantStart: (player: I.Player) => void; - bombPlant: (player: I.Player) => void; - bombExplode: () => void; - bombDefuse: (player: I.Player) => void; - newListener: (eventName: K, listener: Events[K]) => void; - removeListener: (eventName: K, listener: Events[K]) => void; -} - -export type AnyEventName = T | (string & {}); - -export type BaseEvents = keyof Events; - -export type EventNames = AnyEventName; - -export type EmptyListener = () => void; - -export type Callback = K extends BaseEvents ? Events[K] | EmptyListener : EmptyListener; diff --git a/types/index.d.ts b/types/index.d.ts deleted file mode 100644 index c3b8626..0000000 --- a/types/index.d.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { - CSGO, - CSGORaw, - Events, - KillEvent, - PlayerExtension, - RawKill, - Score, - TeamExtension, - Callback, - EventNames, - BaseEvents -} from './interfaces'; -import { RawHurt } from './mirv'; -import { DigestMirvType, HurtEvent } from './parsed'; -import { mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound } from './utils.js'; -interface EventDescriptor { - listener: Events[BaseEvents]; - once: boolean; -} -declare type RoundPlayerDamage = { - steamid: string; - damage: number; -}; -declare type RoundDamage = { - round: number; - players: RoundPlayerDamage[]; -}; -declare class CSGOGSI { - private descriptors; - private maxListeners; - teams: { - left: TeamExtension | null; - right: TeamExtension | null; - }; - damage: RoundDamage[]; - players: PlayerExtension[]; - overtimeMR: number; - regulationMR: number; - last?: CSGO; - current?: CSGO; - constructor(); - eventNames: () => EventNames[]; - getMaxListeners: () => number; - listenerCount: (eventName: EventNames) => number; - listeners: ( - eventName: EventNames - ) => ( - | ((data: CSGORaw) => void) - | ((data: CSGO) => void) - | ((team: Score) => void) - | ((score: Score) => void) - | ((kill: KillEvent) => void) - | ((kill: HurtEvent) => void) - | ((team: any) => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | (() => void) - | (() => void) - | (() => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | ((player: import('./parsed').Player) => void) - | (() => void) - | ((player: import('./parsed').Player) => void) - | ((eventName: K, listener: Events[K]) => void) - | ((eventName: K_1, listener: Events[K_1]) => void) - )[]; - removeListener: (eventName: K, listener: Callback) => this; - off: (eventName: K, listener: Callback) => this; - addListener: (eventName: K, listener: Callback) => this; - on: (eventName: K, listener: Callback) => this; - once: (eventName: K, listener: Callback) => this; - prependListener: (eventName: K, listener: Callback) => this; - emit: (eventName: EventNames, arg?: any, arg2?: any) => boolean; - prependOnceListener: (eventName: K, listener: Callback) => this; - removeAllListeners: (eventName: EventNames) => this; - setMaxListeners: (n: number) => this; - rawListeners: (eventName: EventNames) => EventDescriptor[]; - digest: (raw: CSGORaw) => CSGO | null; - digestMIRV: (raw: RawKill | RawHurt, eventType?: string) => DigestMirvType; - static findSite(mapName: string, position: number[]): 'A' | 'B' | null; -} -export { CSGOGSI, mapSteamIDToPlayer, parseTeam, getHalfFromRound, didTeamWinThatRound, RoundDamage }; -export { - CSGO, - CSGORaw, - Side, - RoundOutcome, - WeaponType, - Observer, - RawHurt, - WeaponRaw, - TeamRaw, - PlayerRaw, - PlayerObservedRaw, - PlayersRaw, - Provider, - HurtEvent, - RoundWins, - MapRaw, - RoundRaw, - BombRaw, - PhaseRaw, - Events, - Team, - Player, - Bomb, - Map, - Round, - Score, - KillEvent, - RawKill, - TeamExtension, - RoundInfo, - PlayerExtension, - Orientation -} from './interfaces'; diff --git a/types/interfaces.d.ts b/types/interfaces.d.ts deleted file mode 100644 index 432580a..0000000 --- a/types/interfaces.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -export * from './csgo'; -export * from './events'; -export * from './parsed'; -export * from './mirv'; - -export interface TeamExtension { - id: string; - name: string; - country: string | null; - logo: string | null; - map_score: number; - extra: Record; -} - -export interface PlayerExtension { - id: string; - name: string; - steamid: string; - realName: string | null; - country: string | null; - avatar: string | null; - extra: Record; -} diff --git a/types/mirv.d.ts b/types/mirv.d.ts deleted file mode 100644 index 96018b7..0000000 --- a/types/mirv.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -export interface RawKill { - name: 'player_death'; - clientTime: number; - keys: { - userid: { - value: number; - xuid: string; - }; - attacker: { - value: number; - xuid: string; - }; - assister: { - value: number; - xuid: string; - }; - assistedflash: boolean; - weapon: string; - weapon_itemid: string; - weapon_fauxitemid: string; - weapon_originalowner_xuid: string; - headshot: boolean; - dominated: number; - revenge: number; - wipe: number; - attackerblind: boolean; - thrusmoke: boolean; - noscope: boolean; - penetrated: number; - noreplay: boolean; - attackerinair: boolean; - }; -} - -export interface RawHurt { - name: 'player_hurt'; - clientTime: number; - keys: { - userid: { - value: number; - xuid: string; - }; - attacker: { - value: number; - xuid: string; - }; - health: number; - armor: number; - weapon: string; - dmg_health: number; - dmg_armor: number; - hitgroup: number; - }; -} diff --git a/types/parsed.d.ts b/types/parsed.d.ts deleted file mode 100644 index 8c0913d..0000000 --- a/types/parsed.d.ts +++ /dev/null @@ -1,153 +0,0 @@ -import * as I from './interfaces'; - -export type Orientation = 'left' | 'right'; - -export interface Team { - logo: string | null; - score: number; - consecutive_round_losses: number; - timeouts_remaining: number; - matches_won_this_series: number; - side: I.Side; - name: string; - country: string | null; - id: string | null; - orientation: Orientation; - extra: Record; -} - -export interface RoundInfo { - team: Team; - round: number; - side: I.Side; - outcome: I.RoundOutcome; -} -export interface Player { - steamid: string; - name: string; - defaultName: string; - clan?: string; - observer_slot?: number; - team: Team; - stats: { - kills: number; - assists: number; - deaths: number; - mvps: number; - score: number; - }; - weapons: { - [key: string]: I.WeaponRaw; - }; - state: { - health: number; - armor: number; - helmet: boolean; - defusekit?: boolean; - flashed: number; - smoked: number; - burning: number; - money: number; - round_kills: number; - round_killhs: number; - round_totaldmg: number; - equip_value: number; - adr: number; - }; - position: number[]; - forward: number[]; - avatar: string | null; - country: string | null; - realName: string | null; - extra: Record; -} - -export type RoundWins = { - [key: string]: I.RoundOutcome; -}; -export interface Bomb { - state: 'carried' | 'planted' | 'dropped' | 'defused' | 'defusing' | 'planting' | 'exploded'; - countdown?: string; - player?: Player; - site: 'A' | 'B' | null; - position: number[]; -} - -export interface Map { - mode: string; - name: string; - phase: 'warmup' | 'live' | 'intermission' | 'gameover'; - round: number; - team_ct: Team; - team_t: Team; - num_matches_to_win_series: number; - current_spectators: number; - souvenirs_total: number; - round_wins: RoundWins; - rounds: I.RoundInfo[]; -} - -export interface Round { - phase: 'freezetime' | 'live' | 'over'; - bomb?: 'planted' | 'exploded' | 'defused'; - win_team?: I.Side; -} - -export interface Observer { - activity?: 'playing' | 'textinput' | 'menu'; - spectarget?: 'free' | (string & {}); - position?: number[]; - forward?: number[]; -} - -export interface CSGO { - provider: I.Provider; - map: Map; - round: Round | null; - observer: Observer; - player: Player | null; - players: Player[]; - bomb: Bomb | null; - grenades?: { - [key: string]: any; - }; - previously?: any; - phase_countdowns: I.PhaseRaw; - auth?: { - token: string; - }; -} -export interface Score { - winner: I.Team; - loser: I.Team; - map: Map; - mapEnd: boolean; -} - -export interface KillEvent { - killer: Player | null; - victim: Player; - assister: Player | null; - flashed: boolean; - headshot: boolean; - weapon: string; - wallbang: boolean; - attackerblind: boolean; - thrusmoke: boolean; - noscope: boolean; - attackerinair: boolean; -} - -export interface HurtEvent { - attacker: Player; - victim: Player; - health: number; - armor: number; - weapon: string; - dmg_health: number; - dmg_armor: number; - hitgroup: number; -} - -//export type DigestMirvType = ((kill: RawKill, eventType: 'player_death') => KillEvent | null) | ((hurt: RawHurt, eventType: 'player_hurt') => HurtEvent | null) -export type DigestMirvType = KillEvent | HurtEvent | null; diff --git a/types/utils.d.ts b/types/utils.d.ts deleted file mode 100644 index 0b029b7..0000000 --- a/types/utils.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - Team, - PlayerExtension, - Player, - PlayersRaw, - Side, - Orientation, - TeamExtension, - TeamRaw, - RoundInfo, - RoundWins -} from '.'; -export declare const mapSteamIDToPlayer: ( - players: PlayersRaw, - teams: { - CT: Team; - T: Team; - }, - extensions: PlayerExtension[] -) => (steamid: string) => Player; -export declare const parseTeam: ( - team: TeamRaw, - orientation: Orientation, - side: Side, - extension: TeamExtension | null -) => Team; -export declare const getHalfFromRound: (round: number, regulationMR: number, mr: number) => number; -export declare const didTeamWinThatRound: ( - team: Team, - round: number, - wonBy: Side, - currentRound: number, - regulationMR: number, - mr: number -) => boolean; -export declare const getRoundWin: ( - mapRound: number, - teams: { - ct: Team; - t: Team; - }, - roundWins: RoundWins, - round: number, - regulationMR: number, - overtimeMR: number -) => RoundInfo | null;