Merge pull request #4359 from CHOMPStation2/upstream-merge-13046

[MIRROR] tgui-bench Port
This commit is contained in:
Nadyr
2022-06-22 18:01:08 -04:00
committed by GitHub
57 changed files with 4711 additions and 516 deletions
+1 -1
View File
@@ -670,7 +670,7 @@ rules:
# react/sort-prop-types: error
## Enforce the state initialization style to be either in a constructor or
## with a class property
react/state-in-constructor: error
# react/state-in-constructor: error
## Enforces where React component static properties should be positioned.
# react/static-property-placement: error
## Enforce style prop value being an object
+1
View File
@@ -14,6 +14,7 @@ package-lock.json
## Build artifacts
/public/.tmp/**/*
/public/*.map
## Previously ignored locations that are kept to avoid confusing git
## while transitioning to a new project structure.
+4 -4
View File
@@ -5,7 +5,7 @@
*/
const createBabelConfig = options => {
const { mode, presets = [], plugins = [] } = options;
const { presets = [], plugins = [], removeConsole } = options;
return {
presets: [
[require.resolve('@babel/preset-typescript'), {
@@ -20,17 +20,17 @@ const createBabelConfig = options => {
targets: [],
}],
...presets,
],
].filter(Boolean),
plugins: [
[require.resolve('@babel/plugin-proposal-class-properties'), {
loose: true,
}],
require.resolve('@babel/plugin-transform-jscript'),
require.resolve('babel-plugin-inferno'),
require.resolve('babel-plugin-transform-remove-console'),
removeConsole && require.resolve('babel-plugin-transform-remove-console'),
require.resolve('common/string.babel-plugin.cjs'),
...plugins,
],
].filter(Boolean),
};
};
+1 -1
View File
@@ -92,7 +92,7 @@ task-clean() {
rm -f .yarn/build-state.yml
rm -f .yarn/install-state.gz
rm -f .yarn/install-target
rm -f .pnp.js
rm -f .pnp.*
## NPM artifacts
rm -rf **/node_modules
rm -f **/package-lock.json
+9
View File
@@ -0,0 +1,9 @@
@echo off
rem Copyright (c) 2020 Aleksej Komarov
rem SPDX-License-Identifier: MIT
call powershell.exe -NoLogo -ExecutionPolicy Bypass -File "%~dp0\tgui_.ps1" --bench %*
rem Pause if launched in a separate shell unless initiated from powershell
echo %PSModulePath% | findstr %USERPROFILE% >NUL
if %errorlevel% equ 0 exit 0
echo %cmdcmdline% | find /i "/c"
if %errorlevel% equ 0 pause
+12 -1
View File
@@ -50,6 +50,10 @@ function task-dev-server {
yarn node --experimental-modules "packages/tgui-dev-server/index.js" @Args
}
function task-bench {
yarn tgui:bench @Args
}
## Run a linter through all packages
function task-lint {
yarn run tsc
@@ -75,7 +79,7 @@ function task-clean {
Remove-Quiet -Force ".yarn\build-state.yml"
Remove-Quiet -Force ".yarn\install-state.gz"
Remove-Quiet -Force ".yarn\install-target"
Remove-Quiet -Force ".pnp.js"
Remove-Quiet -Force ".pnp.*"
## NPM artifacts
Get-ChildItem -Path "." -Include "node_modules" -Recurse -File:$false | Remove-Item -Recurse -Force
Remove-Quiet -Force "package-lock.json"
@@ -132,6 +136,13 @@ if ($Args.Length -gt 0) {
task-webpack --mode=production --analyze
exit 0
}
if ($Args[0] -eq "--bench") {
$Rest = $Args | Select-Object -Skip 1
task-install
task-bench --wait-on-error
exit 0
}
}
## Make a production webpack build
+175 -179
View File
@@ -4,184 +4,180 @@
* @license MIT
*/
declare global {
// Webpack asset modules.
// Should match extensions used in webpack config.
declare module '*.png' {
const content: string;
export default content;
}
declare module '*.jpg' {
const content: string;
export default content;
}
declare module '*.svg' {
const content: string;
export default content;
}
type TguiMessage = {
type: string;
payload?: any;
[key: string]: any;
};
type ByondType = {
/**
* ID of the Byond window this script is running on.
* Can be used as a parameter to winget/winset.
*/
windowId: string;
/**
* True if javascript is running in BYOND.
*/
IS_BYOND: boolean;
/**
* Version of Trident engine of Internet Explorer. Null if N/A.
*/
TRIDENT: number | null;
/**
* True if browser is IE8 or lower.
*/
IS_LTE_IE8: boolean;
/**
* True if browser is IE9 or lower.
*/
IS_LTE_IE9: boolean;
/**
* True if browser is IE10 or lower.
*/
IS_LTE_IE10: boolean;
/**
* True if browser is IE11 or lower.
*/
IS_LTE_IE11: boolean;
/**
* Makes a BYOND call.
*
* If path is empty, this will trigger a Topic call.
* You can reference a specific object by setting the "src" parameter.
*
* See: https://secure.byond.com/docs/ref/skinparams.html
*/
call(path: string, params: object): void;
/**
* Makes an asynchronous BYOND call. Returns a promise.
*/
callAsync(path: string, params: object): Promise<any>;
/**
* Makes a Topic call.
*
* You can reference a specific object by setting the "src" parameter.
*/
topic(params: object): void;
/**
* Runs a command or a verb.
*/
command(command: string): void;
/**
* Retrieves all properties of the BYOND skin element.
*
* Returns a promise with a key-value object containing all properties.
*/
winget(id: string | null): Promise<object>;
/**
* Retrieves all properties of the BYOND skin element.
*
* Returns a promise with a key-value object containing all properties.
*/
winget(id: string | null, propName: '*'): Promise<object>;
/**
* Retrieves an exactly one property of the BYOND skin element,
* as defined in `propName`.
*
* Returns a promise with the value of that property.
*/
winget(id: string | null, propName: string): Promise<any>;
/**
* Retrieves multiple properties of the BYOND skin element,
* as defined in the `propNames` array.
*
* Returns a promise with a key-value object containing listed properties.
*/
winget(id: string | null, propNames: string[]): Promise<object>;
/**
* Assigns properties to BYOND skin elements in bulk.
*/
winset(props: object): void;
/**
* Assigns properties to the BYOND skin element.
*/
winset(id: string | null, props: object): void;
/**
* Sets a property on the BYOND skin element to a certain value.
*/
winset(id: string | null, propName: string, propValue: any): void;
/**
* Parses BYOND JSON.
*
* Uses a special encoding to preserve `Infinity` and `NaN`.
*/
parseJson(text: string): any;
/**
* Sends a message to `/datum/tgui_window` which hosts this window instance.
*/
sendMessage(type: string, payload?: any): void;
sendMessage(message: TguiMessage): void;
/**
* Subscribe to incoming messages that were sent from `/datum/tgui_window`.
*/
subscribe(listener: (type: string, payload: any) => void): void;
/**
* Subscribe to incoming messages *of some specific type*
* that were sent from `/datum/tgui_window`.
*/
subscribeTo(type: string, listener: (payload: any) => void): void;
/**
* Loads a stylesheet into the document.
*/
loadCss(url: string): void;
/**
* Loads a script into the document.
*/
loadJs(url: string): void;
};
/**
* Object that provides access to Byond Skin API and is available in
* any tgui application.
*/
const Byond: ByondType;
interface Window {
Byond: ByondType;
}
// Webpack asset modules.
// Should match extensions used in webpack config.
declare module '*.png' {
const content: string;
export default content;
}
export {};
declare module '*.jpg' {
const content: string;
export default content;
}
declare module '*.svg' {
const content: string;
export default content;
}
type TguiMessage = {
type: string;
payload?: any;
[key: string]: any;
};
type ByondType = {
/**
* ID of the Byond window this script is running on.
* Can be used as a parameter to winget/winset.
*/
windowId: string;
/**
* True if javascript is running in BYOND.
*/
IS_BYOND: boolean;
/**
* Version of Trident engine of Internet Explorer. Null if N/A.
*/
TRIDENT: number | null;
/**
* True if browser is IE8 or lower.
*/
IS_LTE_IE8: boolean;
/**
* True if browser is IE9 or lower.
*/
IS_LTE_IE9: boolean;
/**
* True if browser is IE10 or lower.
*/
IS_LTE_IE10: boolean;
/**
* True if browser is IE11 or lower.
*/
IS_LTE_IE11: boolean;
/**
* Makes a BYOND call.
*
* If path is empty, this will trigger a Topic call.
* You can reference a specific object by setting the "src" parameter.
*
* See: https://secure.byond.com/docs/ref/skinparams.html
*/
call(path: string, params: object): void;
/**
* Makes an asynchronous BYOND call. Returns a promise.
*/
callAsync(path: string, params: object): Promise<any>;
/**
* Makes a Topic call.
*
* You can reference a specific object by setting the "src" parameter.
*/
topic(params: object): void;
/**
* Runs a command or a verb.
*/
command(command: string): void;
/**
* Retrieves all properties of the BYOND skin element.
*
* Returns a promise with a key-value object containing all properties.
*/
winget(id: string | null): Promise<object>;
/**
* Retrieves all properties of the BYOND skin element.
*
* Returns a promise with a key-value object containing all properties.
*/
winget(id: string | null, propName: '*'): Promise<object>;
/**
* Retrieves an exactly one property of the BYOND skin element,
* as defined in `propName`.
*
* Returns a promise with the value of that property.
*/
winget(id: string | null, propName: string): Promise<any>;
/**
* Retrieves multiple properties of the BYOND skin element,
* as defined in the `propNames` array.
*
* Returns a promise with a key-value object containing listed properties.
*/
winget(id: string | null, propNames: string[]): Promise<object>;
/**
* Assigns properties to BYOND skin elements in bulk.
*/
winset(props: object): void;
/**
* Assigns properties to the BYOND skin element.
*/
winset(id: string | null, props: object): void;
/**
* Sets a property on the BYOND skin element to a certain value.
*/
winset(id: string | null, propName: string, propValue: any): void;
/**
* Parses BYOND JSON.
*
* Uses a special encoding to preserve `Infinity` and `NaN`.
*/
parseJson(text: string): any;
/**
* Sends a message to `/datum/tgui_window` which hosts this window instance.
*/
sendMessage(type: string, payload?: any): void;
sendMessage(message: TguiMessage): void;
/**
* Subscribe to incoming messages that were sent from `/datum/tgui_window`.
*/
subscribe(listener: (type: string, payload: any) => void): void;
/**
* Subscribe to incoming messages *of some specific type*
* that were sent from `/datum/tgui_window`.
*/
subscribeTo(type: string, listener: (payload: any) => void): void;
/**
* Loads a stylesheet into the document.
*/
loadCss(url: string): void;
/**
* Loads a script into the document.
*/
loadJs(url: string): void;
};
/**
* Object that provides access to Byond Skin API and is available in
* any tgui application.
*/
const Byond: ByondType;
interface Window {
Byond: ByondType;
}
+3
View File
@@ -4,6 +4,9 @@ module.exports = {
'<rootDir>/packages/**/__tests__/*.{js,ts,tsx}',
'<rootDir>/packages/**/*.{spec,test}.{js,ts,tsx}',
],
testPathIgnorePatterns: [
'<rootDir>/packages/tgui-bench',
],
testEnvironment: 'jsdom',
testRunner: require.resolve('jest-circus/runner'),
transform: {
+14
View File
@@ -6,6 +6,18 @@
"workspaces": [
"packages/*"
],
"scripts": {
"tgui:build": "webpack",
"tgui:analyze": "webpack --analyze",
"tgui:dev": "node --experimental-modules packages/tgui-dev-server/index.js",
"tgui:lint": "eslint packages --ext .js,.cjs,.ts,.tsx",
"tgui:sonar": "eslint packages --ext .js,.cjs,.ts,.tsx -c .eslintrc-harder.yml",
"tgui:tsc": "tsc",
"tgui:test": "jest --watch",
"tgui:test-simple": "CI=true jest --color",
"tgui:test-ci": "CI=true jest --color --collect-coverage",
"tgui:bench": "webpack --env TGUI_BENCH=1 && node packages/tgui-bench/index.js"
},
"dependencies": {
"@babel/core": "^7.18.0",
"@babel/eslint-parser": "^7.17.0",
@@ -16,6 +28,8 @@
"@types/jest": "^27.5.1",
"@types/jsdom": "^16.2.14",
"@types/node": "^17.0.35",
"@types/webpack": "^5.28.0",
"@types/webpack-env": "^1.17.0",
"@typescript-eslint/parser": "^5.25.0",
"babel-jest": "^28.1.0",
"babel-loader": "^8.2.5",
+114 -154
View File
@@ -4,64 +4,6 @@
* @license MIT
*/
/**
* Converts a given collection to an array.
*
* - Arrays are returned unmodified;
* - If object was provided, keys will be discarded;
* - Everything else will result in an empty array.
*
* @returns {any[]}
*/
export const toArray = collection => {
if (Array.isArray(collection)) {
return collection;
}
if (typeof collection === 'object') {
const hasOwnProperty = Object.prototype.hasOwnProperty;
const result = [];
for (let i in collection) {
if (hasOwnProperty.call(collection, i)) {
result.push(collection[i]);
}
}
return result;
}
return [];
};
/**
* Converts a given object to an array, and appends a key to every
* object inside of that array.
*
* Example input (object):
* ```
* {
* 'Foo': { info: 'Hello world!' },
* 'Bar': { info: 'Hello world!' },
* }
* ```
*
* Example output (array):
* ```
* [
* { key: 'Foo', info: 'Hello world!' },
* { key: 'Bar', info: 'Hello world!' },
* ]
* ```
*
* @template T
* @param {{ [key: string]: T }} obj Object, or in DM terms, an assoc array
* @param {string} keyProp Property, to which key will be assigned
* @returns {T[]} Array of keyed objects
*/
export const toKeyedArray = (obj, keyProp = 'key') => {
return map((item, key) => ({
[keyProp]: key,
...item,
}))(obj);
};
/**
* Iterates over elements of collection, returning an array of all elements
* iteratee returns truthy for. The predicate is invoked with three
@@ -72,21 +14,40 @@ export const toKeyedArray = (obj, keyProp = 'key') => {
*
* @returns {any[]}
*/
export const filter = iterateeFn => collection => {
if (collection === null || collection === undefined) {
return collection;
}
if (Array.isArray(collection)) {
const result = [];
for (let i = 0; i < collection.length; i++) {
const item = collection[i];
if (iterateeFn(item, i, collection)) {
result.push(item);
export const filter = <T>(iterateeFn: (
input: T,
index: number,
collection: T[],
) => boolean) =>
(collection: T[]): T[] => {
if (collection === null || collection === undefined) {
return collection;
}
}
return result;
}
throw new Error(`filter() can't iterate on type ${typeof collection}`);
if (Array.isArray(collection)) {
const result: T[] = [];
for (let i = 0; i < collection.length; i++) {
const item = collection[i];
if (iterateeFn(item, i, collection)) {
result.push(item);
}
}
return result;
}
throw new Error(`filter() can't iterate on type ${typeof collection}`);
};
type MapFunction = {
<T, U>(iterateeFn: (
value: T,
index: number,
collection: T[],
) => U): (collection: T[]) => U[];
<T, U, K extends string | number>(iterateeFn: (
value: T,
index: K,
collection: Record<K, T>,
) => U): (collection: Record<K, T>) => U[];
};
/**
@@ -96,32 +57,25 @@ export const filter = iterateeFn => collection => {
*
* If collection is 'null' or 'undefined', it will be returned "as is"
* without emitting any errors (which can be useful in some cases).
*
* @returns {any[]}
*/
export const map = iterateeFn => collection => {
if (collection === null || collection === undefined) {
return collection;
}
if (Array.isArray(collection)) {
const result = [];
for (let i = 0; i < collection.length; i++) {
result.push(iterateeFn(collection[i], i, collection));
export const map: MapFunction = <T, U>(iterateeFn) =>
(collection: T[]): U[] => {
if (collection === null || collection === undefined) {
return collection;
}
return result;
}
if (typeof collection === 'object') {
const hasOwnProperty = Object.prototype.hasOwnProperty;
const result = [];
for (let i in collection) {
if (hasOwnProperty.call(collection, i)) {
result.push(iterateeFn(collection[i], i, collection));
}
if (Array.isArray(collection)) {
return collection.map(iterateeFn);
}
return result;
}
throw new Error(`map() can't iterate on type ${typeof collection}`);
};
if (typeof collection === 'object') {
return Object.entries(collection).map(([key, value]) => {
return iterateeFn(value, key, collection);
});
}
throw new Error(`map() can't iterate on type ${typeof collection}`);
};
const COMPARATOR = (objA, objB) => {
const criteriaA = objA.criteria;
@@ -148,28 +102,35 @@ const COMPARATOR = (objA, objB) => {
*
* @returns {any[]}
*/
export const sortBy = (...iterateeFns) => array => {
if (!Array.isArray(array)) {
return array;
}
let length = array.length;
// Iterate over the array to collect criteria to sort it by
let mappedArray = [];
for (let i = 0; i < length; i++) {
const value = array[i];
mappedArray.push({
criteria: iterateeFns.map(fn => fn(value)),
value,
});
}
// Sort criteria using the base comparator
mappedArray.sort(COMPARATOR);
// Unwrap values
while (length--) {
mappedArray[length] = mappedArray[length].value;
}
return mappedArray;
};
export const sortBy = <T>(
...iterateeFns: ((input: T) => unknown)[]
) => (array: T[]): T[] => {
if (!Array.isArray(array)) {
return array;
}
let length = array.length;
// Iterate over the array to collect criteria to sort it by
let mappedArray: {
criteria: unknown[],
value: T,
}[] = [];
for (let i = 0; i < length; i++) {
const value = array[i];
mappedArray.push({
criteria: iterateeFns.map(fn => fn(value)),
value,
});
}
// Sort criteria using the base comparator
mappedArray.sort(COMPARATOR);
// Unwrap values
const values: T[] = [];
while (length--) {
values[length] = mappedArray[length].value;
}
return values;
};
export const sort = sortBy();
@@ -212,40 +173,38 @@ export const reduce = (reducerFn, initialValue) => array => {
* is determined by the order they occur in the array. The iteratee is
* invoked with one argument: value.
*/
/* eslint-disable indent */
export const uniqBy = <T extends unknown>(
iterateeFn?: (value: T) => unknown
) => (array: T[]) => {
const { length } = array;
const result = [];
const seen = iterateeFn ? [] : result;
let index = -1;
outer:
while (++index < length) {
let value: T | 0 = array[index];
const computed = iterateeFn ? iterateeFn(value) : value;
value = value !== 0 ? value : 0;
if (computed === computed) {
let seenIndex = seen.length;
while (seenIndex--) {
if (seen[seenIndex] === computed) {
continue outer;
) => (array: T[]): T[] => {
const { length } = array;
const result: T[] = [];
const seen: unknown[] = iterateeFn ? [] : result;
let index = -1;
outer:
while (++index < length) {
let value: T | 0 = array[index];
const computed = iterateeFn ? iterateeFn(value) : value;
if (computed === computed) {
let seenIndex = seen.length;
while (seenIndex--) {
if (seen[seenIndex] === computed) {
continue outer;
}
}
if (iterateeFn) {
seen.push(computed);
}
result.push(value);
}
if (iterateeFn) {
seen.push(computed);
else if (!seen.includes(computed)) {
if (seen !== result) {
seen.push(computed);
}
result.push(value);
}
result.push(value);
}
else if (!seen.includes(computed)) {
if (seen !== result) {
seen.push(computed);
}
result.push(value);
}
}
return result;
};
return result;
};
/* eslint-enable indent */
export const uniq = uniqBy();
@@ -261,17 +220,19 @@ type Zip<T extends unknown[][]> = {
*/
export const zip = <T extends unknown[][]>(...arrays: T): Zip<T> => {
if (arrays.length === 0) {
return;
return [];
}
const numArrays = arrays.length;
const numValues = arrays[0].length;
const result = [];
const result: Zip<T> = [];
for (let valueIndex = 0; valueIndex < numValues; valueIndex++) {
const entry = [];
const entry: unknown[] = [];
for (let arrayIndex = 0; arrayIndex < numArrays; arrayIndex++) {
entry.push(arrays[arrayIndex][valueIndex]);
}
result.push(entry);
// I tried everything to remove this any, and have no idea how to do it.
result.push(entry as any);
}
return result;
};
@@ -280,9 +241,8 @@ export const zip = <T extends unknown[][]>(...arrays: T): Zip<T> => {
* This method is like "zip" except that it accepts iteratee to
* specify how grouped values should be combined. The iteratee is
* invoked with the elements of each group.
*
* @returns {any[]}
*/
export const zipWith = iterateeFn => (...arrays) => {
return map(values => iterateeFn(...values))(zip(...arrays));
};
export const zipWith = <T, U>(iterateeFn: (...values: T[]) => U) =>
(...arrays: T[][]): U[] => {
return map((values: T[]) => iterateeFn(...values))(zip(...arrays));
};
+5
View File
@@ -0,0 +1,5 @@
/**
* Returns the arguments of a function F as an array.
*/
export type ArgumentsOf<F extends Function>
= F extends (...args: infer A) => unknown ? A : never;
+17 -8
View File
@@ -1,7 +1,7 @@
@font-face {
font-family: "tgfont";
src: url("./tgfont.woff2?8fcc44d209cc0a286e2fedc5edea15e7") format("woff2"),
url("./tgfont.eot?8fcc44d209cc0a286e2fedc5edea15e7#iefix") format("embedded-opentype");
src: url("./tgfont.woff2?45c3c7acc69dd413375d77898d24e41e") format("woff2"),
url("./tgfont.eot?45c3c7acc69dd413375d77898d24e41e#iefix") format("embedded-opentype");
}
i[class^="tg-"]:before, i[class*=" tg-"]:before {
@@ -21,21 +21,30 @@ i[class^="tg-"]:before, i[class*=" tg-"]:before {
.tg-air-tank:before {
content: "\f102";
}
.tg-image-minus:before {
.tg-bad-touch:before {
content: "\f103";
}
.tg-image-plus:before {
.tg-image-minus:before {
content: "\f104";
}
.tg-nanotrasen-logo:before {
.tg-image-plus:before {
content: "\f105";
}
.tg-sound-minus:before {
.tg-nanotrasen-logo:before {
content: "\f106";
}
.tg-sound-plus:before {
.tg-non-binary:before {
content: "\f107";
}
.tg-syndicate-logo:before {
.tg-prosthetic-leg:before {
content: "\f108";
}
.tg-sound-minus:before {
content: "\f109";
}
.tg-sound-plus:before {
content: "\f10a";
}
.tg-syndicate-logo:before {
content: "\f10b";
}
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
bad-touch.svg contains:
- hug by Phạm Thanh Lộc from the Noun Project
- Fight by Rudez Studio from the Noun Project
prosthetic-leg.svg contains:
- prosthetic leg by Gan Khoon Lay from the Noun Project
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 500 388" style="enable-background:new 0 0 500 388;" xml:space="preserve">
<g>
<g>
<ellipse transform="matrix(0.7071 -0.7071 0.7071 0.7071 471.6391 371.7563)" cx="684.6" cy="-383.4" rx="83.1" ry="83.1"/>
<polygon points="947,-49.1 885.8,46.5 870.2,71.6 813.7,159.4 769.8,131.2 718.1,96.7 793.3,-19.3 694.6,-89.9 669.5,55.9
671,55.9 724.3,200.2 774.5,333.4 697.7,452.6 628.7,560.8 531.5,499.7 647.5,319.3 598.9,187.6 359,560.8 263.4,499.7
556.6,43.4 556.6,43.4 575.4,-66.4 355.9,112.4 283.7,24.6 603.6,-235.7 608.3,-240.4 625.6,-237.3 666.3,-231 700.8,-224.7
714.9,-215.3 854.5,-115 "/>
</g>
</g>
<g transform="translate(-1.9001193,-43.556581)">
<path d="M131.6-382.3c0-54.7-44.3-99-99-99s-99,44.3-99,99l0,0c0,54.7,44.3,99,99,99S131.6-327.6,131.6-382.3z"/>
<path d="M321.8-85.3C231.4-90.8,142.5-111,58.5-145c-6.6-2.7-9.7-10.1-7.1-16.7c1.9-4.9,6.7-8,11.9-8h243.8
c22.3,0,40.5-18.1,40.5-40.5s-18.1-40.5-40.5-40.5H-41.1c-36.3,0-68.1,24.1-77.9,59l-69.8,248.5l-35.9,209.6l-178,32
c-27.5,4.9-45.8,31.2-40.8,58.7c4.9,27.5,31.2,45.8,58.7,40.8l200.4-36.1c33.5-6,59.7-32.4,65.5-66l16.7-97.4
c0.8-4.4,5.1-7.3,9.5-6.4c2.4,0.5,4.5,2,5.6,4.2l53.2,107.2l-84.2,229.3c-9.2,26.4,4.6,55.2,31,64.4c25.8,9,54.1-4.1,63.9-29.6
l91-247.9c7.7-20.9,6.4-44-3.4-63.9L-24,77.6L21.6-72.7c94,38.9,193.7,61.9,295.2,68.2c22.3,1.4,41.5-15.6,42.9-37.9
C361.1-64.7,344.1-83.9,321.8-85.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 707.8 944.4" style="enable-background:new 0 0 707.8 944.4;" xml:space="preserve">
<g id="woman" focusable="false">
</g>
<g id="man">
<g>
<path d="M532.7,767.2L532.7,767.2l-80-320.1c-4.5-17.8-20.5-30.3-38.8-30.3H395c-19.1,8.8-40,13.3-61.1,13.3v600.1h26.7
c22.1,0,40-17.9,40-40V816.9h93.3C519.9,816.9,539,792.5,532.7,767.2z"/>
<path d="M440.6,283.5c0-58.9-47.8-106.7-106.7-106.7v213.4C392.8,390.2,440.6,342.4,440.6,283.5z"/>
<path d="M253.9,416.9c-44.2,0-80,35.8-80,80v226.7c0,22.1,17.9,40,40,40h26.7v226.7c0,22.1,17.9,40,40,40h53.3V430.2
c-20.7,0-41.5-4.3-61.1-13.3H253.9z"/>
<path d="M227.2,283.5c0,58.9,47.8,106.7,106.7,106.7V176.8C275,176.8,227.2,224.6,227.2,283.5z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 966 B

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<ellipse cx="97" cy="-305.1" rx="141.8" ry="141.8"/>
<path d="M654.7,11.6L455.2-212.6c-22.9-25.8-101.3,34.4-118.8,76.8c-42.1,11.9-85.6,16.4-126.2,16.4c-49.5,0-94.4-6.6-126.6-13.2
c-16.1-3.3-29-6.6-37.6-9c-4.3-1.1-7.6-2.2-9.7-2.8c-1.1-0.3-1.8-0.6-2.3-0.7c-0.4-0.2-0.4-0.2-0.4-0.2c-0.5-0.2-0.9-0.2-1.4-0.4
c-4.2-2-8.6-3.7-13.2-4.8c-53.8-13.4-131.9,15.8-163.7,108.1c-42.9,127.3-52.2,210.1-35.8,350.2c17.3,89.2,73.2,108.1,125.7,110.8
c4,0.7,8.1,1.1,12.3,1.1l0,0h302.7L359.9,687c11.9,31.7,41.9,51.3,73.9,51.3c9.2,0,18.5-1.6,27.6-5c40.8-15.2,61.5-60.6,46.3-101.4
L388.8,313.4c-11.5-30.8-41-51.3-73.9-51.3h-98.5l59.5-37.2c36.9-23.1-46.8-156.7-83.7-133.7L46.3,182.6
c5.6-48.8,14.9-96.4,23.5-138.7c-54.2-9.9-89.7-24-99.2-28c-15.9-7-27.7-19.3-33.9-35s-5.8-32.8,1-48.3
c10.1-23,32.7-37.8,57.8-37.8c8.8,0,17.3,1.8,25.3,5.3l1.2,0.5c1.8,0.7,4.5,1.7,8,3c7,2.5,18.3,6.1,33.1,9.8
c26.9,6.8,70,14.8,122.5,14.8c79.8,0,157.6-18.2,231.1-54c8.7-4.3,18-6.4,27.6-6.4c24.4,0,46.1,13.6,56.8,35.5
c15.2,31.2,2.1,69.1-29.1,84.3c-11.7,5.7-23.5,11-35.3,16l100.3,112.7c29,32.6,78.8,35.4,111.3,6.5c21-18.7,29.7-46.2,25.3-72.2
C671.2,36.6,665,23,654.7,11.6z"/>
<path d="M489.7-91.2c-12.2-25-42.4-35.5-67.5-23.3c-87.4,42.6-169.1,55.3-236.6,55.3c-52,0-95.5-7.6-125.7-15.2
c-15-3.8-26.7-7.4-34.3-10.1c-3.8-1.3-6.6-2.4-8.3-3.1c-0.8-0.3-1.5-0.6-1.7-0.7h-0.1c-25.5-11.1-55.3,0.5-66.4,26
C-62-36.8-50.4-7.1-24.8,4.1l0,0c4.3,1.8,86.6,37.5,210.6,37.7c0.1,0,0.2,0,0.2,0c80.2,0,177.9-15.5,280.6-65.4
C491.5-35.9,501.9-66,489.7-91.2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

+3 -3
View File
@@ -2,10 +2,10 @@
"private": true,
"name": "tgfont",
"version": "1.0.0",
"dependencies": {
"fantasticon": "^1.2.3"
},
"scripts": {
"build": "node mkdist.cjs && fantasticon --config config.cjs"
},
"dependencies": {
"fantasticon": "^1.2.3"
}
}
+73
View File
@@ -0,0 +1,73 @@
/**
* @file
* @copyright 2021 Aleksej Komarov
* @license MIT
*/
import { setupGlobalEvents } from 'tgui/events';
import 'tgui/styles/main.scss';
import Benchmark from './lib/benchmark';
const sendMessage = (obj: any) => {
const req = new XMLHttpRequest();
req.open('POST', `/message`, false);
req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
// req.timeout = 250;
req.send(JSON.stringify(obj));
};
const setupApp = async () => {
// Delay setup
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', setupApp);
return;
}
setupGlobalEvents({
ignoreWindowFocus: true,
});
const requireTest = require.context('./tests', false, /\.test\./);
for (const file of requireTest.keys()) {
sendMessage({ type: 'suite-start', file });
try {
const tests = requireTest(file);
await new Promise<void>((resolve) => {
const suite = new Benchmark.Suite(file, {
onCycle(e) {
sendMessage({
type: 'suite-cycle',
message: String(e.target),
});
},
onComplete() {
// This message is somewhat useless, but leaving it here in case
// someone has an idea how to show more useful data.
// sendMessage({
// type: 'suite-complete',
// message: 'Fastest is ' + this.filter('fastest').map('name'),
// });
resolve();
},
onError(e) {
sendMessage({ type: 'error', e });
resolve();
},
});
for (const [name, fn] of Object.entries(tests)) {
if (typeof fn === 'function') {
suite.add(name, fn);
}
}
suite.run();
});
}
catch (error) {
sendMessage({ type: 'error', error });
}
}
sendMessage({ type: 'finished' });
};
setupApp();
+93
View File
@@ -0,0 +1,93 @@
/**
* @file
* @copyright 2021 Aleksej Komarov
* @license MIT
*/
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const { fastify } = require('fastify');
process.chdir(__dirname);
const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));
const IE_TIMEOUT_SECONDS = 60;
const setup = async () => {
const server = fastify();
let hasResponded = false;
let assets = '';
assets += `<script>\n`;
assets += `Byond.loadJs('tgui-bench.bundle.js');\n`;
assets += `Byond.loadCss('tgui-bench.bundle.css');\n`;
assets += `</script>\n`;
const publicDir = path.resolve(__dirname, '../../public');
const page = fs.readFileSync(path.join(publicDir, 'tgui.html'), 'utf-8')
.replace('<!-- tgui:assets -->\n', assets);
server.register(require('@fastify/static'), {
root: publicDir,
});
server.get('/', async (req, res) => {
return res.type('text/html').send(page);
});
server.post('/message', async (req, res) => {
if (!hasResponded) {
process.stdout.write('\n');
hasResponded = true;
}
const { type, ...rest } = req.body;
if (type === 'suite-start') {
console.log(`=> Test '${rest.file}'`);
return res.send();
}
if (type === 'suite-cycle') {
console.log(rest.message);
return res.send();
}
if (type === 'suite-complete') {
console.log(rest.message);
return res.send();
}
if (type === 'finished') {
await res.send();
process.exit(0);
}
// Unhandled message
console.log(req.body);
return res.send();
});
try {
await server.listen(3002, '0.0.0.0');
}
catch (err) {
console.error(err);
process.exit(1);
}
if (process.platform === 'win32') {
exec(`start "" "iexplore" "http://127.0.0.1:3002"`);
}
console.log('Waiting for Internet Explorer to respond.');
for (let i = 0; i < IE_TIMEOUT_SECONDS; i++) {
await sleep(1000);
if (hasResponded) {
return;
}
process.stdout.write('.');
}
process.stdout.write('\n');
console.error('Did not receive a response, exiting.');
process.exit(1);
};
setup();
+219
View File
@@ -0,0 +1,219 @@
/* eslint-disable */
// Type definitions for Benchmark v2.1.4
// Project: https://benchmarkjs.com
// Definitions by: Asana <https://asana.com>
// Charlie Fish <https://github.com/fishcharlie>
// Blair Zajac <https://github.com/blair>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare class Benchmark {
static filter<T>(arr: T[], callback: (value: T) => any, thisArg?: any): T[];
static filter<T>(arr: T[], filter: string, thisArg?: any): T[];
static formatNumber(num: number): string;
static join(obj: Object, separator1?: string, separator2?: string): string;
static invoke(
benches: Benchmark[],
name: string | Object,
...args: any[]
): any[];
static runInContext(context: Object): Function;
static each(obj: Object | any[], callback: Function, thisArg?: any): void;
static forEach<T>(arr: T[], callback: (value: T) => any, thisArg?: any): void;
static forOwn(obj: Object, callback: Function, thisArg?: any): void;
static has(obj: Object, path: any[] | string): boolean;
static indexOf<T>(arr: T[], value: T, fromIndex?: number): number;
static map<T, K>(arr: T[], callback: (value: T) => K, thisArg?: any): K[];
static reduce<T, K>(
arr: T[],
callback: (accumulator: K, value: T) => K,
thisArg?: any
): K;
static options: Benchmark.Options;
static platform: Benchmark.Platform;
static support: Benchmark.Support;
static version: string;
constructor(fn: Function | string, options?: Benchmark.Options);
constructor(name: string, fn: Function | string, options?: Benchmark.Options);
constructor(name: string, options?: Benchmark.Options);
constructor(options: Benchmark.Options);
id: number;
name: string;
count: number;
cycles: number;
hz: number;
compiled: Function | string;
error: Error;
fn: Function | string;
aborted: boolean;
running: boolean;
setup: Function | string;
teardown: Function | string;
stats: Benchmark.Stats;
times: Benchmark.Times;
abort(): Benchmark;
clone(options: Benchmark.Options): Benchmark;
compare(benchmark: Benchmark): number;
emit(type: string | Object): any;
listeners(type: string): Function[];
off(type?: string, listener?: Function): Benchmark;
off(types: string[]): Benchmark;
on(type?: string, listener?: Function): Benchmark;
on(types: string[]): Benchmark;
reset(): Benchmark;
run(options?: Benchmark.Options): Benchmark;
toString(): string;
}
declare namespace Benchmark {
export interface Options {
async?: boolean | undefined;
defer?: boolean | undefined;
delay?: number | undefined;
id?: string | undefined;
initCount?: number | undefined;
maxTime?: number | undefined;
minSamples?: number | undefined;
minTime?: number | undefined;
name?: string | undefined;
onAbort?: Function | undefined;
onComplete?: Function | undefined;
onCycle?: Function | undefined;
onError?: Function | undefined;
onReset?: Function | undefined;
onStart?: Function | undefined;
setup?: Function | string | undefined;
teardown?: Function | string | undefined;
fn?: Function | string | undefined;
queued?: boolean | undefined;
}
export interface Platform {
description: string;
layout: string;
product: string;
name: string;
manufacturer: string;
os: string;
prerelease: string;
version: string;
toString(): string;
}
export interface Support {
browser: boolean;
timeout: boolean;
decompilation: boolean;
}
export interface Stats {
moe: number;
rme: number;
sem: number;
deviation: number;
mean: number;
sample: any[];
variance: number;
}
export interface Times {
cycle: number;
elapsed: number;
period: number;
timeStamp: number;
}
export class Deferred {
constructor(clone: Benchmark);
benchmark: Benchmark;
cycles: number;
elapsed: number;
timeStamp: number;
resolve(): void;
}
export interface Target {
options: Options;
async?: boolean | undefined;
defer?: boolean | undefined;
delay?: number | undefined;
initCount?: number | undefined;
maxTime?: number | undefined;
minSamples?: number | undefined;
minTime?: number | undefined;
name?: string | undefined;
fn?: Function | undefined;
id: number;
stats?: Stats | undefined;
times?: Times | undefined;
running: boolean;
count?: number | undefined;
compiled?: Function | undefined;
cycles?: number | undefined;
hz?: number | undefined;
}
export class Event {
constructor(type: string | Object);
aborted: boolean;
cancelled: boolean;
currentTarget: Object;
result: any;
target: Target;
timeStamp: number;
type: string;
}
export class Suite {
static options: { name: string };
constructor(name?: string, options?: Options);
length: number;
aborted: boolean;
running: boolean;
abort(): Suite;
add(name: string, fn: Function | string, options?: Options): Suite;
add(fn: Function | string, options?: Options): Suite;
add(name: string, options?: Options): Suite;
add(options: Options): Suite;
clone(options: Options): Suite;
emit(type: string | Object): any;
filter(callback: Function | string): Suite;
join(separator?: string): string;
listeners(type: string): Function[];
off(type?: string, callback?: Function): Suite;
off(types: string[]): Suite;
on(type?: string, callback?: Function): Suite;
on(types: string[]): Suite;
push(benchmark: Benchmark): number;
reset(): Suite;
run(options?: Options): Suite;
reverse(): any[];
sort(compareFn: (a: any, b: any) => number): any[];
splice(start: number, deleteCount?: number): any[];
unshift(benchmark: Benchmark): number;
each(callback: Function): Suite;
forEach(callback: Function): Suite;
indexOf(value: any): number;
map(callback: Function | string): any[];
reduce<T>(callback: Function, accumulator: T): T;
pop(): Function;
shift(): Benchmark;
slice(start: number, end: number): any[];
slice(start: number, deleteCount: number, ...values: any[]): any[];
}
}
export = Benchmark;
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
{
"private": true,
"name": "tgui-bench",
"version": "4.3.0",
"dependencies": {
"@fastify/static": "^5.0.2",
"common": "workspace:*",
"fastify": "^3.20.2",
"inferno": "^7.4.8",
"inferno-vnode-flags": "^7.4.8",
"lodash": "^4.17.21",
"platform": "^1.3.6",
"tgui": "workspace:*"
}
}
@@ -0,0 +1,99 @@
import { linkEvent } from 'inferno';
import { Button } from 'tgui/components';
import { createRenderer } from 'tgui/renderer';
const render = createRenderer();
const handleClick = () => undefined;
export const SingleButton = () => {
const node = (
<Button>
Hello world!
</Button>
);
render(node);
};
export const SingleButtonWithCallback = () => {
const node = (
<Button onClick={() => undefined}>
Hello world!
</Button>
);
render(node);
};
export const SingleButtonWithLinkEvent = () => {
const node = (
<Button onClick={linkEvent(null, handleClick)}>
Hello world!
</Button>
);
render(node);
};
export const ListOfButtons = () => {
const nodes: JSX.Element[] = [];
for (let i = 0; i < 100; i++) {
const node = (
<Button key={i}>
Hello world! {i}
</Button>
);
nodes.push(node);
}
render(<div>{nodes}</div>);
};
export const ListOfButtonsWithCallback = () => {
const nodes: JSX.Element[] = [];
for (let i = 0; i < 100; i++) {
const node = (
<Button key={i} onClick={() => undefined}>
Hello world! {i}
</Button>
);
nodes.push(node);
}
render(<div>{nodes}</div>);
};
export const ListOfButtonsWithLinkEvent = () => {
const nodes: JSX.Element[] = [];
for (let i = 0; i < 100; i++) {
const node = (
<Button key={i} onClick={linkEvent(null, handleClick)}>
Hello world! {i}
</Button>
);
nodes.push(node);
}
render(<div>{nodes}</div>);
};
export const ListOfButtonsWithIcons = () => {
const nodes: JSX.Element[] = [];
for (let i = 0; i < 100; i++) {
const node = (
<Button key={i} icon={'arrow-left'}>
Hello world! {i}
</Button>
);
nodes.push(node);
}
render(<div>{nodes}</div>);
};
export const ListOfButtonsWithTooltips = () => {
const nodes: JSX.Element[] = [];
for (let i = 0; i < 100; i++) {
const node = (
<Button key={i} tooltip={'Hello world!'}>
Hello world! {i}
</Button>
);
nodes.push(node);
}
render(<div>{nodes}</div>);
};
@@ -0,0 +1,28 @@
import { backendUpdate } from 'tgui/backend';
import { DisposalBin } from 'tgui/interfaces/DisposalBin';
import { createRenderer } from 'tgui/renderer';
import { configureStore, StoreProvider } from 'tgui/store';
const store = configureStore({ sideEffets: false });
const renderUi = createRenderer((dataJson: string) => {
store.dispatch(backendUpdate({
data: Byond.parseJson(dataJson),
}));
return (
<StoreProvider store={store}>
<DisposalBin />
</StoreProvider>
);
});
export const data = JSON.stringify({
flush: 0,
full_pressure: 1,
pressure_charging: 0,
panel_open: 0,
per: 1,
isai: 0,
});
export const Default = () => renderUi(data);
@@ -0,0 +1,18 @@
import { Flex } from 'tgui/components';
import { createRenderer } from 'tgui/renderer';
const render = createRenderer();
export const Default = () => {
const node = (
<Flex align="baseline">
<Flex.Item mr={1}>
Text {Math.random()}
</Flex.Item>
<Flex.Item grow={1} basis={0}>
Text {Math.random()}
</Flex.Item>
</Flex>
);
render(node);
};
@@ -0,0 +1,18 @@
import { Stack } from 'tgui/components';
import { createRenderer } from 'tgui/renderer';
const render = createRenderer();
export const Default = () => {
const node = (
<Stack align="baseline">
<Stack.Item>
Text {Math.random()}
</Stack.Item>
<Stack.Item grow={1} basis={0}>
Text {Math.random()}
</Stack.Item>
</Stack>
);
render(node);
};
@@ -0,0 +1,20 @@
import { Box, Tooltip } from "tgui/components";
import { createRenderer } from "tgui/renderer";
const render = createRenderer();
export const ListOfTooltips = () => {
const nodes: JSX.Element[] = [];
for (let i = 0; i < 100; i++) {
nodes.push(
<Tooltip key={i} content={`This is from tooltip ${i}`} position="bottom">
<Box as="span" backgroundColor="blue" fontSize="48px" m={1}>
Tooltip #{i}
</Box>
</Tooltip>
);
}
render(<div>{nodes}</div>);
};
+1 -1
View File
@@ -743,7 +743,7 @@
ontype = 'on' + type,
handlers = (window[ontype] || Object)[SECRET],
i = handlers ? find(handlers, handler) : -1
;
;
if (-1 < i) handlers.splice(i, 1);
}),
pageXOffset: {get: getter('scrollLeft')},
@@ -0,0 +1,19 @@
import { Component, createRef } from "inferno";
export class Autofocus extends Component {
ref = createRef<HTMLDivElement>();
componentDidMount() {
setTimeout(() => {
this.ref.current?.focus();
}, 1);
}
render() {
return (
<div ref={this.ref} tabIndex={-1}>
{this.props.children}
</div>
);
}
}
+6 -6
View File
@@ -5,7 +5,7 @@
*/
import { BooleanLike, classes, pureComponentHooks } from 'common/react';
import { createVNode, InfernoNode } from 'inferno';
import { createVNode, InfernoNode, SFC } from 'inferno';
import { ChildFlags, VNodeFlags } from 'inferno-vnode-flags';
import { CSS_COLORS } from '../constants';
@@ -109,9 +109,7 @@ export const halfUnit = (value: unknown): string | undefined => {
const isColorCode = (str: unknown) => !isColorClass(str);
const isColorClass = (str: unknown): boolean => {
if (typeof str === 'string') {
return CSS_COLORS.includes(str);
}
return typeof str === "string" && CSS_COLORS.includes(str);
};
const mapRawPropTo = attrName => (style, value) => {
@@ -290,7 +288,7 @@ export const computeBoxClassName = (props: BoxProps) => {
]);
};
export const Box = (props: BoxProps) => {
export const Box: SFC<BoxProps> = (props: BoxProps) => {
const {
as = 'div',
className,
@@ -312,7 +310,9 @@ export const Box = (props: BoxProps) => {
computedClassName,
children,
ChildFlags.UnknownChildren,
computedProps);
computedProps,
undefined,
);
};
Box.defaultHooks = pureComponentHooks;
+18 -12
View File
@@ -8,7 +8,7 @@ import { KEY_ENTER, KEY_ESCAPE, KEY_SPACE } from 'common/keycodes';
import { classes, pureComponentHooks } from 'common/react';
import { Component, createRef } from 'inferno';
import { createLogger } from '../logging';
import { Box } from './Box';
import { Box, computeBoxClassName, computeBoxProps } from './Box';
import { Icon } from './Icon';
import { Tooltip } from './Tooltip';
@@ -47,10 +47,17 @@ export const Button = props => {
+ `'onClick' instead and read: `
+ `https://infernojs.org/docs/guides/event-handling`);
}
// IE8: Use a lowercase "onclick" because synthetic events are fucked.
// IE8: Use an "unselectable" prop because "user-select" doesn't work.
rest.onClick = e => {
if (!disabled && onClick) {
onClick(e);
}
};
// IE8: Use "unselectable" because "user-select" doesn't work.
if (Byond.IS_LTE_IE8) {
rest.unselectable = true;
}
let buttonContent = (
<Box
<div
className={classes([
'Button',
fluid && 'Button--fluid',
@@ -65,15 +72,14 @@ export const Button = props => {
? 'Button--color--' + color
: 'Button--color--default',
className,
computeBoxClassName(rest),
])}
tabIndex={!disabled && '0'}
unselectable={Byond.IS_LTE_IE8}
onClick={e => {
if (!disabled && onClick) {
onClick(e);
}
}}
onKeyDown={e => {
if (props.captureKeys === false) {
return;
}
const keyCode = window.event ? e.which : e.keyCode;
// Simulate a click when pressing space or enter.
if (keyCode === KEY_SPACE || keyCode === KEY_ENTER) {
@@ -89,7 +95,7 @@ export const Button = props => {
return;
}
}}
{...rest}>
{...computeBoxProps(rest)}>
{(icon && iconPosition !== 'right') && (
<Icon
name={icon}
@@ -108,7 +114,7 @@ export const Button = props => {
fontSize={iconSize} // VOREStation Addition
/>
)}
</Box>
</div>
);
if (tooltip) {
+1 -2
View File
@@ -133,11 +133,10 @@ export class ByondUi extends Component {
render() {
const { params, ...rest } = this.props;
const boxProps = computeBoxProps(rest);
return (
<div
ref={this.containerRef}
{...boxProps}>
{...computeBoxProps(rest)}>
{/* Filler */}
<div style={{ 'min-height': '22px' }} />
</div>
+52 -31
View File
@@ -5,16 +5,26 @@
*/
import { BooleanLike, classes, pureComponentHooks } from 'common/react';
import { Box, BoxProps, unit } from './Box';
import { BoxProps, computeBoxClassName, computeBoxProps, unit } from './Box';
export interface FlexProps extends BoxProps {
export type FlexProps = BoxProps & {
direction?: string | BooleanLike;
wrap?: string | BooleanLike;
align?: string | BooleanLike;
alignContent?: string | BooleanLike; // VOREStation Addition
justify?: string | BooleanLike;
inline?: BooleanLike;
}
};
export const computeFlexClassName = (props: FlexProps) => {
return classes([
'Flex',
props.inline && 'Flex--inline',
Byond.IS_LTE_IE10 && 'Flex--iefix',
Byond.IS_LTE_IE10 && props.direction === 'column' && 'Flex--iefix--column',
computeBoxClassName(props),
]);
};
export const computeFlexProps = (props: FlexProps) => {
const {
@@ -27,17 +37,7 @@ export const computeFlexProps = (props: FlexProps) => {
inline,
...rest
} = props;
return {
className: classes([
'Flex',
Byond.IS_LTE_IE10 && (
direction === 'column'
? 'Flex--iefix--column'
: 'Flex--iefix'
),
inline && 'Flex--inline',
className,
]),
return computeBoxProps({
style: {
...rest.style,
'flex-direction': direction,
@@ -47,22 +47,39 @@ export const computeFlexProps = (props: FlexProps) => {
'justify-content': justify,
},
...rest,
};
});
};
export const Flex = props => (
<Box {...computeFlexProps(props)} />
);
export const Flex = props => {
const { className, ...rest } = props;
return (
<div
className={classes([
className,
computeFlexClassName(rest),
])}
{...computeFlexProps(rest)}
/>
);
};
Flex.defaultHooks = pureComponentHooks;
export interface FlexItemProps extends BoxProps {
export type FlexItemProps = BoxProps & {
grow?: number;
order?: number;
shrink?: number;
basis?: string | BooleanLike;
align?: string | BooleanLike;
}
};
export const computeFlexItemClassName = (props: FlexItemProps) => {
return classes([
'Flex__item',
Byond.IS_LTE_IE10 && 'Flex__item--iefix',
computeBoxClassName(props),
]);
};
export const computeFlexItemProps = (props: FlexItemProps) => {
const {
@@ -77,13 +94,7 @@ export const computeFlexItemProps = (props: FlexItemProps) => {
align,
...rest
} = props;
return {
className: classes([
'Flex__item',
Byond.IS_LTE_IE10 && 'Flex__item--iefix',
Byond.IS_LTE_IE10 && grow > 0 && 'Flex__item--iefix--grow',
className,
]),
return computeBoxProps({
style: {
...style,
'flex-grow': grow !== undefined && Number(grow),
@@ -93,12 +104,22 @@ export const computeFlexItemProps = (props: FlexItemProps) => {
'align-self': align,
},
...rest,
};
});
};
const FlexItem = props => (
<Box {...computeFlexItemProps(props)} />
);
const FlexItem = props => {
const { className, ...rest } = props;
return (
<div
className={classes([
className,
computeFlexItemClassName(props),
computeBoxClassName(props),
])}
{...computeFlexItemProps(rest)}
/>
);
};
FlexItem.defaultHooks = pureComponentHooks;
+21 -15
View File
@@ -7,7 +7,7 @@
*/
import { classes, pureComponentHooks } from 'common/react';
import { Box } from './Box';
import { computeBoxClassName, computeBoxProps } from './Box';
const FA_OUTLINE_REGEX = /-o$/;
@@ -17,17 +17,26 @@ export const Icon = props => {
size,
spin,
className,
style = {},
rotation,
inverse,
...rest
} = props;
if (size) {
style['font-size'] = (size * 100) + '%';
if (!rest.style) {
rest.style = {};
}
rest.style['font-size'] = (size * 100) + '%';
}
if (typeof rotation === 'number') {
style['transform'] = `rotate(${rotation}deg)`;
if (!rest.style) {
rest.style = {};
}
rest.style['transform'] = `rotate(${rotation}deg)`;
}
const boxProps = computeBoxProps(rest);
let iconClass = "";
if (name.startsWith("tg-")) {
// tgfont icon
@@ -39,15 +48,14 @@ export const Icon = props => {
iconClass = (faRegular ? 'far ' : 'fas ') + 'fa-'+ faName + (spin ? " fa-spin" : "");
}
return (
<Box
as="i"
<i
className={classes([
'Icon',
className,
iconClass,
className,
computeBoxClassName(rest),
])}
style={style}
{...rest} />
{...boxProps} />
);
};
@@ -56,21 +64,19 @@ Icon.defaultHooks = pureComponentHooks;
export const IconStack = props => {
const {
className,
style = {},
children,
...rest
} = props;
return (
<Box
as="span"
<span
class={classes([
'IconStack',
className,
computeBoxClassName(rest),
])}
style={style}
{...rest}>
{...computeBoxProps(rest)}>
{children}
</Box>
</span>
);
};
+14 -2
View File
@@ -73,6 +73,11 @@ export class Input extends Component {
return;
}
if (e.keyCode === KEY_ESCAPE) {
if (this.props.onEscape) {
this.props.onEscape(e);
return;
}
this.setEditing(false);
e.target.value = toInputValue(this.props.value);
e.target.blur();
@@ -87,8 +92,15 @@ export class Input extends Component {
if (input) {
input.value = toInputValue(nextValue);
}
if (this.props.autoFocus) {
setTimeout(() => input.focus(), 1);
if (this.props.autoFocus || this.props.autoSelect) {
setTimeout(() => {
input.focus();
if (this.props.autoSelect) {
input.select();
}
}, 1);
}
}
@@ -0,0 +1,39 @@
import { Component } from "inferno";
import { KeyEvent } from "../events";
import { listenForKeyEvents } from "../hotkeys";
type KeyListenerProps = Partial<{
onKey: (key: KeyEvent) => void,
onKeyDown: (key: KeyEvent) => void,
onKeyUp: (key: KeyEvent) => void,
}>;
export class KeyListener extends Component<KeyListenerProps> {
dispose: () => void;
constructor() {
super();
this.dispose = listenForKeyEvents(key => {
if (this.props.onKey) {
this.props.onKey(key);
}
if (key.isDown() && this.props.onKeyDown) {
this.props.onKeyDown(key);
}
if (key.isUp() && this.props.onKeyUp) {
this.props.onKeyUp(key);
}
});
}
componentWillUnmount() {
this.dispose();
}
render() {
return null;
}
}
+29 -16
View File
@@ -1,10 +1,10 @@
// import { createPopper, OptionsGeneric } from "@popperjs/core";
import { createPopper, OptionsGeneric } from '@popperjs/core';
import { createPopper } from '@popperjs/core';
import { ArgumentsOf } from 'common/types';
import { Component, findDOMfromVNode, InfernoNode, render } from 'inferno';
type PopperProps = {
popperContent: InfernoNode;
options?: Partial<OptionsGeneric<unknown>>;
options?: ArgumentsOf<typeof createPopper>[2];
additionalStyles?: CSSProperties;
};
@@ -33,17 +33,22 @@ export class Popper extends Component<PopperProps> {
this.renderPopperContent(() => {
document.body.appendChild(this.renderedContent);
// HACK: We don't want to create a wrapper, as it could break the layout
// of consumers, so we do the inferno equivalent of `findDOMNode(this)`.
// This is usually bad as refs are usually better, but refs did
// not work in this case, as they weren't propagating correctly.
// A previous attempt was made as a render prop that passed an ID,
// but this made consuming use too unwieldly.
// This code is copied from `findDOMNode` in inferno-extras.
// Because this component is written in TypeScript, we will know
// immediately if this internal variable is removed.
const domNode = findDOMfromVNode(this.$LI, true);
if (!domNode) {
return;
}
this.popperInstance = createPopper(
// HACK: We don't want to create a wrapper, as it could break the layout
// of consumers, so we do the inferno equivalent of `findDOMNode(this)`.
// This is usually bad as refs are usually better, but refs did
// not work in this case, as they weren't propagating correctly.
// A previous attempt was made as a render prop that passed an ID,
// but this made consuming use too unwieldly.
// This code is copied from `findDOMNode` in inferno-extras.
// Because this component is written in TypeScript, we will know
// immediately if this internal variable is removed.
findDOMfromVNode(this.$LI, true),
domNode,
this.renderedContent,
options
);
@@ -56,12 +61,20 @@ export class Popper extends Component<PopperProps> {
componentWillUnmount() {
this.popperInstance?.destroy();
this.renderedContent.remove();
this.renderedContent = null;
render(null, this.renderedContent, () => {
this.renderedContent.remove();
});
}
renderPopperContent(callback: () => void) {
render(this.props.popperContent, this.renderedContent, callback);
// `render` errors when given false, so we convert it to `null`,
// which is supported.
render(
this.props.popperContent || null,
this.renderedContent,
callback,
this.context,
);
}
render() {
+5 -1
View File
@@ -40,7 +40,11 @@ export class Section extends Component<SectionProps> {
addScrollableNode(this.scrollableRef.current);
}
if (this.props.autoFocus) {
setTimeout(() => this.scrollableRef.current.focus(), 1);
setTimeout(() => {
if (this.scrollableRef.current) {
return this.scrollableRef.current.focus();
}
}, 1);
}
}
+8 -2
View File
@@ -5,6 +5,7 @@
*/
import { classes } from 'common/react';
import { RefObject } from 'inferno';
import { Flex, FlexItemProps, FlexProps } from './Flex';
interface StackProps extends FlexProps {
@@ -29,14 +30,19 @@ export const Stack = (props: StackProps) => {
);
};
const StackItem = (props: FlexProps) => {
const { className, ...rest } = props;
type StackItemProps = FlexProps & {
innerRef?: RefObject<HTMLDivElement>,
};
const StackItem = (props: StackItemProps) => {
const { className, innerRef, ...rest } = props;
return (
<Flex.Item
className={classes([
'Stack__item',
className,
])}
ref={innerRef}
{...rest} />
);
};
+15 -12
View File
@@ -7,7 +7,7 @@ const DEFAULT_PLACEMENT = "top";
type TooltipProps = {
children?: InfernoNode;
content: string;
content: InfernoNode;
position?: Placement,
};
@@ -15,14 +15,15 @@ type TooltipState = {
hovered: boolean;
};
export class Tooltip extends Component<TooltipProps, TooltipState> {
constructor() {
super();
const DISABLE_EVENT_LISTENERS = [{
name: "eventListeners",
enabled: false,
}];
this.state = {
hovered: false,
};
}
export class Tooltip extends Component<TooltipProps, TooltipState> {
state = {
hovered: false,
};
componentDidMount() {
// HACK: We don't want to create a wrapper, as it could break the layout
@@ -35,6 +36,10 @@ export class Tooltip extends Component<TooltipProps, TooltipState> {
// immediately if this internal variable is removed.
const domNode = findDOMfromVNode(this.$LI, true);
if (!domNode) {
return;
}
domNode.addEventListener("mouseenter", () => {
this.setState({
hovered: true,
@@ -53,10 +58,7 @@ export class Tooltip extends Component<TooltipProps, TooltipState> {
<Popper
options={{
placement: this.props.position || "auto",
modifiers: [{
name: "eventListeners",
enabled: false,
}],
modifiers: DISABLE_EVENT_LISTENERS,
}}
popperContent={
<div
@@ -69,6 +71,7 @@ export class Tooltip extends Component<TooltipProps, TooltipState> {
}
additionalStyles={{
"pointer-events": "none",
"z-index": 2,
}}>
{this.props.children}
</Popper>
@@ -0,0 +1,37 @@
import { Component, createRef } from "inferno";
export class TrackOutsideClicks extends Component<{
onOutsideClick: () => void,
}> {
ref = createRef<HTMLDivElement>();
constructor() {
super();
this.handleOutsideClick = this.handleOutsideClick.bind(this);
document.addEventListener("click", this.handleOutsideClick);
}
componentWillUnmount() {
document.removeEventListener("click", this.handleOutsideClick);
}
handleOutsideClick(event: MouseEvent) {
if (!(event.target instanceof Node)) {
return;
}
if (this.ref.current && !this.ref.current.contains(event.target)) {
this.props.onOutsideClick();
}
}
render() {
return (
<div ref={this.ref}>
{this.props.children}
</div>
);
}
}
+3
View File
@@ -5,6 +5,7 @@
*/
export { AnimatedNumber } from './AnimatedNumber';
export { Autofocus } from './Autofocus';
export { Blink } from './Blink';
export { BlockQuote } from './BlockQuote';
export { Box } from './Box';
@@ -22,6 +23,7 @@ export { Grid } from './Grid';
export { Icon } from './Icon';
export { InfinitePlane } from './InfinitePlane';
export { Input } from './Input';
export { KeyListener } from './KeyListener';
export { Knob } from './Knob';
export { LabeledControls } from './LabeledControls';
export { LabeledList } from './LabeledList';
@@ -39,4 +41,5 @@ export { Table } from './Table';
export { Tabs } from './Tabs';
export { TextArea } from './TextArea';
export { TimeDisplay } from './TimeDisplay';
export { TrackOutsideClicks } from './TrackOutsideClicks';
export { Tooltip } from './Tooltip';
+35
View File
@@ -31,6 +31,9 @@ const hotKeysAcquired = [
// State of passed-through keys.
const keyState: Record<string, boolean> = {};
// Custom listeners for key events
const keyListeners: ((key: KeyEvent) => void)[] = [];
/**
* Converts a browser keycode to BYOND keycode.
*/
@@ -178,6 +181,38 @@ export const setupHotKeys = () => {
releaseHeldKeys();
});
globalEvents.on('key', (key: KeyEvent) => {
for (const keyListener of keyListeners) {
keyListener(key);
}
handlePassthrough(key);
});
};
/**
* Registers for any key events, such as key down or key up.
* This should be preferred over directly connecting to keydown/keyup
* as it lets tgui prevent the key from reaching BYOND.
*
* If using in a component, prefer KeyListener, which automatically handles
* stopping listening when unmounting.
*
* @param callback The function to call whenever a key event occurs
* @returns A callback to stop listening
*/
export const listenForKeyEvents = (
callback: (key: KeyEvent) => void,
): () => void => {
keyListeners.push(callback);
let removed = false;
return () => {
if (removed) {
return;
}
removed = true;
keyListeners.splice(keyListeners.indexOf(callback), 1);
};
};
+17
View File
@@ -0,0 +1,17 @@
/**
* An equivalent to `fetch`, except will automatically retry.
*/
export const fetchRetry
= (
url: string,
options?: RequestInit,
retryTimer: number = 1000,
): Promise<Response> => {
return fetch(url, options).catch(() => {
return new Promise(resolve => {
setTimeout(() => {
fetchRetry(url, options, retryTimer).then(resolve);
}, retryTimer);
});
});
};
+2 -2
View File
@@ -37,7 +37,7 @@ export const Layout = props => {
className={classes([
'Layout',
className,
...computeBoxClassName(rest),
computeBoxClassName(rest),
])}
{...computeBoxProps(rest)}>
{children}
@@ -59,7 +59,7 @@ const LayoutContent = props => {
'Layout__content',
scrollable && 'Layout__content--scrollable',
className,
...computeBoxClassName(rest),
computeBoxClassName(rest),
])}
{...computeBoxProps(rest)}>
{children}
@@ -4,8 +4,8 @@ import { createLogger } from './logging';
const logger = createLogger('renderer');
let reactRoot;
let initialRender = true;
let reactRoot: any;
let initialRender: string | boolean = true;
let suspended = false;
// These functions are used purely for profiling.
@@ -18,13 +18,22 @@ export const suspendRenderer = () => {
suspended = true;
};
export const createRenderer = getVNode => () => {
type CreateRenderer = <T extends unknown[] = [unknown]>(
getVNode?: (...args: T) => any,
) => (...args: T) => void;
export const createRenderer: CreateRenderer = (getVNode) => (...args) => {
perf.mark('render/start');
// Start rendering
if (!reactRoot) {
reactRoot = document.getElementById('react-root');
}
render(getVNode(), reactRoot);
if (getVNode) {
render(getVNode(...args), reactRoot);
}
else {
render(args[0] as any, reactRoot);
}
perf.mark('render/finish');
if (suspended) {
return;
+10 -5
View File
@@ -15,6 +15,7 @@ import { createLogger } from './logging';
const logger = createLogger('store');
export const configureStore = (options = {}) => {
const { sideEffects = true } = options;
const reducer = flow([
combineReducers({
debug: debugReducer,
@@ -22,17 +23,21 @@ export const configureStore = (options = {}) => {
}),
options.reducer,
]);
const middleware = [
const middleware = !sideEffects ? [] : [
...(options.middleware?.pre || []),
assetMiddleware,
backendMiddleware,
...(options.middleware?.post || []),
];
if (process.env.NODE_ENV !== 'production') {
middleware.unshift(
loggingMiddleware,
debugMiddleware,
relayMiddleware);
// We are using two if statements because Webpack is capable of
// removing this specific block as dead code.
if (sideEffects) {
middleware.unshift(
loggingMiddleware,
debugMiddleware,
relayMiddleware);
}
}
const enhancer = applyMiddleware(...middleware);
const store = createStore(reducer, enhancer);
+8 -29
View File
@@ -13,40 +13,19 @@
}
.Flex--iefix {
display: table !important;
width: 105%;
border-collapse: collapse;
border-spacing: 0;
&:after {
content: '';
display: table-cell;
width: 5%;
}
display: block;
}
.Flex--iefix--column {
display: table !important;
width: 100% !important;
height: 100% !important;
border-collapse: collapse;
border-spacing: 0;
& > .Flex__item--iefix {
display: table-row !important;
}
& > .Flex__item--iefix--grow {
height: 100% !important;
}
.Flex--iefix.Flex--inline {
display: inline-block;
}
.Flex__item--iefix {
display: table-cell !important;
width: 1% !important;
min-width: 99%;
display: inline-block;
}
.Flex__item--iefix--grow {
width: auto !important;
.Flex--iefix--column {
& > .Flex__item--iefix {
display: block;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -14,6 +14,7 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": false,
"strictNullChecks": true,
"target": "ES3"
},
"include": [
+11 -8
View File
@@ -26,6 +26,7 @@ const createStats = verbose => ({
module.exports = (env = {}, argv) => {
const mode = argv.mode === 'production' ? 'production' : 'development';
const bench = env.TGUI_BENCH;
const config = {
mode,
context: path.resolve(__dirname),
@@ -59,7 +60,9 @@ module.exports = (env = {}, argv) => {
use: [
{
loader: require.resolve('babel-loader'),
options: createBabelConfig({ mode }),
options: createBabelConfig({
removeConsole: !bench,
}),
},
],
},
@@ -124,13 +127,13 @@ module.exports = (env = {}, argv) => {
],
};
// Add a bundle analyzer to the plugins array
if (argv.analyze) {
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
config.plugins = [
...config.plugins,
new BundleAnalyzerPlugin(),
];
if (bench) {
config.entry = {
'tgui-bench': [
'./packages/tgui-polyfill',
'./packages/tgui-bench/entrypoint',
],
};
}
// Production build specific options
+573 -13
View File
@@ -1592,6 +1592,37 @@ __metadata:
languageName: node
linkType: hard
"@fastify/ajv-compiler@npm:^1.0.0":
version: 1.1.0
resolution: "@fastify/ajv-compiler@npm:1.1.0"
dependencies:
ajv: ^6.12.6
checksum: b8a2522ead00a01ab7ff2921f00aa8e4aeb943949191ce2a617c88e4679db1358a70e4099791828a397a50e5d6f6bd75184ad0ac75a12dffeb9df4c089986a32
languageName: node
linkType: hard
"@fastify/error@npm:^2.0.0":
version: 2.0.0
resolution: "@fastify/error@npm:2.0.0"
checksum: ecf0834966b2bfb33ff834e3d55fe4dc04cbe9f822fda6c937b12cce4f162be4f8b0577ee665bc856d7012b1640c12472a1829a22ae38d287342c90b0f33a595
languageName: node
linkType: hard
"@fastify/static@npm:^5.0.2":
version: 5.0.2
resolution: "@fastify/static@npm:5.0.2"
dependencies:
content-disposition: ^0.5.3
encoding-negotiator: ^2.0.1
fastify-plugin: ^3.0.0
glob: ^7.1.4
p-limit: ^3.1.0
readable-stream: ^3.4.0
send: ^0.17.1
checksum: f66193a64fa0e160a1aebdeda0579aa19b7990da1a17721e2f91092b0a1d1caaeebff12dad1da2f83a435c387b45d6e9e7aa635579798805a60c6cc66230b3d2
languageName: node
linkType: hard
"@gar/promisify@npm:^1.1.3":
version: 1.1.3
resolution: "@gar/promisify@npm:1.1.3"
@@ -2198,6 +2229,24 @@ __metadata:
languageName: node
linkType: hard
"@types/webpack-env@npm:^1.17.0":
version: 1.17.0
resolution: "@types/webpack-env@npm:1.17.0"
checksum: 9ad4d208c4429c9427191d1f4c92e4c43e530384c17a6bc298acb89003fc47fcde1d8372e50acefa3061e9100e57fd9d616e96def875afd06c0c2afe508f298e
languageName: node
linkType: hard
"@types/webpack@npm:^5.28.0":
version: 5.28.0
resolution: "@types/webpack@npm:5.28.0"
dependencies:
"@types/node": "*"
tapable: ^2.2.0
webpack: ^5
checksum: a038d7e12dd109c6a8d2eb744fd32070ef94f1655e730fb1443b370db98864c3a0e408638b02d12ba08269b9c012b3be8b801117ced2d1102e7676203fd663ed
languageName: node
linkType: hard
"@types/yargs-parser@npm:*":
version: 20.2.0
resolution: "@types/yargs-parser@npm:20.2.0"
@@ -2502,6 +2551,13 @@ __metadata:
languageName: node
linkType: hard
"abstract-logging@npm:^2.0.0":
version: 2.0.1
resolution: "abstract-logging@npm:2.0.1"
checksum: 6967d15e5abbafd17f56eaf30ba8278c99333586fa4f7935fd80e93cfdc006c37fcc819c5d63ee373a12e6cb2d0417f7c3c6b9e42b957a25af9937d26749415e
languageName: node
linkType: hard
"acorn-globals@npm:^6.0.0":
version: 6.0.0
resolution: "acorn-globals@npm:6.0.0"
@@ -2635,7 +2691,7 @@ __metadata:
languageName: node
linkType: hard
"ajv@npm:^6.10.0, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5":
"ajv@npm:^6.10.0, ajv@npm:^6.11.0, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:^6.12.6":
version: 6.12.6
resolution: "ajv@npm:6.12.6"
dependencies:
@@ -2647,7 +2703,7 @@ __metadata:
languageName: node
linkType: hard
"ajv@npm:^8.0.0, ajv@npm:^8.8.0":
"ajv@npm:^8.0.0, ajv@npm:^8.1.0, ajv@npm:^8.8.0":
version: 8.11.0
resolution: "ajv@npm:8.11.0"
dependencies:
@@ -2755,6 +2811,13 @@ __metadata:
languageName: node
linkType: hard
"archy@npm:^1.0.0":
version: 1.0.0
resolution: "archy@npm:1.0.0"
checksum: 504ae7af655130bab9f471343cfdb054feaec7d8e300e13348bc9fe9e660f83d422e473069584f73233c701ae37d1c8452ff2522f2a20c38849e0f406f1732ac
languageName: node
linkType: hard
"are-we-there-yet@npm:^3.0.0":
version: 3.0.0
resolution: "are-we-there-yet@npm:3.0.0"
@@ -2859,6 +2922,25 @@ __metadata:
languageName: node
linkType: hard
"atomic-sleep@npm:^1.0.0":
version: 1.0.0
resolution: "atomic-sleep@npm:1.0.0"
checksum: b95275afb2f80732f22f43a60178430c468906a415a7ff18bcd0feeebc8eec3930b51250aeda91a476062a90e07132b43a1794e8d8ffcf9b650e8139be75fa36
languageName: node
linkType: hard
"avvio@npm:^7.1.2":
version: 7.2.5
resolution: "avvio@npm:7.2.5"
dependencies:
archy: ^1.0.0
debug: ^4.0.0
fastq: ^1.6.1
queue-microtask: ^1.1.2
checksum: 9a0aa7208441f5abe49c12741ad7f127283ec749b25f0b941a1c84e8f41e958b86b56a1c6baff5a7b5ae5e713a919f1128702dbcf80a6b17e7dc5b095c85b3bd
languageName: node
linkType: hard
"aws-sign2@npm:~0.7.0":
version: 0.7.0
resolution: "aws-sign2@npm:0.7.0"
@@ -3534,6 +3616,15 @@ __metadata:
languageName: node
linkType: hard
"content-disposition@npm:^0.5.3":
version: 0.5.4
resolution: "content-disposition@npm:0.5.4"
dependencies:
safe-buffer: 5.2.1
checksum: afb9d545e296a5171d7574fcad634b2fdf698875f4006a9dd04a3e1333880c5c0c98d47b560d01216fb6505a54a2ba6a843ee3a02ec86d7e911e8315255f56c3
languageName: node
linkType: hard
"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0":
version: 1.7.0
resolution: "convert-source-map@npm:1.7.0"
@@ -3543,6 +3634,13 @@ __metadata:
languageName: node
linkType: hard
"cookie@npm:^0.5.0":
version: 0.5.0
resolution: "cookie@npm:0.5.0"
checksum: 1f4bd2ca5765f8c9689a7e8954183f5332139eb72b6ff783d8947032ec1fdf43109852c178e21a953a30c0dd42257828185be01b49d1eb1a67fd054ca588a180
languageName: node
linkType: hard
"core-js-compat@npm:^3.21.0, core-js-compat@npm:^3.22.1":
version: 3.22.5
resolution: "core-js-compat@npm:3.22.5"
@@ -3554,9 +3652,9 @@ __metadata:
linkType: hard
"core-js@npm:^3.22.5":
version: 3.22.5
resolution: "core-js@npm:3.22.5"
checksum: d3d7495d7cdde01cf9ac3debc5087afc3c8dd56baa4953d9ccbb46b1a80872c79d14c1e6343c664c9c0fade288ab44c70b54dd34f879a71e6eff6fffeab84e00
version: 3.23.1
resolution: "core-js@npm:3.23.1"
checksum: 460328e0b743900d48fc744aab475f6dabdae498cc73f6d038321b0ae1488cb5e73d1670b5914abfe7dd84d0843a828b5d4dd3eba0a5b6a4450f0d7094cda2a5
languageName: node
linkType: hard
@@ -3672,7 +3770,16 @@ __metadata:
languageName: node
linkType: hard
"debug@npm:4, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4":
"debug@npm:2.6.9":
version: 2.6.9
resolution: "debug@npm:2.6.9"
dependencies:
ms: 2.0.0
checksum: d2f51589ca66df60bf36e1fa6e4386b318c3f1e06772280eea5b1ae9fd3d05e9c2b7fd8a7d862457d00853c75b00451aa2d7459b924629ee385287a650f58fe6
languageName: node
linkType: hard
"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4":
version: 4.3.4
resolution: "debug@npm:4.3.4"
dependencies:
@@ -3757,13 +3864,20 @@ __metadata:
languageName: node
linkType: hard
"depd@npm:^1.1.2":
"depd@npm:^1.1.2, depd@npm:~1.1.2":
version: 1.1.2
resolution: "depd@npm:1.1.2"
checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9
languageName: node
linkType: hard
"destroy@npm:~1.0.4":
version: 1.0.4
resolution: "destroy@npm:1.0.4"
checksum: da9ab4961dc61677c709da0c25ef01733042614453924d65636a7db37308fef8a24cd1e07172e61173d471ca175371295fbc984b0af5b2b4ff47cd57bd784c03
languageName: node
linkType: hard
"detect-newline@npm:^3.0.0":
version: 3.1.0
resolution: "detect-newline@npm:3.1.0"
@@ -3855,6 +3969,13 @@ __metadata:
languageName: node
linkType: hard
"ee-first@npm:1.1.1":
version: 1.1.1
resolution: "ee-first@npm:1.1.1"
checksum: 1b4cac778d64ce3b582a7e26b218afe07e207a0f9bfe13cc7395a6d307849cfe361e65033c3251e00c27dd060cab43014c2d6b2647676135e18b77d2d05b3f4f
languageName: node
linkType: hard
"electron-to-chromium@npm:^1.3.649":
version: 1.3.671
resolution: "electron-to-chromium@npm:1.3.671"
@@ -3890,6 +4011,20 @@ __metadata:
languageName: node
linkType: hard
"encodeurl@npm:~1.0.2":
version: 1.0.2
resolution: "encodeurl@npm:1.0.2"
checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c
languageName: node
linkType: hard
"encoding-negotiator@npm:^2.0.1":
version: 2.0.1
resolution: "encoding-negotiator@npm:2.0.1"
checksum: 3a9226dc47a327796c7c01d06eff0bf9a614ef9b8cbe3a7539d0c506ae92e603582c4fc5b5a61d093ff14a5d71b1b332d28a7dad73eda798a08ed73c08531c41
languageName: node
linkType: hard
"encoding@npm:^0.1.13":
version: 0.1.13
resolution: "encoding@npm:0.1.13"
@@ -4072,6 +4207,13 @@ __metadata:
languageName: node
linkType: hard
"escape-html@npm:~1.0.3":
version: 1.0.3
resolution: "escape-html@npm:1.0.3"
checksum: 6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24
languageName: node
linkType: hard
"escape-string-regexp@npm:^1.0.5":
version: 1.0.5
resolution: "escape-string-regexp@npm:1.0.5"
@@ -4331,6 +4473,13 @@ __metadata:
languageName: node
linkType: hard
"etag@npm:~1.8.1":
version: 1.8.1
resolution: "etag@npm:1.8.1"
checksum: 571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff
languageName: node
linkType: hard
"event-emitter@npm:^0.3.5":
version: 0.3.5
resolution: "event-emitter@npm:0.3.5"
@@ -4436,6 +4585,13 @@ __metadata:
languageName: node
linkType: hard
"fast-decode-uri-component@npm:^1.0.1":
version: 1.0.1
resolution: "fast-decode-uri-component@npm:1.0.1"
checksum: 427a48fe0907e76f0e9a2c228e253b4d8a8ab21d130ee9e4bb8339c5ba4086235cf9576831f7b20955a752eae4b525a177ff9d5825dd8d416e7726939194fbee
languageName: node
linkType: hard
"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
version: 3.1.3
resolution: "fast-deep-equal@npm:3.1.3"
@@ -4463,6 +4619,18 @@ __metadata:
languageName: node
linkType: hard
"fast-json-stringify@npm:^2.5.2":
version: 2.7.13
resolution: "fast-json-stringify@npm:2.7.13"
dependencies:
ajv: ^6.11.0
deepmerge: ^4.2.2
rfdc: ^1.2.0
string-similarity: ^4.0.1
checksum: f78ab25047c790de5b521c369e0b18c595055d48a106add36e9f86fe45be40226f168ff4708a226e187d0b46f1d6b32129842041728944bd9a03ca5efbbe4ccb
languageName: node
linkType: hard
"fast-levenshtein@npm:^2.0.6, fast-levenshtein@npm:~2.0.6":
version: 2.0.6
resolution: "fast-levenshtein@npm:2.0.6"
@@ -4470,6 +4638,20 @@ __metadata:
languageName: node
linkType: hard
"fast-redact@npm:^3.0.0":
version: 3.1.1
resolution: "fast-redact@npm:3.1.1"
checksum: e486cc9990b5c9724f39bf4e392c1b250c8fd5e8c0145be80c73de3461fc390babe7b48f35746b50bf3cbcd917e093b5685ae66295162c7d9b686a761d48e989
languageName: node
linkType: hard
"fast-safe-stringify@npm:^2.0.8":
version: 2.1.1
resolution: "fast-safe-stringify@npm:2.1.1"
checksum: a851cbddc451745662f8f00ddb622d6766f9bd97642dabfd9a405fb0d646d69fc0b9a1243cbf67f5f18a39f40f6fa821737651ff1bceeba06c9992ca2dc5bd3d
languageName: node
linkType: hard
"fastest-levenshtein@npm:^1.0.12":
version: 1.0.12
resolution: "fastest-levenshtein@npm:1.0.12"
@@ -4477,6 +4659,36 @@ __metadata:
languageName: node
linkType: hard
"fastify-plugin@npm:^3.0.0":
version: 3.0.1
resolution: "fastify-plugin@npm:3.0.1"
checksum: 131ba0a388f777829c3fb0fd5b75cf057688ce6d0ca354fb1ebf829767a8c853b0825762b9185b5200097454df0ede2f3095da2efe1aa1b3736d07f194e6d374
languageName: node
linkType: hard
"fastify@npm:^3.20.2":
version: 3.29.0
resolution: "fastify@npm:3.29.0"
dependencies:
"@fastify/ajv-compiler": ^1.0.0
"@fastify/error": ^2.0.0
abstract-logging: ^2.0.0
avvio: ^7.1.2
fast-json-stringify: ^2.5.2
find-my-way: ^4.5.0
flatstr: ^1.0.12
light-my-request: ^4.2.0
pino: ^6.13.0
process-warning: ^1.0.0
proxy-addr: ^2.0.7
rfdc: ^1.1.4
secure-json-parse: ^2.0.0
semver: ^7.3.2
tiny-lru: ^8.0.1
checksum: ed2964035e34843d08c09eee80f5f14bd8cc0ab9b46ac9d146c6821b586a359a93e1354fca4004ac14e37b267afe5bb1ba3ddb555ecf09b74d9b6bf2f9893ba1
languageName: node
linkType: hard
"fastq@npm:^1.6.0":
version: 1.10.1
resolution: "fastq@npm:1.10.1"
@@ -4486,6 +4698,15 @@ __metadata:
languageName: node
linkType: hard
"fastq@npm:^1.6.1":
version: 1.13.0
resolution: "fastq@npm:1.13.0"
dependencies:
reusify: ^1.0.4
checksum: 32cf15c29afe622af187d12fc9cd93e160a0cb7c31a3bb6ace86b7dea3b28e7b72acde89c882663f307b2184e14782c6c664fa315973c03626c7d4bff070bb0b
languageName: node
linkType: hard
"fb-watchman@npm:^2.0.0":
version: 2.0.1
resolution: "fb-watchman@npm:2.0.1"
@@ -4543,6 +4764,18 @@ __metadata:
languageName: node
linkType: hard
"find-my-way@npm:^4.5.0":
version: 4.5.1
resolution: "find-my-way@npm:4.5.1"
dependencies:
fast-decode-uri-component: ^1.0.1
fast-deep-equal: ^3.1.3
safe-regex2: ^2.0.0
semver-store: ^0.3.0
checksum: 85b8c07d34a36f0203438e0c0f0cdbfaf5e1c521ed2e56f9250bed846ceb0eea074127fad7f70137d61bed56387047f212969cc0ba5d818ed5e37b3e3606c43f
languageName: node
linkType: hard
"find-up@npm:^4.0.0, find-up@npm:^4.1.0":
version: 4.1.0
resolution: "find-up@npm:4.1.0"
@@ -4563,6 +4796,13 @@ __metadata:
languageName: node
linkType: hard
"flatstr@npm:^1.0.12":
version: 1.0.12
resolution: "flatstr@npm:1.0.12"
checksum: e1bb562c94b119e958bf37e55738b172b5f8aaae6532b9660ecd877779f8559dbbc89613ba6b29ccc13447e14c59277d41450f785cf75c30df9fce62f459e9a8
languageName: node
linkType: hard
"flatted@npm:^3.1.0":
version: 3.1.1
resolution: "flatted@npm:3.1.1"
@@ -4609,6 +4849,20 @@ __metadata:
languageName: node
linkType: hard
"forwarded@npm:0.2.0":
version: 0.2.0
resolution: "forwarded@npm:0.2.0"
checksum: fd27e2394d8887ebd16a66ffc889dc983fbbd797d5d3f01087c020283c0f019a7d05ee85669383d8e0d216b116d720fc0cef2f6e9b7eb9f4c90c6e0bc7fd28e6
languageName: node
linkType: hard
"fresh@npm:0.5.2":
version: 0.5.2
resolution: "fresh@npm:0.5.2"
checksum: 13ea8b08f91e669a64e3ba3a20eb79d7ca5379a81f1ff7f4310d54e2320645503cc0c78daedc93dfb6191287295f6479544a649c64d8e41a1c0fb0c221552346
languageName: node
linkType: hard
"fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0":
version: 2.1.0
resolution: "fs-minipass@npm:2.1.0"
@@ -5030,6 +5284,19 @@ __metadata:
languageName: node
linkType: hard
"http-errors@npm:1.8.1":
version: 1.8.1
resolution: "http-errors@npm:1.8.1"
dependencies:
depd: ~1.1.2
inherits: 2.0.4
setprototypeof: 1.2.0
statuses: ">= 1.5.0 < 2"
toidentifier: 1.0.1
checksum: d3c7e7e776fd51c0a812baff570bdf06fe49a5dc448b700ab6171b1250e4cf7db8b8f4c0b133e4bfe2451022a5790c1ca6c2cae4094dedd6ac8304a1267f91d2
languageName: node
linkType: hard
"http-proxy-agent@npm:^5.0.0":
version: 5.0.0
resolution: "http-proxy-agent@npm:5.0.0"
@@ -5167,14 +5434,14 @@ __metadata:
languageName: node
linkType: hard
"inferno-vnode-flags@npm:7.4.11, inferno-vnode-flags@npm:^7.4.11":
"inferno-vnode-flags@npm:7.4.11, inferno-vnode-flags@npm:^7.4.11, inferno-vnode-flags@npm:^7.4.8":
version: 7.4.11
resolution: "inferno-vnode-flags@npm:7.4.11"
checksum: 8a2f1d8d546b99c14c31a25a88ac45f076be9ac630202f898c49140aa420cf2c96d871fcc3f8e5813d5176d569a40c3fd1727198edf46306de3a989fe85176ab
languageName: node
linkType: hard
"inferno@npm:^7.4.11":
"inferno@npm:^7.4.11, inferno@npm:^7.4.8":
version: 7.4.11
resolution: "inferno@npm:7.4.11"
dependencies:
@@ -5195,7 +5462,7 @@ __metadata:
languageName: node
linkType: hard
"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:~2.0.1, inherits@npm:~2.0.3":
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:~2.0.1, inherits@npm:~2.0.3":
version: 2.0.4
resolution: "inherits@npm:2.0.4"
checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
@@ -5227,6 +5494,13 @@ __metadata:
languageName: node
linkType: hard
"ipaddr.js@npm:1.9.1":
version: 1.9.1
resolution: "ipaddr.js@npm:1.9.1"
checksum: f88d3825981486f5a1942414c8d77dd6674dd71c065adcfa46f578d677edcb99fda25af42675cb59db492fdf427b34a5abfcde3982da11a8fd83a500b41cfe77
languageName: node
linkType: hard
"is-arrayish@npm:^0.2.1":
version: 0.2.1
resolution: "is-arrayish@npm:0.2.1"
@@ -6319,6 +6593,18 @@ __metadata:
languageName: node
linkType: hard
"light-my-request@npm:^4.2.0":
version: 4.10.1
resolution: "light-my-request@npm:4.10.1"
dependencies:
ajv: ^8.1.0
cookie: ^0.5.0
process-warning: ^1.0.0
set-cookie-parser: ^2.4.1
checksum: 137856232489f0198f4da72fcc6c83db9ed8d653b8c00c30f9e518a58bd67259e429894657153ec667c5ce2064206ea8ea5b6be76a9ada9376a054f2de51748f
languageName: node
linkType: hard
"lines-and-columns@npm:^1.1.6":
version: 1.1.6
resolution: "lines-and-columns@npm:1.1.6"
@@ -6374,7 +6660,7 @@ __metadata:
languageName: node
linkType: hard
"lodash@npm:^4.17.10, lodash@npm:^4.17.19, lodash@npm:^4.17.20":
"lodash@npm:^4.17.10, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
@@ -6540,6 +6826,15 @@ __metadata:
languageName: node
linkType: hard
"mime@npm:1.6.0":
version: 1.6.0
resolution: "mime@npm:1.6.0"
bin:
mime: cli.js
checksum: fef25e39263e6d207580bdc629f8872a3f9772c923c7f8c7e793175cee22777bbe8bba95e5d509a40aaa292d8974514ce634ae35769faa45f22d17edda5e8557
languageName: node
linkType: hard
"mime@npm:^2.3.1":
version: 2.5.2
resolution: "mime@npm:2.5.2"
@@ -6689,6 +6984,13 @@ __metadata:
languageName: node
linkType: hard
"ms@npm:2.0.0":
version: 2.0.0
resolution: "ms@npm:2.0.0"
checksum: 0e6a22b8b746d2e0b65a430519934fefd41b6db0682e3477c10f60c76e947c4c0ad06f63ffdf1d78d335f83edee8c0aa928aa66a36c7cd95b69b26f468d527f4
languageName: node
linkType: hard
"ms@npm:2.1.2":
version: 2.1.2
resolution: "ms@npm:2.1.2"
@@ -6696,7 +6998,7 @@ __metadata:
languageName: node
linkType: hard
"ms@npm:^2.0.0":
"ms@npm:2.1.3, ms@npm:^2.0.0":
version: 2.1.3
resolution: "ms@npm:2.1.3"
checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d
@@ -6991,6 +7293,15 @@ __metadata:
languageName: node
linkType: hard
"on-finished@npm:~2.3.0":
version: 2.3.0
resolution: "on-finished@npm:2.3.0"
dependencies:
ee-first: 1.1.1
checksum: 1db595bd963b0124d6fa261d18320422407b8f01dc65863840f3ddaaf7bcad5b28ff6847286703ca53f4ec19595bd67a2f1253db79fc4094911ec6aa8df1671b
languageName: node
linkType: hard
"once@npm:^1.3.0":
version: 1.4.0
resolution: "once@npm:1.4.0"
@@ -7064,6 +7375,15 @@ __metadata:
languageName: node
linkType: hard
"p-limit@npm:^3.1.0":
version: 3.1.0
resolution: "p-limit@npm:3.1.0"
dependencies:
yocto-queue: ^0.1.0
checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360
languageName: node
linkType: hard
"p-locate@npm:^4.1.0":
version: 4.1.0
resolution: "p-locate@npm:4.1.0"
@@ -7224,6 +7544,30 @@ __metadata:
languageName: node
linkType: hard
"pino-std-serializers@npm:^3.1.0":
version: 3.2.0
resolution: "pino-std-serializers@npm:3.2.0"
checksum: 77e29675b116e42ae9fe6d4ef52ef3a082ffc54922b122d85935f93ddcc20277f0b0c873c5c6c5274a67b0409c672aaae3de6bcea10a2d84699718dda55ba95b
languageName: node
linkType: hard
"pino@npm:^6.13.0":
version: 6.14.0
resolution: "pino@npm:6.14.0"
dependencies:
fast-redact: ^3.0.0
fast-safe-stringify: ^2.0.8
flatstr: ^1.0.12
pino-std-serializers: ^3.1.0
process-warning: ^1.0.0
quick-format-unescaped: ^4.0.3
sonic-boom: ^1.0.2
bin:
pino: bin.js
checksum: eb13e12e3a3d682abe4a4da426455a9f4e041e55e4fa57d72d9677ee8d188a9c952f69347e728a3761c8262cdce76ef24bee29e1a53ab15aa9c5e851099163d0
languageName: node
linkType: hard
"pirates@npm:^4.0.4":
version: 4.0.5
resolution: "pirates@npm:4.0.5"
@@ -7240,6 +7584,13 @@ __metadata:
languageName: node
linkType: hard
"platform@npm:^1.3.6":
version: 1.3.6
resolution: "platform@npm:1.3.6"
checksum: 6f472a09c61d418c7e26c1c16d0bdc029549d512dbec6526216a1e59ec68100d07007d0097dcba69dddad883d6f2a83361b4bdfe0094a3d9a2af24158643d85e
languageName: node
linkType: hard
"postcss-modules-extract-imports@npm:^3.0.0":
version: 3.0.0
resolution: "postcss-modules-extract-imports@npm:3.0.0"
@@ -7365,6 +7716,13 @@ __metadata:
languageName: node
linkType: hard
"process-warning@npm:^1.0.0":
version: 1.0.0
resolution: "process-warning@npm:1.0.0"
checksum: c708a03241deec3cabaeee39c4f9ee8c4d71f1c5ef9b746c8252cdb952a6059068cfcdaf348399775244cbc441b6ae5e26a9c87ed371f88335d84f26d19180f9
languageName: node
linkType: hard
"promise-inflight@npm:^1.0.1":
version: 1.0.1
resolution: "promise-inflight@npm:1.0.1"
@@ -7403,6 +7761,16 @@ __metadata:
languageName: node
linkType: hard
"proxy-addr@npm:^2.0.7":
version: 2.0.7
resolution: "proxy-addr@npm:2.0.7"
dependencies:
forwarded: 0.2.0
ipaddr.js: 1.9.1
checksum: 29c6990ce9364648255454842f06f8c46fcd124d3e6d7c5066df44662de63cdc0bad032e9bf5a3d653ff72141cc7b6019873d685708ac8210c30458ad99f2b74
languageName: node
linkType: hard
"psl@npm:^1.1.28, psl@npm:^1.1.33":
version: 1.8.0
resolution: "psl@npm:1.8.0"
@@ -7424,6 +7792,13 @@ __metadata:
languageName: node
linkType: hard
"queue-microtask@npm:^1.1.2":
version: 1.2.3
resolution: "queue-microtask@npm:1.2.3"
checksum: b676f8c040cdc5b12723ad2f91414d267605b26419d5c821ff03befa817ddd10e238d22b25d604920340fd73efd8ba795465a0377c4adf45a4a41e4234e42dc4
languageName: node
linkType: hard
"queue-microtask@npm:^1.2.2":
version: 1.2.2
resolution: "queue-microtask@npm:1.2.2"
@@ -7431,6 +7806,13 @@ __metadata:
languageName: node
linkType: hard
"quick-format-unescaped@npm:^4.0.3":
version: 4.0.4
resolution: "quick-format-unescaped@npm:4.0.4"
checksum: 7bc32b99354a1aa46c089d2a82b63489961002bb1d654cee3e6d2d8778197b68c2d854fd23d8422436ee1fdfd0abaddc4d4da120afe700ade68bd357815b26fd
languageName: node
linkType: hard
"randombytes@npm:^2.1.0":
version: 2.1.0
resolution: "randombytes@npm:2.1.0"
@@ -7440,6 +7822,13 @@ __metadata:
languageName: node
linkType: hard
"range-parser@npm:~1.2.1":
version: 1.2.1
resolution: "range-parser@npm:1.2.1"
checksum: 0a268d4fea508661cf5743dfe3d5f47ce214fd6b7dec1de0da4d669dd4ef3d2144468ebe4179049eff253d9d27e719c88dae55be64f954e80135a0cada804ec9
languageName: node
linkType: hard
"react-is@npm:^16.13.1":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
@@ -7785,6 +8174,13 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"ret@npm:~0.2.0":
version: 0.2.2
resolution: "ret@npm:0.2.2"
checksum: 774964bb413a3525e687bca92d81c1cd75555ec33147c32ecca22f3d06409e35df87952cfe3d57afff7650a0f7e42139cf60cb44e94c29dde390243bc1941f16
languageName: node
linkType: hard
"retry@npm:^0.12.0":
version: 0.12.0
resolution: "retry@npm:0.12.0"
@@ -7799,6 +8195,13 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"rfdc@npm:^1.1.4, rfdc@npm:^1.2.0":
version: 1.3.0
resolution: "rfdc@npm:1.3.0"
checksum: fb2ba8512e43519983b4c61bd3fa77c0f410eff6bae68b08614437bc3f35f91362215f7b4a73cbda6f67330b5746ce07db5dd9850ad3edc91271ad6deea0df32
languageName: node
linkType: hard
"rimraf@npm:^3.0.0, rimraf@npm:^3.0.2":
version: 3.0.2
resolution: "rimraf@npm:3.0.2"
@@ -7819,7 +8222,7 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.2, safe-buffer@npm:~5.2.0":
"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.2, safe-buffer@npm:~5.2.0":
version: 5.2.1
resolution: "safe-buffer@npm:5.2.1"
checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491
@@ -7833,6 +8236,15 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"safe-regex2@npm:^2.0.0":
version: 2.0.0
resolution: "safe-regex2@npm:2.0.0"
dependencies:
ret: ~0.2.0
checksum: f5e182fca040dedd50ae052ea0eb035d9903b2db71243d5d8b43299735857288ef2ab52546a368d9c6fd1333b2a0d039297925e78ffc14845354f3f6158af7c2
languageName: node
linkType: hard
"safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
@@ -7939,6 +8351,20 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"secure-json-parse@npm:^2.0.0":
version: 2.4.0
resolution: "secure-json-parse@npm:2.4.0"
checksum: efaafcaa08a4646ca829b29168474f57fb289a0ca7a1d77b66b55a0292785bc6eb9143b21cfc50b37dd12a823c25b12aa1771f18314ed5a616a1f8f12a318533
languageName: node
linkType: hard
"semver-store@npm:^0.3.0":
version: 0.3.0
resolution: "semver-store@npm:0.3.0"
checksum: b38f747123e850191526a912657c653c7e5963d164a8daf99e52aa30bc8c5bdac176dc6dab714e17a1a8489ac138c18ff7161b1961f1882888bce637990442dd
languageName: node
linkType: hard
"semver@npm:7.0.0":
version: 7.0.0
resolution: "semver@npm:7.0.0"
@@ -7990,6 +8416,27 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"send@npm:^0.17.1":
version: 0.17.2
resolution: "send@npm:0.17.2"
dependencies:
debug: 2.6.9
depd: ~1.1.2
destroy: ~1.0.4
encodeurl: ~1.0.2
escape-html: ~1.0.3
etag: ~1.8.1
fresh: 0.5.2
http-errors: 1.8.1
mime: 1.6.0
ms: 2.1.3
on-finished: ~2.3.0
range-parser: ~1.2.1
statuses: ~1.5.0
checksum: c28f36deb4ccba9b8d6e6a1e472b8e7c40a1f51575bdf8f67303568cc9e71131faa3adc36fdb72611616ccad1584358bbe4c3ebf419e663ecc5de868ad3d3f03
languageName: node
linkType: hard
"sentence-case@npm:^3.0.4":
version: 3.0.4
resolution: "sentence-case@npm:3.0.4"
@@ -8017,6 +8464,20 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"set-cookie-parser@npm:^2.4.1":
version: 2.5.0
resolution: "set-cookie-parser@npm:2.5.0"
checksum: df277b2c49f05738997f78a9848b8a9954a77ff57989d32e373622921788cf6b154c30b7fab8d69bc8d1cf7687cb904efa642d5adee7a9ebae883c15cea3c145
languageName: node
linkType: hard
"setprototypeof@npm:1.2.0":
version: 1.2.0
resolution: "setprototypeof@npm:1.2.0"
checksum: be18cbbf70e7d8097c97f713a2e76edf84e87299b40d085c6bf8b65314e994cc15e2e317727342fa6996e38e1f52c59720b53fe621e2eb593a6847bf0356db89
languageName: node
linkType: hard
"shallow-clone@npm:^3.0.0":
version: 3.0.1
resolution: "shallow-clone@npm:3.0.1"
@@ -8137,6 +8598,16 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"sonic-boom@npm:^1.0.2":
version: 1.4.1
resolution: "sonic-boom@npm:1.4.1"
dependencies:
atomic-sleep: ^1.0.0
flatstr: ^1.0.12
checksum: 189fa8fe5c2dc05d3513fc1a4926a2f16f132fa6fa0b511745a436010cdcd9c1d3b3cb6a9d7c05bd32a965dc77673a5ac0eb0992e920bdedd16330d95323124f
languageName: node
linkType: hard
"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.2":
version: 1.0.2
resolution: "source-map-js@npm:1.0.2"
@@ -8249,6 +8720,13 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"statuses@npm:>= 1.5.0 < 2, statuses@npm:~1.5.0":
version: 1.5.0
resolution: "statuses@npm:1.5.0"
checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c
languageName: node
linkType: hard
"string-length@npm:^4.0.1":
version: 4.0.1
resolution: "string-length@npm:4.0.1"
@@ -8259,6 +8737,13 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"string-similarity@npm:^4.0.1":
version: 4.0.4
resolution: "string-similarity@npm:4.0.4"
checksum: 797b41b24e1eb6b3b0ab896950b58c295a19a82933479c75f7b5279ffb63e0b456a8c8d10329c02f607ca1a50370e961e83d552aa468ff3b0fa15809abc9eff7
languageName: node
linkType: hard
"string-width@npm:^1.0.1":
version: 1.0.2
resolution: "string-width@npm:1.0.2"
@@ -8656,6 +9141,21 @@ resolve@^2.0.0-next.3:
languageName: unknown
linkType: soft
"tgui-bench@workspace:packages/tgui-bench":
version: 0.0.0-use.local
resolution: "tgui-bench@workspace:packages/tgui-bench"
dependencies:
"@fastify/static": ^5.0.2
common: "workspace:*"
fastify: ^3.20.2
inferno: ^7.4.8
inferno-vnode-flags: ^7.4.8
lodash: ^4.17.21
platform: ^1.3.6
tgui: "workspace:*"
languageName: unknown
linkType: soft
"tgui-dev-server@workspace:*, tgui-dev-server@workspace:packages/tgui-dev-server":
version: 0.0.0-use.local
resolution: "tgui-dev-server@workspace:packages/tgui-dev-server"
@@ -8705,6 +9205,8 @@ resolve@^2.0.0-next.3:
"@types/jest": ^27.5.1
"@types/jsdom": ^16.2.14
"@types/node": ^17.0.35
"@types/webpack": ^5.28.0
"@types/webpack-env": ^1.17.0
"@typescript-eslint/parser": ^5.25.0
babel-jest: ^28.1.0
babel-loader: ^8.2.5
@@ -8769,6 +9271,13 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"tiny-lru@npm:^8.0.1":
version: 8.0.2
resolution: "tiny-lru@npm:8.0.2"
checksum: ec4d884914626760eef05cd57850f21a153adeeb7c4242eb8d44a031f1bd8489f18c1bf5d6f10f0a11c5dcfe03b302f26b00f2b879b38853599486bf0dca8c97
languageName: node
linkType: hard
"tmpl@npm:1.0.x":
version: 1.0.4
resolution: "tmpl@npm:1.0.4"
@@ -8792,6 +9301,13 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"toidentifier@npm:1.0.1":
version: 1.0.1
resolution: "toidentifier@npm:1.0.1"
checksum: 952c29e2a85d7123239b5cfdd889a0dde47ab0497f0913d70588f19c53f7e0b5327c95f4651e413c74b785147f9637b17410ac8c846d5d4a20a5a33eb6dc3a45
languageName: node
linkType: hard
"totalist@npm:^1.0.0":
version: 1.1.0
resolution: "totalist@npm:1.1.0"
@@ -9340,6 +9856,43 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard
"webpack@npm:^5":
version: 5.73.0
resolution: "webpack@npm:5.73.0"
dependencies:
"@types/eslint-scope": ^3.7.3
"@types/estree": ^0.0.51
"@webassemblyjs/ast": 1.11.1
"@webassemblyjs/wasm-edit": 1.11.1
"@webassemblyjs/wasm-parser": 1.11.1
acorn: ^8.4.1
acorn-import-assertions: ^1.7.6
browserslist: ^4.14.5
chrome-trace-event: ^1.0.2
enhanced-resolve: ^5.9.3
es-module-lexer: ^0.9.0
eslint-scope: 5.1.1
events: ^3.2.0
glob-to-regexp: ^0.4.1
graceful-fs: ^4.2.9
json-parse-even-better-errors: ^2.3.1
loader-runner: ^4.2.0
mime-types: ^2.1.27
neo-async: ^2.6.2
schema-utils: ^3.1.0
tapable: ^2.1.1
terser-webpack-plugin: ^5.1.3
watchpack: ^2.3.1
webpack-sources: ^3.2.3
peerDependenciesMeta:
webpack-cli:
optional: true
bin:
webpack: bin/webpack.js
checksum: aa434a241bad6176b68e1bf0feb1972da4dcbf27cb3d94ae24f6eb31acc37dceb9c4aae55e068edca75817bfe91f13cd20b023ac55d9b1b2f8b66a4037c9468f
languageName: node
linkType: hard
"webpack@npm:^5.72.1":
version: 5.72.1
resolution: "webpack@npm:5.72.1"
@@ -9594,3 +10147,10 @@ resolve@^2.0.0-next.3:
checksum: 00d58a2c052937fa044834313f07910fd0a115dec5ee35919e857eeee3736b21a4eafa8264535800ba8bac312991ce785ecb8a51f4d2cc8c4676d865af1cfbde
languageName: node
linkType: hard
"yocto-queue@npm:^0.1.0":
version: 0.1.0
resolution: "yocto-queue@npm:0.1.0"
checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700
languageName: node
linkType: hard