mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: new stats renderer
This commit is contained in:
1 parent
a0290bb59f
commit
94481e81bb
14 files changed
+333
-126
No files matched your search
@@ -1,3 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
.env
|
.env
|
||||||
|
/test-results/
|
||||||
|
/playwright-report/
|
||||||
|
/playwright/.cache/
|
||||||
@@ -11,13 +11,16 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"discord.js": "^14.9.0",
|
"discord.js": "^14.9.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
"fuzzysort": "^2.0.4",
|
"fuzzysort": "^2.0.4",
|
||||||
"lodash.startcase": "^4.4.0",
|
"lodash.startcase": "^4.4.0",
|
||||||
"markdown-escape": "^2.0.0",
|
"markdown-escape": "^2.0.0",
|
||||||
"node-fetch": "^3.3.1"
|
"node-fetch": "^3.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.34.2",
|
||||||
"@total-typescript/ts-reset": "^0.4.2",
|
"@total-typescript/ts-reset": "^0.4.2",
|
||||||
|
"@types/escape-html": "^1.0.2",
|
||||||
"@types/lodash.startcase": "^4.4.7",
|
"@types/lodash.startcase": "^4.4.7",
|
||||||
"@types/markdown-escape": "^1.1.0",
|
"@types/markdown-escape": "^1.1.0",
|
||||||
"@types/node": "^20.2.1",
|
"@types/node": "^20.2.1",
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { defineConfig, devices } from '@playwright/test';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
testDir: './tests',
|
||||||
|
fullyParallel: true,
|
||||||
|
forbidOnly: !!process.env.CI,
|
||||||
|
retries: process.env.CI ? 2 : 0,
|
||||||
|
workers: process.env.CI ? 1 : undefined,
|
||||||
|
reporter: 'html',
|
||||||
|
use: { trace: 'on-first-retry' },
|
||||||
|
|
||||||
|
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
||||||
|
});
|
||||||
+89
-97
@@ -1,25 +1,35 @@
|
|||||||
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
import markdownEscape from 'markdown-escape';
|
import escapeHTML from 'escape-html';
|
||||||
import { INFO_COLOR } from '../constants/colors.js';
|
import GenericStats from '../components/GenericStats/index.js';
|
||||||
|
import Screenshot from '../components/Screenshot.js';
|
||||||
|
import TitleBar from '../components/TitleBar.js';
|
||||||
|
import Wrapper from '../components/Wrapper.js';
|
||||||
|
import { BLITZ_SERVERS } from '../constants/servers.js';
|
||||||
import usernameAutocomplete from '../core/autocomplete/username.js';
|
import usernameAutocomplete from '../core/autocomplete/username.js';
|
||||||
import getBlitzAccount from '../core/blitz/getBlitzAccount.js';
|
import getBlitzAccount from '../core/blitz/getBlitzAccount.js';
|
||||||
import getWargamingResponse from '../core/blitz/getWargamingResponse.js';
|
import getWargamingResponse from '../core/blitz/getWargamingResponse.js';
|
||||||
import blitzStarsLinks from '../core/blitzstars/blitzStarsLinks.js';
|
|
||||||
import getBlitzStarsAccount from '../core/blitzstars/getBlitzStarsAccount.js';
|
import getBlitzStarsAccount from '../core/blitzstars/getBlitzStarsAccount.js';
|
||||||
import poweredByBlitzStars from '../core/blitzstars/poweredByBlitzStars.js';
|
|
||||||
import cleanTable from '../core/interaction/cleanTable.js';
|
|
||||||
import cmdName from '../core/interaction/cmdName.js';
|
import cmdName from '../core/interaction/cmdName.js';
|
||||||
import addUsernameOption from '../core/options/addUsernameOption.js';
|
import addUsernameOption from '../core/options/addUsernameOption.js';
|
||||||
import { args } from '../core/process/args.js';
|
import { args } from '../core/process/args.js';
|
||||||
import { CommandRegistry } from '../events/interactionCreate.js';
|
import { CommandRegistry } from '../events/interactionCreate.js';
|
||||||
|
import { browser } from '../index.js';
|
||||||
import { AccountInfo, AllStats } from '../types/accountInfo.js';
|
import { AccountInfo, AllStats } from '../types/accountInfo.js';
|
||||||
|
import { PlayerClanData } from '../types/playerClanData.js';
|
||||||
import { BlitzStartsComputedPeriodicStatistics } from '../types/statistics.js';
|
import { BlitzStartsComputedPeriodicStatistics } from '../types/statistics.js';
|
||||||
|
|
||||||
type Period = 'today' | '30' | '90' | 'career';
|
type Period = 'today' | '30' | '90' | 'career';
|
||||||
|
|
||||||
|
const periodNames: Record<Period, string> = {
|
||||||
|
today: "Today's statistics",
|
||||||
|
30: '30-day statistics',
|
||||||
|
90: '90-day statistics',
|
||||||
|
career: 'Career statistics',
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
@@ -50,6 +60,10 @@ export default {
|
|||||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`,
|
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`,
|
||||||
);
|
);
|
||||||
if (!accountInfo) return;
|
if (!accountInfo) return;
|
||||||
|
const clanData = await getWargamingResponse<PlayerClanData>(
|
||||||
|
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${id}&extra=clan`,
|
||||||
|
);
|
||||||
|
if (!clanData) return;
|
||||||
const blitzStarsAccount = await getBlitzStarsAccount(interaction, id);
|
const blitzStarsAccount = await getBlitzStarsAccount(interaction, id);
|
||||||
if (!blitzStarsAccount) return;
|
if (!blitzStarsAccount) return;
|
||||||
|
|
||||||
@@ -97,98 +111,76 @@ export default {
|
|||||||
? blitzStarsAccount.statistics
|
? blitzStarsAccount.statistics
|
||||||
: blitzStarsAccount[`period${period}d`];
|
: blitzStarsAccount[`period${period}d`];
|
||||||
}
|
}
|
||||||
if (!stats!) return;
|
if (!stats) return;
|
||||||
|
|
||||||
await interaction.editReply({
|
const page = await browser.newPage();
|
||||||
embeds: [
|
await page.setViewportSize({ width: 640, height: 1 });
|
||||||
poweredByBlitzStars(
|
await page.setContent(
|
||||||
new EmbedBuilder()
|
Screenshot(
|
||||||
.setColor(INFO_COLOR)
|
Wrapper(
|
||||||
.setTitle(
|
TitleBar(
|
||||||
`${markdownEscape(blitzStarsAccount.nickname)}'s ${
|
escapeHTML(blitzStarsAccount.nickname),
|
||||||
period === 'career'
|
clanData[id]?.clan
|
||||||
? period
|
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData[id]?.clan?.emblem_set_id}.png`
|
||||||
: `${period === 'today' ? 'today' : `${period} day`}`
|
: 'https://i.imgur.com/uq6pKbh.png',
|
||||||
} stats`,
|
clanData[id]?.clan ? `[${clanData[id]?.clan?.tag}]` : '',
|
||||||
)
|
`${periodNames[period]} • ${new Date().toDateString()} • ${
|
||||||
.setDescription(
|
BLITZ_SERVERS[server]
|
||||||
stats.all.battles > 0
|
}`,
|
||||||
? `${
|
),
|
||||||
period === 'today'
|
GenericStats([
|
||||||
? '**⚠ "Today" stats are in development. Some stats are not available/wrong.**\n\n'
|
[
|
||||||
: ''
|
'Winrate',
|
||||||
}${cleanTable([
|
`${(100 * (stats.all.wins / stats.all.battles)).toFixed(2)}%`,
|
||||||
[
|
],
|
||||||
'Winrate',
|
['WN8', stats.wn8.toFixed(0)],
|
||||||
`${(100 * (stats.all.wins / stats.all.battles)).toFixed(
|
[
|
||||||
2,
|
'Survival',
|
||||||
)}%`,
|
`${(
|
||||||
],
|
100 *
|
||||||
[
|
(stats.all.survived_battles / stats.all.battles)
|
||||||
'Survival',
|
).toFixed(2)}%`,
|
||||||
`${(
|
],
|
||||||
100 *
|
[
|
||||||
(stats.all.survived_battles / stats.all.battles)
|
'Accuracy',
|
||||||
).toFixed(2)}%`,
|
`${((stats.all.hits / stats.all.shots) * 100).toFixed(2)}%`,
|
||||||
],
|
],
|
||||||
[
|
['Battles', stats.all.battles],
|
||||||
'Accuracy',
|
['Wins', stats.all.wins],
|
||||||
`${((stats.all.hits / stats.all.shots) * 100).toFixed(
|
['Losses', stats.all.losses],
|
||||||
2,
|
[
|
||||||
)}%`,
|
'Average damage',
|
||||||
],
|
(stats.all.damage_dealt / stats.all.battles).toFixed(0),
|
||||||
['WN8', stats.wn8.toFixed(0)],
|
],
|
||||||
['WN7', stats.wn7.toFixed(0)],
|
['Average XP', (stats.all.xp / stats.all.battles).toFixed(0)],
|
||||||
[],
|
['Average shots', (stats.all.shots / stats.all.battles).toFixed(2)],
|
||||||
['Battles', stats.all.battles],
|
['Average hits', (stats.all.hits / stats.all.battles).toFixed(2)],
|
||||||
['Wins', stats.all.wins],
|
['Average kills', (stats.all.frags / stats.all.battles).toFixed(2)],
|
||||||
['Losses', stats.all.losses],
|
[
|
||||||
['Average tier', stats.avg_tier.toFixed(2)],
|
'Average spots',
|
||||||
[],
|
(stats.all.spotted / stats.all.battles).toFixed(2),
|
||||||
[
|
],
|
||||||
'Shots per battle',
|
['Average tier', stats.avg_tier.toFixed(2)],
|
||||||
(stats.all.shots / stats.all.battles).toFixed(2),
|
[
|
||||||
],
|
'Damage ratio',
|
||||||
[
|
(stats.all.damage_dealt / stats.all.damage_received).toFixed(2),
|
||||||
'Hits per battle',
|
],
|
||||||
(stats.all.hits / stats.all.battles).toFixed(2),
|
[
|
||||||
],
|
'Kills to death ratio',
|
||||||
[
|
(
|
||||||
'Damage per battle',
|
stats.all.frags /
|
||||||
(stats.all.damage_dealt / stats.all.battles).toFixed(0),
|
(stats.all.battles - stats.all.survived_battles)
|
||||||
],
|
).toFixed(2),
|
||||||
[
|
],
|
||||||
'Kills per battle',
|
]),
|
||||||
(stats.all.frags / stats.all.battles).toFixed(2),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'Spots per battle',
|
|
||||||
(stats.all.spotted / stats.all.battles).toFixed(2),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'XP per battle',
|
|
||||||
(stats.all.xp / stats.all.battles).toFixed(0),
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
[
|
|
||||||
'Damage ratio',
|
|
||||||
(
|
|
||||||
stats.all.damage_dealt / stats.all.damage_received
|
|
||||||
).toFixed(2),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'Kills to death ratio',
|
|
||||||
(
|
|
||||||
stats.all.frags /
|
|
||||||
(stats.all.battles - stats.all.survived_battles)
|
|
||||||
).toFixed(2),
|
|
||||||
],
|
|
||||||
])}\n\n${blitzStarsLinks(server, blitzStarsAccount.nickname)}`
|
|
||||||
: 'No battles played in this period.',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
});
|
);
|
||||||
|
const screenshot = await page
|
||||||
|
.locator('#screenshot')
|
||||||
|
.screenshot({ omitBackground: true, scale: 'css' });
|
||||||
|
await page.close();
|
||||||
|
await interaction.editReply({ files: [screenshot] });
|
||||||
|
|
||||||
console.log(`Showing stats for ${blitzStarsAccount.nickname}`);
|
console.log(`Showing stats for ${blitzStarsAccount.nickname}`);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
|
||||||
import usernameAutocomplete from '../core/autocomplete/username.js';
|
|
||||||
import cmdName from '../core/interaction/cmdName.js';
|
|
||||||
import addUsernameOption from '../core/options/addUsernameOption.js';
|
|
||||||
import { CommandRegistry } from '../events/interactionCreate.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
inProduction: false,
|
|
||||||
inDevelopment: true,
|
|
||||||
inPublic: true,
|
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
|
||||||
.setName(cmdName('today'))
|
|
||||||
.setDescription('A brief summary of your performance today')
|
|
||||||
.addStringOption(addUsernameOption),
|
|
||||||
|
|
||||||
async execute(interaction) {
|
|
||||||
interaction.editReply("let's do this!");
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: usernameAutocomplete,
|
|
||||||
} satisfies CommandRegistry;
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export type ChildrenArgument = string | string[];
|
||||||
|
|
||||||
|
export default function Children(children: string[]) {
|
||||||
|
return children.join('\n');
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Stat } from '../index.js';
|
||||||
|
import GenericStatsRow from './GenericStatsRow.js';
|
||||||
|
|
||||||
|
export default function GenericStatsColumn(stats: Stat[]) {
|
||||||
|
return `
|
||||||
|
<style>
|
||||||
|
.generic-stats-column {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="generic-stats-column">
|
||||||
|
${stats.map((stat) => GenericStatsRow(stat)).join('\n')}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Stat } from '../index.js';
|
||||||
|
|
||||||
|
export default function GenericStatsRow(stat: Stat) {
|
||||||
|
return `
|
||||||
|
<style>
|
||||||
|
.generic-stats-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generic-stats-label {
|
||||||
|
color: #A0A0A0;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generic-stats-value {
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="generic-stats-row">
|
||||||
|
<span class="generic-stats-label">${stat[0]}</span>
|
||||||
|
<span class="generic-stats-value">${stat[1]}</span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import GenericStatsColumn from './components/GenericStatsColumn.js';
|
||||||
|
|
||||||
|
export type Stat = [string, string | number];
|
||||||
|
|
||||||
|
export default function GenericStats(stats: Stat[], columnCount = 2) {
|
||||||
|
const itemsPerRow = Math.ceil(stats.length / columnCount);
|
||||||
|
const columns: Stat[][] = [];
|
||||||
|
|
||||||
|
stats.forEach((stat, index) => {
|
||||||
|
const column = Math.floor(index / itemsPerRow);
|
||||||
|
if (!columns[column]) columns[column] = [];
|
||||||
|
columns[column].push(stat);
|
||||||
|
});
|
||||||
|
|
||||||
|
return `
|
||||||
|
<style>
|
||||||
|
.generic-stats {
|
||||||
|
display: flex;
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="generic-stats">
|
||||||
|
${columns.map((column) => GenericStatsColumn(column)).join('\n')}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import Children from './Children.js';
|
||||||
|
|
||||||
|
export default function Screenshot(...children: string[]) {
|
||||||
|
return `
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:[email protected]');
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:[email protected]');
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: 'Roboto Flex', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screenshot {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="screenshot">
|
||||||
|
${Children(children)}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
export default function TitleBar(
|
||||||
|
name: string,
|
||||||
|
image: string,
|
||||||
|
nameDiscriminator = '',
|
||||||
|
description = '',
|
||||||
|
) {
|
||||||
|
return `
|
||||||
|
<style>
|
||||||
|
.title-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-info {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-avatar {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-name {
|
||||||
|
font-size: 32px;
|
||||||
|
color: white;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-discriminator {
|
||||||
|
color: #A0A0A0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-description {
|
||||||
|
color: #A0A0A0;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-blitzkrieg {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="title-bar">
|
||||||
|
<div class="title-bar-info">
|
||||||
|
<img class="title-bar-avatar" src="${image}" />
|
||||||
|
|
||||||
|
<div class="title-bar-text">
|
||||||
|
<span class="title-bar-name">
|
||||||
|
${name}
|
||||||
|
<span class="title-bar-discriminator">${nameDiscriminator}</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="title-bar-description">${description}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<img class="title-bar-blitzkrieg" src="https://i.imgur.com/35phKIu.png" />
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import Children from './Children.js';
|
||||||
|
|
||||||
|
export default function Wrapper(...children: string[]) {
|
||||||
|
return `
|
||||||
|
<style>
|
||||||
|
#wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 16px;
|
||||||
|
gap: 32px;
|
||||||
|
width: 640px;
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="wrapper">
|
||||||
|
${Children(children)}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
+3
-6
@@ -1,3 +1,4 @@
|
|||||||
|
import { chromium } from '@playwright/test';
|
||||||
import { Client, GatewayIntentBits } from 'discord.js';
|
import { Client, GatewayIntentBits } from 'discord.js';
|
||||||
import { args } from './core/process/args.js';
|
import { args } from './core/process/args.js';
|
||||||
import { registerErrorHandlers } from './events/error.js';
|
import { registerErrorHandlers } from './events/error.js';
|
||||||
@@ -5,16 +6,12 @@ import guildMemberAdd from './events/guildMemberAdd.js';
|
|||||||
import interactionCreate from './events/interactionCreate.js';
|
import interactionCreate from './events/interactionCreate.js';
|
||||||
import ready from './events/ready.js';
|
import ready from './events/ready.js';
|
||||||
|
|
||||||
// sudo apt-get install libatk-bridge2.0-0
|
registerErrorHandlers();
|
||||||
// node node_modules/puppeteer/install.js
|
|
||||||
|
|
||||||
export const client = new Client({
|
export const client = new Client({
|
||||||
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
|
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
|
||||||
});
|
});
|
||||||
// export const browser = await launch({ headless: 'new' });
|
export const browser = await chromium.launch();
|
||||||
// export const page = await browser.newPage();
|
|
||||||
|
|
||||||
registerErrorHandlers();
|
|
||||||
|
|
||||||
client
|
client
|
||||||
.on('ready', ready)
|
.on('ready', ready)
|
||||||
|
|||||||
@@ -156,6 +156,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061"
|
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061"
|
||||||
integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==
|
integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==
|
||||||
|
|
||||||
|
"@playwright/test@^1.34.2":
|
||||||
|
version "1.34.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.34.2.tgz#938ccfb8c162e8ef83dbef3d88ce6851acd469e6"
|
||||||
|
integrity sha512-v/LBnwzD0225q8xEv3t9DmNPX61yvNnEbiA8PoNk1fbkxApJFCWYLPpQbdVWzHaARdZD9g1PYBoOvnffortfKw==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
playwright-core "1.34.2"
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "2.3.2"
|
||||||
|
|
||||||
"@sapphire/async-queue@^1.5.0":
|
"@sapphire/async-queue@^1.5.0":
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz"
|
resolved "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz"
|
||||||
@@ -184,6 +194,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@total-typescript/ts-reset/-/ts-reset-0.4.2.tgz#c564c173ba09973968e1046c93965b7a257878a4"
|
resolved "https://registry.yarnpkg.com/@total-typescript/ts-reset/-/ts-reset-0.4.2.tgz#c564c173ba09973968e1046c93965b7a257878a4"
|
||||||
integrity sha512-vqd7ZUDSrXFVT1n8b2kc3LnklncDQFPvR58yUS1kEP23/nHPAO9l1lMjUfnPrXYYk4Hj54rrLKMW5ipwk7k09A==
|
integrity sha512-vqd7ZUDSrXFVT1n8b2kc3LnklncDQFPvR58yUS1kEP23/nHPAO9l1lMjUfnPrXYYk4Hj54rrLKMW5ipwk7k09A==
|
||||||
|
|
||||||
|
"@types/escape-html@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/escape-html/-/escape-html-1.0.2.tgz#072b7b13784fb3cee9c2450c22f36405983f5e3c"
|
||||||
|
integrity sha512-gaBLT8pdcexFztLSPRtriHeXY/Kn4907uOCZ4Q3lncFBkheAWOuNt53ypsF8szgxbEJ513UeBzcf4utN0EzEwA==
|
||||||
|
|
||||||
"@types/lodash.startcase@^4.4.7":
|
"@types/lodash.startcase@^4.4.7":
|
||||||
version "4.4.7"
|
version "4.4.7"
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash.startcase/-/lodash.startcase-4.4.7.tgz#69857f17be0aa5ce74da4fa386e32e22c012258a"
|
resolved "https://registry.yarnpkg.com/@types/lodash.startcase/-/lodash.startcase-4.4.7.tgz#69857f17be0aa5ce74da4fa386e32e22c012258a"
|
||||||
@@ -299,6 +314,11 @@ esbuild@^0.17.5:
|
|||||||
"@esbuild/win32-ia32" "0.17.19"
|
"@esbuild/win32-ia32" "0.17.19"
|
||||||
"@esbuild/win32-x64" "0.17.19"
|
"@esbuild/win32-x64" "0.17.19"
|
||||||
|
|
||||||
|
escape-html@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||||
|
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
|
||||||
|
|
||||||
fast-deep-equal@^3.1.3:
|
fast-deep-equal@^3.1.3:
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||||
@@ -328,7 +348,7 @@ formdata-polyfill@^4.0.10:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fetch-blob "^3.1.2"
|
fetch-blob "^3.1.2"
|
||||||
|
|
||||||
fsevents@~2.3.2:
|
[email protected], fsevents@~2.3.2:
|
||||||
version "2.3.2"
|
version "2.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||||
@@ -431,6 +451,11 @@ pkg-types@^1.0.3:
|
|||||||
mlly "^1.2.0"
|
mlly "^1.2.0"
|
||||||
pathe "^1.1.0"
|
pathe "^1.1.0"
|
||||||
|
|
||||||
|
[email protected]:
|
||||||
|
version "1.34.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.34.2.tgz#4989ba082f623f21679724033629b2333b626569"
|
||||||
|
integrity sha512-MrkgGWLANc5qthXduvIY1a/tuafROyTORVd86fwKwgoYrmnBooN/GgeZSBm7ljTLV2FCWNSXV3se7qeScKn83g==
|
||||||
|
|
||||||
postcss@^8.4.23:
|
postcss@^8.4.23:
|
||||||
version "8.4.23"
|
version "8.4.23"
|
||||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab"
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab"
|
||||||
|
|||||||
Reference in new issue
Block a user