From d42ea5c672834474737556f9168c7fbb8de87690 Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sun, 27 Aug 2023 15:03:12 +0200 Subject: [PATCH 01/35] Delete `ObjectUtilities` --- src/utils/ObjectUtilities.ts | 32 --------------------------- tests/tmp/ObjectUtilities.test.ts | 36 ------------------------------- 2 files changed, 68 deletions(-) delete mode 100644 src/utils/ObjectUtilities.ts delete mode 100644 tests/tmp/ObjectUtilities.test.ts diff --git a/src/utils/ObjectUtilities.ts b/src/utils/ObjectUtilities.ts deleted file mode 100644 index 3ea4b84..0000000 --- a/src/utils/ObjectUtilities.ts +++ /dev/null @@ -1,32 +0,0 @@ -// export function extractSubtype(properties: Record) { -// return function (value: TActual) { -// let result = {} as T; -// for (const property of Object.keys(properties) as Array) { -// result[property] = value[property]; -// } - -// return result; -// } -// } -export function deepCopy(obj: object): object { - if (obj instanceof Date) { - return new Date(obj); - } - - if (obj instanceof Array) { - const arrayCopy: unknown[] = []; - for (let i = 0; i < obj.length; i++) { - arrayCopy[i] = typeof obj[i] === "object" ? deepCopy(obj[i]) : obj[i]; - } - return arrayCopy; - } - - const objectCopy: Record = {}; - for (const property in obj) { - const objectProperty = property as keyof typeof obj; - objectCopy[property] = typeof obj[objectProperty] === "object" - ? deepCopy(obj[objectProperty]) - : obj[objectProperty]; - } - return objectCopy; -} diff --git a/tests/tmp/ObjectUtilities.test.ts b/tests/tmp/ObjectUtilities.test.ts deleted file mode 100644 index eb6f906..0000000 --- a/tests/tmp/ObjectUtilities.test.ts +++ /dev/null @@ -1,36 +0,0 @@ - -import { describe, test, expect } from "@jest/globals"; -import { ObjectUtilities } from "@lc/utils"; - -describe("ObjectUtilities tests", () => { - test("ObjectUtilities.deepCopy", () => { - const basicObject = { - name: "Test object", - id: 2137 - }; - expect(ObjectUtilities.deepCopy(basicObject)).toStrictEqual(basicObject); - expect(ObjectUtilities.deepCopy(basicObject)).not.toBe(basicObject); - - const extendedObject = { - name: "Test object", - id: 2137, - data: { - timestamp: new Date(), - values: [ 1, 2, 3, 4, 5 ], - message: "Hi, I'm a test object!" - } - }; - expect(ObjectUtilities.deepCopy(extendedObject)).toStrictEqual(extendedObject); - expect(ObjectUtilities.deepCopy(extendedObject)).not.toBe(extendedObject); - // So shitty name. - // let m: Move = { - // origin: new BoardVector2d(1, 1), - // destination: new BoardVector2d(1, 1), - // moveType: MoveType.Capture, - // rotation: Rotation.Clockwise, - // promotedTo: null, - // piece: new King(new BoardVector2d(1, 1), 0, new Board(5, 5)), - // captured: null - // } - }); -}); From 3a5371d8e1908ea3770dddb00a5f2f6d4e7c19a7 Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sun, 27 Aug 2023 15:58:42 +0200 Subject: [PATCH 02/35] Move direction namespace to another module --- src/geometry/Direction.ts | 103 ---------------------- src/geometry/DirectionUtils.ts | 100 +++++++++++++++++++++ src/geometry/Vector2d.ts | 4 +- src/geometry/index.ts | 1 + src/pieces/Mirror.ts | 6 +- src/pieces/Pawn.ts | 10 +-- src/pieces/movements/LongRangeMovement.ts | 21 ----- 7 files changed, 111 insertions(+), 134 deletions(-) create mode 100644 src/geometry/DirectionUtils.ts delete mode 100644 src/pieces/movements/LongRangeMovement.ts diff --git a/src/geometry/Direction.ts b/src/geometry/Direction.ts index 43ec30a..1a80329 100644 --- a/src/geometry/Direction.ts +++ b/src/geometry/Direction.ts @@ -1,5 +1,3 @@ -import { BoardVector2d } from "@lc/geometry"; - export enum Direction { LeftRank = 0, UpperLeftDiagonal = 1, @@ -15,104 +13,3 @@ export const enum Rotation { Clockwise = 0, Anticlockwise = 1 } - -export namespace Direction { - - export function turnLeft(direction: Direction): Direction { - return (direction.valueOf() + 7) % 8 as Direction; - } - - export function turnRight(direction: Direction): Direction { - return (direction.valueOf() + 1) % 8 as Direction; - } - - export function turnDoubleLeft(direction: Direction): Direction { - return turnLeft(turnLeft(direction)) as Direction; - } - - export function turnDoubleRight(direction: Direction): Direction { - return turnRight(turnRight(direction)) as Direction; - } - - export function turnByStep(direction: Direction, turnNumber: number): Direction { - if (turnNumber >= 0) { - return (direction.valueOf() + turnNumber) % 8 as Direction; - } - else { - const turnsLeft = Math.abs(turnNumber) - direction.valueOf(); - if (turnsLeft < 0) { - return Math.abs(turnsLeft) as Direction; - } - return 7 - (turnsLeft % 8) as Direction; - } - } - - export function createFrom(coordinates: BoardVector2d | [number, number]): Direction { - if (coordinates instanceof BoardVector2d) { - coordinates = coordinates.toTuple(); - } - switch (coordinates.join(", ")) { - case "-1, 0": - return Direction.LeftRank; - case "1, 0": - return Direction.RightRank; - case "0, 1": - return Direction.UpperFile; - case "0, -1": - return Direction.BottomFile; - case "-1, 1": - return Direction.UpperLeftDiagonal; - case "1, 1": - return Direction.UpperRightDiagonal; - case "1, -1": - return Direction.BottomRightDiagonal; - case "-1, -1": - return Direction.BottomLeftDiagonal; - default: - throw new Error("Wrong value of vector") - } - } - - - export function toTuple(direction: Direction): [number, number] { - switch (direction) { - case Direction.LeftRank: - return [-1, 0] - case Direction.RightRank: - return [1, 0] - case Direction.UpperFile: - return [0, 1] - case Direction.BottomFile: - return [0, -1] - case Direction.UpperLeftDiagonal: - return [-1, 1] - case Direction.UpperRightDiagonal: - return [1, 1] - case Direction.BottomRightDiagonal: - return [1, -1] - case Direction.BottomLeftDiagonal: - return [-1, -1] - } - } - - export function toBoardVector2d(direction: Direction): BoardVector2d { - switch (direction) { - case Direction.LeftRank: - return new BoardVector2d(-1, 0); - case Direction.RightRank: - return new BoardVector2d(1, 0) - case Direction.UpperFile: - return new BoardVector2d(0, 1) - case Direction.BottomFile: - return new BoardVector2d(0, -1) - case Direction.UpperLeftDiagonal: - return new BoardVector2d(-1, 1) - case Direction.UpperRightDiagonal: - return new BoardVector2d(1, 1) - case Direction.BottomRightDiagonal: - return new BoardVector2d(1, -1) - case Direction.BottomLeftDiagonal: - return new BoardVector2d(-1, -1) - } - } -} \ No newline at end of file diff --git a/src/geometry/DirectionUtils.ts b/src/geometry/DirectionUtils.ts new file mode 100644 index 0000000..8028aac --- /dev/null +++ b/src/geometry/DirectionUtils.ts @@ -0,0 +1,100 @@ +import { BoardVector2d, Direction } from "@lc/geometry"; + +export function turnLeft(direction: Direction): Direction { + return (direction.valueOf() + 7) % 8 as Direction; +} + +export function turnRight(direction: Direction): Direction { + return (direction.valueOf() + 1) % 8 as Direction; +} + +export function turnDoubleLeft(direction: Direction): Direction { + return turnLeft(turnLeft(direction)) as Direction; +} + +export function turnDoubleRight(direction: Direction): Direction { + return turnRight(turnRight(direction)) as Direction; +} + +export function turnByStep(direction: Direction, turnNumber: number): Direction { + if (turnNumber >= 0) { + return (direction.valueOf() + turnNumber) % 8 as Direction; + } + else { + const turnsLeft = Math.abs(turnNumber) - direction.valueOf(); + if (turnsLeft < 0) { + return Math.abs(turnsLeft) as Direction; + } + return 7 - (turnsLeft % 8) as Direction; + } +} + +export function createFrom(coordinates: BoardVector2d | [number, number]): Direction { + if (coordinates instanceof BoardVector2d) { + coordinates = coordinates.toTuple(); + } + + switch (coordinates.join(", ")) { + case "-1, 0": + return Direction.LeftRank; + case "1, 0": + return Direction.RightRank; + case "0, 1": + return Direction.UpperFile; + case "0, -1": + return Direction.BottomFile; + case "-1, 1": + return Direction.UpperLeftDiagonal; + case "1, 1": + return Direction.UpperRightDiagonal; + case "1, -1": + return Direction.BottomRightDiagonal; + case "-1, -1": + return Direction.BottomLeftDiagonal; + default: + throw new Error("Wrong value of vector"); + } +} + + +export function toTuple(direction: Direction): [number, number] { + switch (direction) { + case Direction.LeftRank: + return [-1, 0]; + case Direction.RightRank: + return [1, 0]; + case Direction.UpperFile: + return [0, 1]; + case Direction.BottomFile: + return [0, -1]; + case Direction.UpperLeftDiagonal: + return [-1, 1]; + case Direction.UpperRightDiagonal: + return [1, 1]; + case Direction.BottomRightDiagonal: + return [1, -1]; + case Direction.BottomLeftDiagonal: + return [-1, -1]; + } +} + +export function toBoardVector2d(direction: Direction): BoardVector2d { + switch (direction) { + case Direction.LeftRank: + return new BoardVector2d(-1, 0); + case Direction.RightRank: + return new BoardVector2d(1, 0); + case Direction.UpperFile: + return new BoardVector2d(0, 1); + case Direction.BottomFile: + return new BoardVector2d(0, -1); + case Direction.UpperLeftDiagonal: + return new BoardVector2d(-1, 1); + case Direction.UpperRightDiagonal: + return new BoardVector2d(1, 1); + case Direction.BottomRightDiagonal: + return new BoardVector2d(1, -1); + case Direction.BottomLeftDiagonal: + return new BoardVector2d(-1, -1); + } +} diff --git a/src/geometry/Vector2d.ts b/src/geometry/Vector2d.ts index d82ed2e..ac9fb90 100644 --- a/src/geometry/Vector2d.ts +++ b/src/geometry/Vector2d.ts @@ -1,4 +1,4 @@ -import { Direction } from "@lc/geometry"; +import { Direction, DirectionUtils } from "@lc/geometry"; import { Integer } from "@lc/utils"; import { Board } from "@lc/core"; @@ -496,6 +496,6 @@ export class BoardVector2d extends IntVector2d { } public getSqares(direction: Direction, board: Board): BoardVector2d[] { - return this.getDirectedMoveFromTuple(Direction.toTuple(direction), board); + return this.getDirectedMoveFromTuple(DirectionUtils.toTuple(direction), board); } } diff --git a/src/geometry/index.ts b/src/geometry/index.ts index df2a8f8..31db3f8 100644 --- a/src/geometry/index.ts +++ b/src/geometry/index.ts @@ -5,3 +5,4 @@ export { BoardVector2d } from "./Vector2d.js"; export { Direction, Rotation } from "./Direction.js"; +export * as DirectionUtils from "./DirectionUtils.js"; diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index 254fe70..f9c354a 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -1,5 +1,5 @@ import { Move } from "@lc/core"; -import { Direction, Rotation } from "@lc/geometry"; +import { Direction, DirectionUtils, Rotation } from "@lc/geometry"; import { DirectedPiece, PieceType } from "@lc/pieces"; import { CloseRangeMovement } from "@lc/piece-movements"; import { ObjectUtilities } from "@lc/utils"; @@ -27,12 +27,12 @@ export class MirrorMovement extends CloseRangeMovement { public turnClockwise(): void { const piece: Mirror = this.piece as Mirror; - piece.direction = Direction.turnDoubleRight(piece.direction!); + piece.direction = DirectionUtils.turnDoubleRight(piece.direction!); } public turnAnticlockwise(): void { const piece: Mirror = this.piece as Mirror; - piece.direction = Direction.turnDoubleLeft(piece.direction!); + piece.direction = DirectionUtils.turnDoubleLeft(piece.direction!); } protected updateMovesWrapped(): void { diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index fa00803..abbc33f 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -1,5 +1,5 @@ import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; -import { BoardVector2d, Direction } from "@lc/geometry"; +import { BoardVector2d, Direction, DirectionUtils } from "@lc/geometry"; import { DirectedPiece, PieceType, Piece } from "@lc/pieces"; import { PieceMovement } from "@lc/piece-movements"; import { ObjectUtilities } from "@lc/utils"; @@ -48,7 +48,7 @@ export class PawnMovement extends PieceMovement { public isEnPassantLegal(destination: BoardVector2d): boolean { const piece: Pawn = this.piece as Pawn; const board: Board = this.board; - const otherPiece: Piece | null = board.getPiece(destination.sub(Direction.toBoardVector2d(piece.direction!))); + const otherPiece: Piece | null = board.getPiece(destination.sub(DirectionUtils.toBoardVector2d(piece.direction!))); return otherPiece !== null && !otherPiece.isSameColor(piece) && otherPiece.type === PieceType.PAWN @@ -60,10 +60,10 @@ export class PawnMovement extends PieceMovement { protected updateMovesWrapped(): void { const piece: Pawn = this.piece as Pawn; const board: Board = this.board; - const direction: BoardVector2d = Direction.toBoardVector2d(piece.direction as Direction); + const direction: BoardVector2d = DirectionUtils.toBoardVector2d(piece.direction as Direction); const captureDeltas: BoardVector2d[] = [ - Direction.toBoardVector2d(piece.direction!).reverseAxis().add(Direction.toBoardVector2d(piece.direction!)), - Direction.toBoardVector2d(piece.direction!).reverseAxis().opposite().add(Direction.toBoardVector2d(piece.direction!)) + DirectionUtils.toBoardVector2d(piece.direction!).reverseAxis().add(DirectionUtils.toBoardVector2d(piece.direction!)), + DirectionUtils.toBoardVector2d(piece.direction!).reverseAxis().opposite().add(DirectionUtils.toBoardVector2d(piece.direction!)) ] this.clearMoves(); diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts deleted file mode 100644 index 764dfa8..0000000 --- a/src/pieces/movements/LongRangeMovement.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NotImplementedError } from "@lc/utils"; -import { BoardVector2d } from "@lc/geometry"; -import { Piece } from "@lc/pieces"; - -export class LongRangeMovement /** extends PieceMovement */ { - constructor(ranged: Piece) { - - } - - public iterateSquares(origin: BoardVector2d) { - throw new NotImplementedError("iterateSquares() method is not implemented yet"); - } - - public getAllMoves(): BoardVector2d[][] { - throw new NotImplementedError("getAllMoves() method is not implemented yet"); - } - - public getLegalMoves(): BoardVector2d[][] { - throw new NotImplementedError("getLegalMoves() method is not implemented yet"); - } -} \ No newline at end of file From 47f6c8739d7574d882885627f799805b61a12e45 Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sun, 27 Aug 2023 19:50:53 +0200 Subject: [PATCH 03/35] Refactor direction --- src/geometry/Direction.ts | 5 ++- src/geometry/DirectionUtils.ts | 45 ++++++++++++----------- src/pieces/LongRangePiece.ts | 3 -- src/pieces/Mirror.ts | 4 +- src/pieces/movements/LongRangeMovement.ts | 25 +++++++++++++ 5 files changed, 53 insertions(+), 29 deletions(-) delete mode 100644 src/pieces/LongRangePiece.ts create mode 100644 src/pieces/movements/LongRangeMovement.ts diff --git a/src/geometry/Direction.ts b/src/geometry/Direction.ts index 1a80329..838f5fc 100644 --- a/src/geometry/Direction.ts +++ b/src/geometry/Direction.ts @@ -1,4 +1,4 @@ -export enum Direction { +export const enum Direction { LeftRank = 0, UpperLeftDiagonal = 1, UpperFile = 2, @@ -6,7 +6,8 @@ export enum Direction { RightRank = 4, BottomRightDiagonal = 5, BottomFile = 6, - BottomLeftDiagonal = 7 + BottomLeftDiagonal = 7, + Last } export const enum Rotation { diff --git a/src/geometry/DirectionUtils.ts b/src/geometry/DirectionUtils.ts index 8028aac..e2a7d68 100644 --- a/src/geometry/DirectionUtils.ts +++ b/src/geometry/DirectionUtils.ts @@ -1,35 +1,33 @@ import { BoardVector2d, Direction } from "@lc/geometry"; -export function turnLeft(direction: Direction): Direction { - return (direction.valueOf() + 7) % 8 as Direction; +export function rotate(direction: Direction, steps: number): Direction { + if (steps >= 0) { + return (direction + steps) % Direction.Last as Direction; + } + else { + const notNormalizedDirection = (direction + steps) % Direction.Last; + const normalizedDirection = Direction.Last - notNormalizedDirection; + return normalizedDirection; + } } -export function turnRight(direction: Direction): Direction { - return (direction.valueOf() + 1) % 8 as Direction; +export function rotateClockwise(direction: Direction): Direction { + return rotate(direction, 1); } -export function turnDoubleLeft(direction: Direction): Direction { - return turnLeft(turnLeft(direction)) as Direction; +export function rotateAnticlockwise(direction: Direction): Direction { + return rotate(direction, -1); } -export function turnDoubleRight(direction: Direction): Direction { - return turnRight(turnRight(direction)) as Direction; +export function rotateDoubleClockwise(direction: Direction): Direction { + return rotate(direction, 2); } -export function turnByStep(direction: Direction, turnNumber: number): Direction { - if (turnNumber >= 0) { - return (direction.valueOf() + turnNumber) % 8 as Direction; - } - else { - const turnsLeft = Math.abs(turnNumber) - direction.valueOf(); - if (turnsLeft < 0) { - return Math.abs(turnsLeft) as Direction; - } - return 7 - (turnsLeft % 8) as Direction; - } +export function rotateDoubleAnticlockwise(direction: Direction): Direction { + return rotate(direction, -2); } -export function createFrom(coordinates: BoardVector2d | [number, number]): Direction { +export function fromCoords(coordinates: BoardVector2d | [number, number]): Direction { if (coordinates instanceof BoardVector2d) { coordinates = coordinates.toTuple(); } @@ -52,11 +50,10 @@ export function createFrom(coordinates: BoardVector2d | [number, number]): Direc case "-1, -1": return Direction.BottomLeftDiagonal; default: - throw new Error("Wrong value of vector"); + throw new Error(`Invalid coordinates '${coordinates}'`); } } - export function toTuple(direction: Direction): [number, number] { switch (direction) { case Direction.LeftRank: @@ -75,6 +72,8 @@ export function toTuple(direction: Direction): [number, number] { return [1, -1]; case Direction.BottomLeftDiagonal: return [-1, -1]; + default: + throw new Error("Invalid direction"); } } @@ -96,5 +95,7 @@ export function toBoardVector2d(direction: Direction): BoardVector2d { return new BoardVector2d(1, -1); case Direction.BottomLeftDiagonal: return new BoardVector2d(-1, -1); + default: + throw new Error("Invalid direction"); } } diff --git a/src/pieces/LongRangePiece.ts b/src/pieces/LongRangePiece.ts deleted file mode 100644 index f4bbf1b..0000000 --- a/src/pieces/LongRangePiece.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Piece } from "@lc/pieces"; - -abstract class LongRangePiece extends Piece { } diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index f9c354a..f9c1b4e 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -27,12 +27,12 @@ export class MirrorMovement extends CloseRangeMovement { public turnClockwise(): void { const piece: Mirror = this.piece as Mirror; - piece.direction = DirectionUtils.turnDoubleRight(piece.direction!); + piece.direction = DirectionUtils.rotateDoubleClockwise(piece.direction!); } public turnAnticlockwise(): void { const piece: Mirror = this.piece as Mirror; - piece.direction = DirectionUtils.turnDoubleLeft(piece.direction!); + piece.direction = DirectionUtils.rotateDoubleAnticlockwise(piece.direction!); } protected updateMovesWrapped(): void { diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts new file mode 100644 index 0000000..4458bb0 --- /dev/null +++ b/src/pieces/movements/LongRangeMovement.ts @@ -0,0 +1,25 @@ +import { Move } from "@lc/core"; +import { NotImplementedError } from "@lc/utils"; +import { BoardVector2d, Direction } from "@lc/geometry"; +import { Piece } from "@lc/pieces"; + +export class LongRangeMovement /** extends PieceMovement */ { + // All moves but grouped by its direction. + public allLongRangeMoves: Partial>> = {}; + + constructor(ranged: Piece) { + + } + + public iterateSquares(origin: BoardVector2d) { + throw new NotImplementedError("iterateSquares() method is not implemented yet"); + } + + public getAllMoves(): BoardVector2d[][] { + throw new NotImplementedError("getAllMoves() method is not implemented yet"); + } + + public getLegalMoves(): BoardVector2d[][] { + throw new NotImplementedError("getLegalMoves() method is not implemented yet"); + } +} \ No newline at end of file From 90d731462b852e0287cede380635b43ac009aefc Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sun, 27 Aug 2023 21:23:27 +0200 Subject: [PATCH 04/35] Init `LongRangeMovement` module --- src/pieces/LongRangePiece.ts | 3 ++ src/pieces/movements/LongRangeMovement.ts | 37 +++++++++++++++++++---- src/utils/index.ts | 1 - 3 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 src/pieces/LongRangePiece.ts diff --git a/src/pieces/LongRangePiece.ts b/src/pieces/LongRangePiece.ts new file mode 100644 index 0000000..f4bbf1b --- /dev/null +++ b/src/pieces/LongRangePiece.ts @@ -0,0 +1,3 @@ +import { Piece } from "@lc/pieces"; + +abstract class LongRangePiece extends Piece { } diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index 4458bb0..ed8c33d 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -1,18 +1,43 @@ -import { Move } from "@lc/core"; +import { Board, Move } from "@lc/core"; import { NotImplementedError } from "@lc/utils"; -import { BoardVector2d, Direction } from "@lc/geometry"; +import { BoardVector2d, Direction, DirectionUtils } from "@lc/geometry"; import { Piece } from "@lc/pieces"; +import { PieceMovement } from "@lc/piece-movements"; -export class LongRangeMovement /** extends PieceMovement */ { +export class LongRangeMovement extends PieceMovement { // All moves but grouped by its direction. public allLongRangeMoves: Partial>> = {}; + public readonly directions: Direction[]; - constructor(ranged: Piece) { + constructor(piece: Piece, board: Board, directions: Direction[]) { + super(piece, board); + this.directions = directions; + } + + protected override updateMovesWrapped(): void { } - public iterateSquares(origin: BoardVector2d) { - throw new NotImplementedError("iterateSquares() method is not implemented yet"); + private getAllLongRangeMoves(): Partial>> { + const moves: Partial>> = {}; + for (const direction of this.directions) { + const moveCoordinates = this.getAllCoordinatesByDirection(direction); + } + return moves; + } + + private getAllCoordinatesByDirection(direction: Direction): BoardVector2d[] { + const x = this.piece.position.x, y = this.piece.position.y, + tuple = DirectionUtils.toTuple(direction), + step = { x: tuple[0], y: tuple[1] }; + const maxMoveLength = { + x: step.x > 0 ? this.board.width - x : x, + y: step.y > 0 ? this.board.height - y : y + }; + const moveLength = Math.min(maxMoveLength.x, maxMoveLength.y); + + return new Array(moveLength) + .map((_: unknown, i: number) => new BoardVector2d(x + i * step.x, y + i * step.y)); } public getAllMoves(): BoardVector2d[][] { diff --git a/src/utils/index.ts b/src/utils/index.ts index 0debbc5..2e3a321 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,3 +1,2 @@ export { NotImplementedError, IllegalMoveError } from "./error.js"; export * as Integer from "./int.js"; -export * as ObjectUtilities from "./ObjectUtilities.js" From 7a67f7b84dfaed52d891dc4c8a6d8fe1703dbc0b Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sun, 27 Aug 2023 21:29:58 +0200 Subject: [PATCH 05/35] Create `Queen` piece --- src/pieces/Queen.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/pieces/Queen.ts b/src/pieces/Queen.ts index e69de29..03849f4 100644 --- a/src/pieces/Queen.ts +++ b/src/pieces/Queen.ts @@ -0,0 +1,21 @@ +import { Direction } from "geometry/Direction.js"; +import { Piece, PieceType } from "./Piece.js"; +import { LongRangeMovement } from "./movements/LongRangeMovement.js"; + +export class Queen extends Piece { + public static DIRECTIONS = [ + Direction.UpperFile, + Direction.UpperRightDiagonal, + Direction.RightRank, + Direction.BottomRightDiagonal, + Direction.BottomFile, + Direction.BottomLeftDiagonal, + Direction.LeftRank, + Direction.UpperLeftDiagonal + ]; + + protected override initType(): void { + this._type = PieceType.QUEEN; + this._movement = new LongRangeMovement(this, this.board, Queen.DIRECTIONS); + } +} From 9f1f3e606cae7c467493f52c8ec7b8ba3e63af8d Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sun, 27 Aug 2023 21:39:43 +0200 Subject: [PATCH 06/35] Create player's color enum --- src/core/Player.ts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/core/Player.ts diff --git a/src/core/Player.ts b/src/core/Player.ts new file mode 100644 index 0000000..5b0b2d7 --- /dev/null +++ b/src/core/Player.ts @@ -0,0 +1,4 @@ +export const enum Player { + White = 0, + Black = 1 +} From 270d24a9d3197375c5cbe61f1318ebd1e8c627be Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sat, 2 Sep 2023 21:39:55 +0200 Subject: [PATCH 07/35] Refactor piece movements --- src/pieces/King.ts | 2 +- src/pieces/Knight.ts | 2 +- src/pieces/Mirror.ts | 2 +- src/pieces/Pawn.ts | 2 +- src/pieces/movements/CloseRangeMovement.ts | 4 +++- src/pieces/movements/LongRangeMovement.ts | 3 ++- src/pieces/movements/PieceMovement.ts | 9 +++------ 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pieces/King.ts b/src/pieces/King.ts index c67f334..8a5727c 100644 --- a/src/pieces/King.ts +++ b/src/pieces/King.ts @@ -75,7 +75,7 @@ export class KingMovement extends CloseRangeMovement { return false; } - protected updateMovesWrapped(): void { + protected updateMoves(): void { super.updateMoves(); if (this.isCastlingLegal(MoveType.KingSideCastling)) { const move: Partial = { diff --git a/src/pieces/Knight.ts b/src/pieces/Knight.ts index 6545691..58e5478 100644 --- a/src/pieces/Knight.ts +++ b/src/pieces/Knight.ts @@ -20,7 +20,7 @@ export class Knight extends Piece { export class KnightMovement extends PieceMovement { - protected updateMovesWrapped(): void { + protected updateMoves(): void { const piece: Knight = this.piece as Knight; const board: Board = this.board; const baseVectors: BoardVector2d[] = [new BoardVector2d(1, 2), new BoardVector2d(2, 1)]; diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index f9c1b4e..d6802d1 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -35,7 +35,7 @@ export class MirrorMovement extends CloseRangeMovement { piece.direction = DirectionUtils.rotateDoubleAnticlockwise(piece.direction!); } - protected updateMovesWrapped(): void { + protected updateMoves(): void { super.updateMoves(); this.capturableMoves.length = 0; const move: Partial = { diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index abbc33f..e03547f 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -57,7 +57,7 @@ export class PawnMovement extends PieceMovement { && piece.isOnEnPassantPosition(); } - protected updateMovesWrapped(): void { + protected updateMoves(): void { const piece: Pawn = this.piece as Pawn; const board: Board = this.board; const direction: BoardVector2d = DirectionUtils.toBoardVector2d(piece.direction as Direction); diff --git a/src/pieces/movements/CloseRangeMovement.ts b/src/pieces/movements/CloseRangeMovement.ts index 5e490ba..f1a8e04 100644 --- a/src/pieces/movements/CloseRangeMovement.ts +++ b/src/pieces/movements/CloseRangeMovement.ts @@ -7,7 +7,9 @@ import { ObjectUtilities } from "@lc/utils"; export class CloseRangeMovement extends PieceMovement { // This method sets all around moves as capturableMoves. - protected updateMovesWrapped(): void { + public override updateMoves(): void { + this.clearMoves(); + const piece: Piece = this.piece as Piece; const board: Board = this.board; diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index ed8c33d..9cf2e9c 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -14,7 +14,8 @@ export class LongRangeMovement extends PieceMovement { this.directions = directions; } - protected override updateMovesWrapped(): void { + protected override updateMoves(): void { + this.clearMoves(); } diff --git a/src/pieces/movements/PieceMovement.ts b/src/pieces/movements/PieceMovement.ts index 25dd81c..4141b81 100644 --- a/src/pieces/movements/PieceMovement.ts +++ b/src/pieces/movements/PieceMovement.ts @@ -5,6 +5,7 @@ import { Piece } from "@lc/pieces"; export abstract class PieceMovement { protected board: Board; protected piece: Piece; + protected lastUpdate: number; public readonly allMoves: Partial[]; public readonly legalMoves: Partial[]; public readonly capturableMoves: Partial[]; @@ -12,6 +13,7 @@ export abstract class PieceMovement { public constructor(piece: Piece, board: Board) { this.piece = piece; this.board = board; + this.lastUpdate = 0; this.allMoves = []; this.legalMoves = []; this.capturableMoves = []; @@ -23,10 +25,5 @@ export abstract class PieceMovement { this.capturableMoves.length = 0; } - protected abstract updateMovesWrapped(): void; - - public updateMoves(): void { - this.clearMoves(); - this.updateMovesWrapped(); - } + protected abstract updateMoves(): void; } From 1995e677927020eee8275643fbc119300dae2cd6 Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sat, 2 Sep 2023 21:49:26 +0200 Subject: [PATCH 08/35] Add `preUpdateMoves` method --- src/pieces/King.ts | 3 ++- src/pieces/Knight.ts | 4 +++- src/pieces/Mirror.ts | 4 +++- src/pieces/Pawn.ts | 13 ++++--------- src/pieces/movements/CloseRangeMovement.ts | 2 +- src/pieces/movements/LongRangeMovement.ts | 2 +- src/pieces/movements/PieceMovement.ts | 4 ++++ 7 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/pieces/King.ts b/src/pieces/King.ts index 8a5727c..b2d01c9 100644 --- a/src/pieces/King.ts +++ b/src/pieces/King.ts @@ -76,7 +76,8 @@ export class KingMovement extends CloseRangeMovement { } protected updateMoves(): void { - super.updateMoves(); + this.preUpdateMoves(); + if (this.isCastlingLegal(MoveType.KingSideCastling)) { const move: Partial = { destination: this.piece.position.add(new BoardVector2d(2, 0)) as BoardVector2d, diff --git a/src/pieces/Knight.ts b/src/pieces/Knight.ts index 58e5478..b900168 100644 --- a/src/pieces/Knight.ts +++ b/src/pieces/Knight.ts @@ -19,8 +19,9 @@ export class Knight extends Piece { export class KnightMovement extends PieceMovement { - protected updateMoves(): void { + this.preUpdateMoves(); + const piece: Knight = this.piece as Knight; const board: Board = this.board; const baseVectors: BoardVector2d[] = [new BoardVector2d(1, 2), new BoardVector2d(2, 1)]; @@ -58,4 +59,5 @@ export class KnightMovement extends PieceMovement { } } } + } \ No newline at end of file diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index d6802d1..73181bb 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -36,7 +36,8 @@ export class MirrorMovement extends CloseRangeMovement { } protected updateMoves(): void { - super.updateMoves(); + this.preUpdateMoves(); + this.capturableMoves.length = 0; const move: Partial = { rotation: Rotation.Anticlockwise @@ -48,4 +49,5 @@ export class MirrorMovement extends CloseRangeMovement { this.legalMoves.push(ObjectUtilities.deepCopy(move)); this.allMoves.push(move); } + } \ No newline at end of file diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index e03547f..9434e74 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -58,18 +58,17 @@ export class PawnMovement extends PieceMovement { } protected updateMoves(): void { + this.preUpdateMoves(); + const piece: Pawn = this.piece as Pawn; const board: Board = this.board; const direction: BoardVector2d = DirectionUtils.toBoardVector2d(piece.direction as Direction); const captureDeltas: BoardVector2d[] = [ DirectionUtils.toBoardVector2d(piece.direction!).reverseAxis().add(DirectionUtils.toBoardVector2d(piece.direction!)), DirectionUtils.toBoardVector2d(piece.direction!).reverseAxis().opposite().add(DirectionUtils.toBoardVector2d(piece.direction!)) - ] - - this.clearMoves(); + ]; // Advance 1 square - if (!board.isOutOfBounds(piece.position.add(direction))) { const move: Partial = { destination: piece.position.add(direction) as BoardVector2d, @@ -82,7 +81,6 @@ export class PawnMovement extends PieceMovement { } // Advance 2 squares - if (!board.isOutOfBounds(piece.position.add(direction.mul(2)))) { const move: Partial = { destination: piece.position.add(direction.mul(2)) as BoardVector2d, @@ -99,7 +97,6 @@ export class PawnMovement extends PieceMovement { } // Capture - for (const increment of captureDeltas) { const position: BoardVector2d = piece.position.add(increment); const move: Partial = { @@ -113,11 +110,9 @@ export class PawnMovement extends PieceMovement { this.capturableMoves.push(ObjectUtilities.deepCopy(move)); } } - } // En Passant - if (piece.isOnEnPassantPosition()) { for (const position of captureDeltas) { const tmpPosition: BoardVector2d = piece.position.add(position); @@ -134,7 +129,6 @@ export class PawnMovement extends PieceMovement { } // Promotion flag - const commonMoves: Partial[] = [...this.allMoves,...this.legalMoves,...this.capturableMoves]; for (const move of commonMoves) { if ((this.piece as Pawn).promotionPosition.y === move.destination!.y) { @@ -142,4 +136,5 @@ export class PawnMovement extends PieceMovement { } } } + } \ No newline at end of file diff --git a/src/pieces/movements/CloseRangeMovement.ts b/src/pieces/movements/CloseRangeMovement.ts index f1a8e04..ca56eb3 100644 --- a/src/pieces/movements/CloseRangeMovement.ts +++ b/src/pieces/movements/CloseRangeMovement.ts @@ -8,7 +8,7 @@ export class CloseRangeMovement extends PieceMovement { // This method sets all around moves as capturableMoves. public override updateMoves(): void { - this.clearMoves(); + this.preUpdateMoves(); const piece: Piece = this.piece as Piece; const board: Board = this.board; diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index 9cf2e9c..175b8ae 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -15,7 +15,7 @@ export class LongRangeMovement extends PieceMovement { } protected override updateMoves(): void { - this.clearMoves(); + this.preUpdateMoves(); } diff --git a/src/pieces/movements/PieceMovement.ts b/src/pieces/movements/PieceMovement.ts index 4141b81..6212d60 100644 --- a/src/pieces/movements/PieceMovement.ts +++ b/src/pieces/movements/PieceMovement.ts @@ -25,5 +25,9 @@ export abstract class PieceMovement { this.capturableMoves.length = 0; } + protected preUpdateMoves(): void { + this.clearMoves(); + } + protected abstract updateMoves(): void; } From ff26445a24c7238a662343f2a67d99c8d8ac5905 Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Sun, 3 Sep 2023 20:48:04 +0200 Subject: [PATCH 09/35] Refactor pawn --- src/core/Board.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/Board.ts b/src/core/Board.ts index f7b2de3..d90dbb2 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -152,7 +152,6 @@ export class Board { return false; } - public getPiecesOfType(playerId: number, pieceType: PieceType): Piece[] { return this.piecesOfType.get(pieceType)![playerId]; } @@ -180,5 +179,5 @@ export class Board { public isCheckAt(/* position: BoardVector2d, playerId: number */): boolean { return false; } - + } \ No newline at end of file From e46b667125ec05104cfbf740ab58e96de61039cf Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Mon, 4 Sep 2023 08:32:51 +0200 Subject: [PATCH 10/35] Modified `Board` and `Game` classes --- src/core/Board.ts | 66 ++++++++++++++++++++++++++++++++++++++++++--- src/game.ts | 7 ++--- src/pieces/Piece.ts | 1 - 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/core/Board.ts b/src/core/Board.ts index b3567d3..d130b60 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -6,8 +6,9 @@ import { Move, MoveType } from "@lc/core"; -import { BoardVector2d } from "@lc/geometry"; +import { BoardVector2d, Rotation } from "@lc/geometry"; import { Piece, PieceType } from "@lc/pieces"; +import { Lasgun } from "core/Lasgun.js"; import { MoveOrder } from "game.js"; import { IllegalMoveError } from "utils/error.js"; @@ -25,6 +26,7 @@ export class Board { private readonly piecesOfType: Map; private readonly kingsProtectors: [Piece[], Piece[]]; private readonly movesHistory: [Move[], Move[]]; + private readonly lasguns!: [Lasgun, Lasgun]; private _lastMove: Move | null; private promotionManager?: PromotionManager; @@ -159,12 +161,68 @@ export class Board { return this.piecesOfType.get(pieceType)![playerId]; } - public move(move: MoveOrder, playerId: number): void { - let moves: Partial[]; + private getSpecificMove(move: MoveOrder, playerId: number): Partial { let pieceToMove: Piece | null = this.getTile(move.origin).pieceOnTile; + + if (move.destination !== null && move.rotation !== null) { + throw new IllegalMoveError("Unable to roatate and move piece at once."); + } + + if (move.rotation === null && move.destination === null) { + throw new IllegalMoveError("Piece have to either rotate or move."); + } + + if (move.destination === null && move.rotation === null) { + throw new IllegalMoveError("Unable to roatate and move piece at once."); + } + + + if (move.fireLaser === true && !this.lasguns[playerId].isLoaded()) { + throw new IllegalMoveError("Lasgun is not loaded yet."); + } + if (pieceToMove === null) { - throw new IllegalMoveError("There is no piece") + throw new IllegalMoveError("There is no piece that has this position."); + } + + if (!pieceToMove.isSameColor(playerId)) { + throw new IllegalMoveError("Piece standing on origin position is enemy's piece."); + } + + if (pieceToMove.pieceType !== PieceType.KNIGHT && move.rangedCapture === true) { + throw new IllegalMoveError("Only knight can capture without moving."); } + + if (pieceToMove.pieceType !== PieceType.MIRROR && move.rotation !== null) { + throw new IllegalMoveError("Only mirror can rotate."); + } + + if (move.rotation !== null) { + for (let predictedMove of pieceToMove.movement.legalMoves) { + if (move.rotation === predictedMove.rotation) { + predictedMove.piece = pieceToMove; + return predictedMove; + } + } + } + + if (move.destination !== null) { + for (let predictedMove of pieceToMove.movement.legalMoves) { + if (move.destination === predictedMove.destination) { + predictedMove.piece = pieceToMove; + return predictedMove; + } + } + } + } + + public move(move: MoveOrder, playerId: number): void { + let moves: Partial[]; + let pieceToMove: Piece | null = this.getTile(move.origin).pieceOnTile; + this.validateBasicMoveProperties(move, playerId); + + + } public notifyPositionChange(origin: BoardVector2d, destination: BoardVector2d) { diff --git a/src/game.ts b/src/game.ts index cc1120a..8c54926 100644 --- a/src/game.ts +++ b/src/game.ts @@ -6,13 +6,10 @@ export interface MoveOrder { origin: BoardVector2d, destination: BoardVector2d | null, fireLaser: boolean, - rotation: Rotation | null + rotation: Rotation | null, + rangedCapture: boolean, } -// export interface AdditonalMoveOrderData { -// playerId: number, - -// } export class Game { diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index 5bf4633..0f6c70d 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -11,7 +11,6 @@ export enum PieceType { ROOK = "R", KNIGHT = "N", MIRROR = "M", - LASGUN = "L" } export interface PieceOptions { From 93ee1f107e34d9a3a7df220788099dc30487eb6d Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Tue, 5 Sep 2023 20:55:31 +0200 Subject: [PATCH 11/35] Finished basic board logic --- src/core/Board.ts | 91 ++++++++++++++++------ src/core/Tile.ts | 7 ++ src/core/index.ts | 1 + src/core/move.ts | 11 ++- src/game.ts | 13 +++- src/pieces/Knight.ts | 16 ++-- src/pieces/Mirror.ts | 38 ++++++--- src/pieces/Pawn.ts | 2 +- src/pieces/Piece.ts | 10 +-- src/pieces/movements/CloseRangeMovement.ts | 2 +- src/utils/index.ts | 2 +- 11 files changed, 138 insertions(+), 55 deletions(-) diff --git a/src/core/Board.ts b/src/core/Board.ts index c09bfaf..96c7109 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -3,17 +3,13 @@ import { PromotionManager, Tile, Move, - MoveOrder + MoveOrder, + MoveType } from "@lc/core"; -import { BoardVector2d, Rotation } from "@lc/geometry"; -import { Piece, PieceType } from "@lc/pieces"; -<<<<<<< HEAD -import { Lasgun } from "core/Lasgun.js"; -import { MoveOrder } from "game.js"; -import { IllegalMoveError } from "utils/error.js"; -======= +import { BoardVector2d, Direction, Rotation, Symmetry } from "@lc/geometry"; +import { Pawn, Piece, PieceType } from "@lc/pieces"; import { IllegalMoveError } from "@lc/utils"; ->>>>>>> ce3418d779863c4f753b114c41dc43e9e0d8da6a +import { Lasgun } from "@lc/core"; export const enum CaptureOptions { @@ -60,6 +56,12 @@ export class Board { // this.checkManager } + public updateAllTiles() { + for (let tile of this.tiles) { + tile[1].clearAllPredictions(); + } + } + public getPiecesOfPlayer(playerId: number): Piece[] { let playerPieces: Piece[] = []; for (const type in PieceType) { @@ -166,6 +168,10 @@ export class Board { private getSpecificMove(move: MoveOrder, playerId: number): Partial { let pieceToMove: Piece | null = this.getTile(move.origin).pieceOnTile; + + if (pieceToMove === null) { + throw new IllegalMoveError("There is no piece on origin postion."); + } if (move.destination !== null && move.rotation !== null) { throw new IllegalMoveError("Unable to roatate and move piece at once."); @@ -175,10 +181,13 @@ export class Board { throw new IllegalMoveError("Piece have to either rotate or move."); } - if (move.destination === null && move.rotation === null) { + if (move.destination !== null && move.rotation !== null) { throw new IllegalMoveError("Unable to roatate and move piece at once."); } + if (move.rangedCapture === true && move.rotation !== null) { + throw new IllegalMoveError("Piece cannot rotate and range capture a piece in one move."); + } if (move.fireLaser === true && !this.lasguns[playerId].isLoaded()) { throw new IllegalMoveError("Lasgun is not loaded yet."); @@ -191,19 +200,25 @@ export class Board { if (!pieceToMove.isSameColor(playerId)) { throw new IllegalMoveError("Piece standing on origin position is enemy's piece."); } - - if (pieceToMove.pieceType !== PieceType.KNIGHT && move.rangedCapture === true) { + if (pieceToMove.type !== PieceType.KNIGHT && move.rangedCapture === true) { throw new IllegalMoveError("Only knight can capture without moving."); } - if (pieceToMove.pieceType !== PieceType.MIRROR && move.rotation !== null) { + if (pieceToMove.type !== PieceType.MIRROR && move.rotation !== null) { throw new IllegalMoveError("Only mirror can rotate."); } + + if (move.rangedCapture === true) { + for (let predictedMove of pieceToMove.movement.legalMoves) { + if ((predictedMove.moveType! & MoveType.RangedCapture) === MoveType.RangedCapture && move.destination === predictedMove.destination) { + return predictedMove; + } + } + } if (move.rotation !== null) { for (let predictedMove of pieceToMove.movement.legalMoves) { if (move.rotation === predictedMove.rotation) { - predictedMove.piece = pieceToMove; return predictedMove; } } @@ -212,30 +227,58 @@ export class Board { if (move.destination !== null) { for (let predictedMove of pieceToMove.movement.legalMoves) { if (move.destination === predictedMove.destination) { - predictedMove.piece = pieceToMove; return predictedMove; } } } - } - public move(move: MoveOrder, playerId: number): void { - let moves: Partial[]; - let pieceToMove: Piece | null = this.getTile(move.origin).pieceOnTile; - this.validateBasicMoveProperties(move, playerId); - + throw new IllegalMoveError("Unable to perform such move."); + } + private buildMove(piece: Piece, pieceMove: Partial, moveOrder: MoveOrder): Move { + const ultimateMove: Move = { + destination: pieceMove.destination ?? null, + moveType: pieceMove.moveType!, + rotation: pieceMove.rotation ?? null, + origin: piece.position, + piece: piece, + promotedTo: null, + captured: null + } - } + if ((MoveType.EnPassant & ultimateMove.moveType) === MoveType.EnPassant) { + const directionVector: BoardVector2d = Direction.toBoardVector2d((piece as Pawn).direction!).opposite(); + const enemyPositon: BoardVector2d = ultimateMove.destination!.add(directionVector); + const enemyPiece: Piece = this.getPiece(enemyPositon)!; + ultimateMove.captured = enemyPiece; + } - public notifyPositionChange(/* origin: BoardVector2d, destination: BoardVector2d */) { + else if ((MoveType.Capture & ultimateMove.moveType) === MoveType.Capture) { + const enemyPiece: Piece = this.getPiece(ultimateMove.destination!)!; + ultimateMove.captured = enemyPiece; + } + + else if ((MoveType.RangedCapture & ultimateMove.moveType) === MoveType.RangedCapture) { + const enemyPiece: Piece = this.getPiece(ultimateMove.destination!)!; + ultimateMove.captured = enemyPiece; + } + if (moveOrder.fireLaser === true) { + ultimateMove.moveType |= MoveType.LaserFired + } + return ultimateMove; } - public notifyRangedCapture(/* origin: BoardVector2d, destination: BoardVector2d */) { + public move(move: MoveOrder, playerId: number): void { + const moveFromPiece: Partial = this.getSpecificMove(move, playerId); + const pieceToMove: Piece = this.getTile(move.origin).pieceOnTile!; + const moveToAnalyze: Move = this.buildMove(pieceToMove, moveFromPiece, move); + + pieceToMove.move(moveToAnalyze); } + public get lastMove(): Move | null { return this._lastMove; } diff --git a/src/core/Tile.ts b/src/core/Tile.ts index da7db38..8291a7f 100644 --- a/src/core/Tile.ts +++ b/src/core/Tile.ts @@ -35,6 +35,13 @@ export class Tile { return this._coordinates; } + public clearAllPredictions(): void { + for(let sets of this.setHashMap) { + sets[1][0].clear(); + sets[1][1].clear(); + } + } + public addPieceMovesToTile(piece: Piece, movePredictionsType: MovesPredictionsType): void { for (const item in MovesPredictionsType){ const movesEnumValue: MovesPredictionsType = MovesPredictionsType[item as keyof typeof MovesPredictionsType] diff --git a/src/core/index.ts b/src/core/index.ts index 245e3f8..e680acf 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -4,3 +4,4 @@ export { CheckManager } from "./CheckManager.js"; export { PromotionManager } from "./PromotionManager.js"; export { MoveType, Move, MoveOrder } from "./move.js"; export { Tile, MovesPredictionsType } from "./Tile.js"; +export { Lasgun } from "./Lasgun.js" diff --git a/src/core/move.ts b/src/core/move.ts index a4b716a..8772feb 100644 --- a/src/core/move.ts +++ b/src/core/move.ts @@ -10,6 +10,7 @@ export const enum MoveType { QueenSideCastling = 1 << 5, Rotation = 1 << 6, Promotion = 1 << 7, + Check = 1 << 8, Checkmate = 1 << 9, Stalemate = 1 << 10, @@ -20,10 +21,11 @@ export const enum MoveType { } export interface Move { - origin: BoardVector2d, - destination: BoardVector2d, + destination: BoardVector2d | null, moveType: MoveType, - rotation: Rotation | null + rotation: Rotation | null, + + origin: BoardVector2d, promotedTo: PieceType | null piece: Piece, captured: Piece | null, @@ -33,5 +35,6 @@ export interface MoveOrder { origin: BoardVector2d, destination: BoardVector2d | null, fireLaser: boolean, - rotation: Rotation | null + rotation: Rotation | null, + rangedCapture: boolean } diff --git a/src/game.ts b/src/game.ts index baf3db3..deb7050 100644 --- a/src/game.ts +++ b/src/game.ts @@ -1,4 +1,4 @@ -import { Board } from "@lc/core"; +import { Board, MoveOrder } from "@lc/core"; export class Game { private _currentPlayer: number; @@ -11,6 +11,13 @@ export class Game { public set board(board: Board){ this._board = board; } + + public get board(): Board{ + if (this._board === undefined) { + throw new Error("Board is undefined."); + } + return this._board; + } public get currentPlayer(): number { return this._currentPlayer; @@ -20,8 +27,8 @@ export class Game { return (playerId + 1) % 2; } - public move(/* move: MoveOrder */): void { - // this._board!.move(move, this._currentPlayer); + public move(move: MoveOrder): void { + this.board.move(move, this._currentPlayer); this._currentPlayer = Game.getEnemyId(this._currentPlayer); } diff --git a/src/pieces/Knight.ts b/src/pieces/Knight.ts index 6545691..03e5ae4 100644 --- a/src/pieces/Knight.ts +++ b/src/pieces/Knight.ts @@ -10,10 +10,14 @@ export class Knight extends Piece { this._movement = new KnightMovement(this, this.board); } - public rangedCapture(destination: BoardVector2d) { - this.position = destination; - this.moveCounter += 1; - // this.board.notifyRangedCapture(this.position, destination); + + public override move(move: Move): void { + if ((move.moveType & MoveType.RangedCapture) === MoveType.RangedCapture) { + this.moveCounter++; + } + else { + super.move(move); + } } } @@ -45,7 +49,7 @@ export class KnightMovement extends PieceMovement { this.legalMoves.push(move); if (board.canMoveTo(position, piece, CaptureOptions.RequiredCapture)) { move = ObjectUtilities.deepCopy(move); - move.moveType! &= MoveType.Capture + move.moveType! |= MoveType.Capture this.capturableMoves.push(move); move = { @@ -58,4 +62,6 @@ export class KnightMovement extends PieceMovement { } } } + + } \ No newline at end of file diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index 254fe70..7d3f5d7 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -1,10 +1,9 @@ -import { Move } from "@lc/core"; +import { Move, MoveType } from "@lc/core"; import { Direction, Rotation } from "@lc/geometry"; import { DirectedPiece, PieceType } from "@lc/pieces"; import { CloseRangeMovement } from "@lc/piece-movements"; import { ObjectUtilities } from "@lc/utils"; - export class Mirror extends DirectedPiece { protected override initType(): void { this._type = PieceType.MIRROR; @@ -21,19 +20,38 @@ export class Mirror extends DirectedPiece { public get direction(): Direction | undefined { return this._direction; } -} + + private turnClockwise(): void { + this.direction = Direction.turnDoubleRight(this.direction!); + } -export class MirrorMovement extends CloseRangeMovement { + private turnAnticlockwise(): void { + this.direction = Direction.turnDoubleLeft(this.direction!); + } - public turnClockwise(): void { - const piece: Mirror = this.piece as Mirror; - piece.direction = Direction.turnDoubleRight(piece.direction!); + private turn(rotation: Rotation): void { + switch(rotation) { + case Rotation.Anticlockwise: + this.turnAnticlockwise(); + break; + case Rotation.Anticlockwise: + this.turnClockwise(); + break; + } } - public turnAnticlockwise(): void { - const piece: Mirror = this.piece as Mirror; - piece.direction = Direction.turnDoubleLeft(piece.direction!); + public override move(move: Move): void { + if ((move.moveType & MoveType.Rotation) === MoveType.Rotation) { + this.moveCounter++; + this.turn(move.rotation!); + } + else { + super.move(move); + } } +} + +export class MirrorMovement extends CloseRangeMovement { protected updateMovesWrapped(): void { super.updateMoves(); diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index fa00803..1f7629b 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -138,7 +138,7 @@ export class PawnMovement extends PieceMovement { const commonMoves: Partial[] = [...this.allMoves,...this.legalMoves,...this.capturableMoves]; for (const move of commonMoves) { if ((this.piece as Pawn).promotionPosition.y === move.destination!.y) { - move.moveType! &= MoveType.Promotion; + move.moveType! |= MoveType.Promotion; } } } diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index 705c450..e52e3b3 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -1,4 +1,4 @@ -import { Board } from "@lc/core"; +import { Board, Move } from "@lc/core"; import { BoardVector2d } from "@lc/geometry"; import { PieceMovement } from "@lc/piece-movements"; @@ -84,10 +84,8 @@ export abstract class Piece { return this.playerId === other; } - public move(destination: BoardVector2d) { - // const origin: BoardVector2d = this.position.copy(); - this.position = destination; - this.moveCounter += 1; - // this.board.notifyPositionChange(origin, destination); + public move(move: Move): void { + this.position = move.destination!.copy(); + this.moveCounter++; } } diff --git a/src/pieces/movements/CloseRangeMovement.ts b/src/pieces/movements/CloseRangeMovement.ts index 5e490ba..9a096f1 100644 --- a/src/pieces/movements/CloseRangeMovement.ts +++ b/src/pieces/movements/CloseRangeMovement.ts @@ -28,7 +28,7 @@ export class CloseRangeMovement extends PieceMovement { move = ObjectUtilities.deepCopy(move); this.legalMoves.push(move); if (board.canMoveTo(newVector, piece, CaptureOptions.RequiredCapture)) { - move.moveType! &= MoveType.Capture; + move.moveType! |= MoveType.Capture; move = ObjectUtilities.deepCopy(move); this.capturableMoves.push(move); } diff --git a/src/utils/index.ts b/src/utils/index.ts index 0debbc5..60d7173 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,3 +1,3 @@ export { NotImplementedError, IllegalMoveError } from "./error.js"; export * as Integer from "./int.js"; -export * as ObjectUtilities from "./ObjectUtilities.js" +export * as ObjectUtilities from "./ObjectUtilities.js"; From f9fdd6cdf049cfcd4155907586d5f7915d901fb3 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Wed, 6 Sep 2023 18:12:53 +0200 Subject: [PATCH 12/35] Modified `PieceMovement` class --- src/core/Tile.ts | 50 ++++++---------------- src/pieces/King.ts | 26 ++++++----- src/pieces/Mirror.ts | 10 +++-- src/pieces/movements/CloseRangeMovement.ts | 31 +++++++------- src/pieces/movements/PieceMovement.ts | 18 +++----- src/utils/ObjectUtilities.ts | 32 -------------- src/utils/index.ts | 2 +- src/utils/syntax.ts | 3 ++ 8 files changed, 59 insertions(+), 113 deletions(-) delete mode 100644 src/utils/ObjectUtilities.ts create mode 100644 src/utils/syntax.ts diff --git a/src/core/Tile.ts b/src/core/Tile.ts index 8291a7f..83188c9 100644 --- a/src/core/Tile.ts +++ b/src/core/Tile.ts @@ -1,33 +1,23 @@ import { BoardVector2d } from "@lc/geometry"; import { Piece } from "@lc/pieces"; +import { Syntax } from "@lc/utils"; -export enum MovesPredictionsType { - All = 1 << 0, +export const enum MovesPredictionsType { Legal = 1 << 1, - Capturable = 1 << 2 + Illegal = 1 << 2 } export class Tile { private _coordinates: BoardVector2d; - private inMovesAllOf: Set[]; private inMovesLegalOf: Set[]; - private inMovesCapturableOf: Set[]; - private setHashMap: Map[]>; + private inMovesIllegalOf: Set[]; public pieceOnTile: Piece | null; public constructor(coordinates: BoardVector2d) { this._coordinates = coordinates; - this.inMovesAllOf = [new Set(), new Set()]; this.inMovesLegalOf = [new Set(), new Set()]; - this.inMovesCapturableOf = [new Set(), new Set()]; - this.setHashMap = new Map[]>( - [ - [MovesPredictionsType.All, this.inMovesAllOf], - [MovesPredictionsType.Legal, this.inMovesLegalOf], - [MovesPredictionsType.Capturable, this.inMovesCapturableOf], - ] - ) + this.inMovesIllegalOf = [new Set(), new Set()]; this.pieceOnTile = null; } @@ -36,43 +26,27 @@ export class Tile { } public clearAllPredictions(): void { - for(let sets of this.setHashMap) { - sets[1][0].clear(); - sets[1][1].clear(); + for (let i=0;i<1;i++) { + this.inMovesIllegalOf[i].clear(); + this.inMovesLegalOf[i].clear(); } } public addPieceMovesToTile(piece: Piece, movePredictionsType: MovesPredictionsType): void { - for (const item in MovesPredictionsType){ - const movesEnumValue: MovesPredictionsType = MovesPredictionsType[item as keyof typeof MovesPredictionsType] - if ((movePredictionsType & movesEnumValue) === movesEnumValue) { - this.setHashMap.get(movesEnumValue)![piece.playerId].add(piece); - } + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Illegal)) { + } } public removePieceMovesFromTile(piece: Piece, movePredictionsType: MovesPredictionsType): void { - for (const item in MovesPredictionsType){ - const movesEnumValue: MovesPredictionsType = MovesPredictionsType[item as keyof typeof MovesPredictionsType] - if ((movePredictionsType & movesEnumValue) === movesEnumValue) { - this.setHashMap.get(movesEnumValue)![piece.playerId].delete(piece); - } - } - this.checkIfPieceMovesInTile(piece, MovesPredictionsType.All | MovesPredictionsType.Capturable) + } public checkIfPieceMovesInTile(piece: Piece, movePredictionsType: MovesPredictionsType): boolean { - for (const item in MovesPredictionsType){ - const movesEnumValue: MovesPredictionsType = MovesPredictionsType[item as keyof typeof MovesPredictionsType] - if ((movePredictionsType & movesEnumValue) === movesEnumValue) { - return this.setHashMap.get(movesEnumValue)![piece.playerId].has(piece); - } - } - return false; + } public isPieceMovesEmpty(playerId: number, movePredictionsType: MovesPredictionsType): boolean{ - return this.setHashMap.get(movePredictionsType)![playerId].size === 0; } public getPieceMovesOfTile(playerId: number, movePredictionsType: MovesPredictionsType) { diff --git a/src/pieces/King.ts b/src/pieces/King.ts index c67f334..d19cfa9 100644 --- a/src/pieces/King.ts +++ b/src/pieces/King.ts @@ -2,7 +2,6 @@ import { MoveType, CaptureOptions, Move } from "@lc/core"; import { BoardVector2d } from "@lc/geometry"; import { Piece, PieceType } from "@lc/pieces"; import { CloseRangeMovement } from "@lc/piece-movements"; -import { ObjectUtilities } from "@lc/utils"; @@ -75,21 +74,26 @@ export class KingMovement extends CloseRangeMovement { return false; } - protected updateMovesWrapped(): void { + protected updateMoves(): void { super.updateMoves(); + let move: Partial = { + destination: this.piece.position.add(new BoardVector2d(2, 0)) as BoardVector2d, + moveType: MoveType.Move | MoveType.KingSideCastling + } if (this.isCastlingLegal(MoveType.KingSideCastling)) { - const move: Partial = { - destination: this.piece.position.add(new BoardVector2d(2, 0)) as BoardVector2d, - moveType: MoveType.Move & MoveType.KingSideCastling - } this.legalMoves.push(move) - this.allMoves.push(ObjectUtilities.deepCopy(move)); + } + else { + this.illegalMoves.push(move); + return + } + + move = { + destination: this.piece.position.add(new BoardVector2d(-2, 0)) as BoardVector2d, + moveType: MoveType.Move & MoveType.QueenSideCastling; } else if (this.isCastlingLegal(MoveType.QueenSideCastling)) { - const move: Partial = { - destination: this.piece.position.add(new BoardVector2d(-2, 0)) as BoardVector2d, - moveType: MoveType.Move & MoveType.KingSideCastling - } + const this.legalMoves.push(move) this.allMoves.push(ObjectUtilities.deepCopy(move)); } diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index 7d3f5d7..0a32087 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -1,8 +1,7 @@ import { Move, MoveType } from "@lc/core"; -import { Direction, Rotation } from "@lc/geometry"; +import { Direction, DirectionUtils, Rotation } from "@lc/geometry"; import { DirectedPiece, PieceType } from "@lc/pieces"; import { CloseRangeMovement } from "@lc/piece-movements"; -import { ObjectUtilities } from "@lc/utils"; export class Mirror extends DirectedPiece { protected override initType(): void { @@ -49,12 +48,14 @@ export class Mirror extends DirectedPiece { super.move(move); } } + } export class MirrorMovement extends CloseRangeMovement { - protected updateMovesWrapped(): void { - super.updateMoves(); + protected updateMoves(): void { + this.preUpdateMoves(); + this.capturableMoves.length = 0; const move: Partial = { rotation: Rotation.Anticlockwise @@ -66,4 +67,5 @@ export class MirrorMovement extends CloseRangeMovement { this.legalMoves.push(ObjectUtilities.deepCopy(move)); this.allMoves.push(move); } + } \ No newline at end of file diff --git a/src/pieces/movements/CloseRangeMovement.ts b/src/pieces/movements/CloseRangeMovement.ts index 9a096f1..b787fa3 100644 --- a/src/pieces/movements/CloseRangeMovement.ts +++ b/src/pieces/movements/CloseRangeMovement.ts @@ -2,14 +2,13 @@ import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; import { BoardVector2d } from "@lc/geometry"; import { Piece } from "@lc/pieces"; import { PieceMovement } from "@lc/piece-movements"; -import { ObjectUtilities } from "@lc/utils"; export class CloseRangeMovement extends PieceMovement { - // This method sets all around moves as capturableMoves. - protected updateMovesWrapped(): void { + protected override updateMoves(): void { const piece: Piece = this.piece as Piece; const board: Board = this.board; + this.preUpdateMoves() for (const scalar1 of [-1, 1, 0]) { for (const scalar2 of [-1, 1, 0]) { @@ -19,21 +18,21 @@ export class CloseRangeMovement extends PieceMovement { const newVector: BoardVector2d = new BoardVector2d(scalar1, scalar2).add(piece.position); let move: Partial = { destination: newVector, + moveType: MoveType.Move } - if (!board.isOutOfBounds(newVector)) { - move = ObjectUtilities.deepCopy(move); - move.moveType = MoveType.Move - this.allMoves.push(move); - if (board.canMoveTo(newVector, piece, CaptureOptions.OptionalCapture)) { - move = ObjectUtilities.deepCopy(move); - this.legalMoves.push(move); - if (board.canMoveTo(newVector, piece, CaptureOptions.RequiredCapture)) { - move.moveType! |= MoveType.Capture; - move = ObjectUtilities.deepCopy(move); - this.capturableMoves.push(move); - } - } + if (board.isOutOfBounds(newVector)) { + continue; + } + if (board.canMoveTo(newVector, piece, CaptureOptions.NoCapture)) { + this.legalMoves.push(move); + } + else if (board.canMoveTo(newVector, piece, CaptureOptions.RequiredCapture)) { + move.moveType! |= MoveType.Capture; + this.legalMoves.push(move) + } + else { + this.illegalMoves.push(move); } } } diff --git a/src/pieces/movements/PieceMovement.ts b/src/pieces/movements/PieceMovement.ts index 25dd81c..fb4b133 100644 --- a/src/pieces/movements/PieceMovement.ts +++ b/src/pieces/movements/PieceMovement.ts @@ -5,28 +5,24 @@ import { Piece } from "@lc/pieces"; export abstract class PieceMovement { protected board: Board; protected piece: Piece; - public readonly allMoves: Partial[]; + public readonly illegalMoves: Partial[]; public readonly legalMoves: Partial[]; - public readonly capturableMoves: Partial[]; public constructor(piece: Piece, board: Board) { this.piece = piece; this.board = board; - this.allMoves = []; this.legalMoves = []; - this.capturableMoves = []; + this.illegalMoves = []; } protected clearMoves(): void { - this.allMoves.length = 0; - this.legalMoves.length = 0; - this.capturableMoves.length = 0; + this.legalMoves.length = 0; + this.illegalMoves.length = 0; } - protected abstract updateMovesWrapped(): void; - - public updateMoves(): void { + protected preUpdateMoves(): void { this.clearMoves(); - this.updateMovesWrapped(); } + + protected abstract updateMoves(): void; } diff --git a/src/utils/ObjectUtilities.ts b/src/utils/ObjectUtilities.ts deleted file mode 100644 index 3ea4b84..0000000 --- a/src/utils/ObjectUtilities.ts +++ /dev/null @@ -1,32 +0,0 @@ -// export function extractSubtype(properties: Record) { -// return function (value: TActual) { -// let result = {} as T; -// for (const property of Object.keys(properties) as Array) { -// result[property] = value[property]; -// } - -// return result; -// } -// } -export function deepCopy(obj: object): object { - if (obj instanceof Date) { - return new Date(obj); - } - - if (obj instanceof Array) { - const arrayCopy: unknown[] = []; - for (let i = 0; i < obj.length; i++) { - arrayCopy[i] = typeof obj[i] === "object" ? deepCopy(obj[i]) : obj[i]; - } - return arrayCopy; - } - - const objectCopy: Record = {}; - for (const property in obj) { - const objectProperty = property as keyof typeof obj; - objectCopy[property] = typeof obj[objectProperty] === "object" - ? deepCopy(obj[objectProperty]) - : obj[objectProperty]; - } - return objectCopy; -} diff --git a/src/utils/index.ts b/src/utils/index.ts index 60d7173..107b625 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,3 +1,3 @@ export { NotImplementedError, IllegalMoveError } from "./error.js"; export * as Integer from "./int.js"; -export * as ObjectUtilities from "./ObjectUtilities.js"; +export * as Syntax from "./syntax.js"; \ No newline at end of file diff --git a/src/utils/syntax.ts b/src/utils/syntax.ts new file mode 100644 index 0000000..bc48a75 --- /dev/null +++ b/src/utils/syntax.ts @@ -0,0 +1,3 @@ +export function inAlternative(alternative: number, wanted: number): boolean { + return (alternative & wanted) === wanted; +} \ No newline at end of file From 6242e9b4251e6f4b33296b6a64d6d3bf6589ee0e Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Wed, 6 Sep 2023 20:23:11 +0200 Subject: [PATCH 13/35] Refactored `KingMovement` and `KnightMovement` --- src/pieces/King.ts | 15 ++++++++------- src/pieces/Knight.ts | 24 +++++++++--------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/pieces/King.ts b/src/pieces/King.ts index d19cfa9..dff6530 100644 --- a/src/pieces/King.ts +++ b/src/pieces/King.ts @@ -81,21 +81,22 @@ export class KingMovement extends CloseRangeMovement { moveType: MoveType.Move | MoveType.KingSideCastling } if (this.isCastlingLegal(MoveType.KingSideCastling)) { - this.legalMoves.push(move) + this.legalMoves.push(move); } else { this.illegalMoves.push(move); - return } move = { destination: this.piece.position.add(new BoardVector2d(-2, 0)) as BoardVector2d, - moveType: MoveType.Move & MoveType.QueenSideCastling; + moveType: MoveType.Move & MoveType.QueenSideCastling } - else if (this.isCastlingLegal(MoveType.QueenSideCastling)) { - const - this.legalMoves.push(move) - this.allMoves.push(ObjectUtilities.deepCopy(move)); + + if (this.isCastlingLegal(MoveType.QueenSideCastling)) { + this.legalMoves.push(move); + } + else { + this.illegalMoves.push(move); } } } diff --git a/src/pieces/Knight.ts b/src/pieces/Knight.ts index 03e5ae4..6ff0dbc 100644 --- a/src/pieces/Knight.ts +++ b/src/pieces/Knight.ts @@ -2,7 +2,6 @@ import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; import { BoardVector2d, Symmetry } from "@lc/geometry"; import { Piece, PieceType } from "@lc/pieces"; import { PieceMovement } from "@lc/piece-movements"; -import { ObjectUtilities } from "@lc/utils"; export class Knight extends Piece { protected override initType(): void { @@ -43,25 +42,20 @@ export class KnightMovement extends PieceMovement { moveType: MoveType.Move } if (!board.isOutOfBounds(position)) { - this.allMoves.push(move); - if (board.canMoveTo(position, piece, CaptureOptions.OptionalCapture)) { - move = ObjectUtilities.deepCopy(move); + if (board.canMoveTo(position, piece, CaptureOptions.NoCapture)) { this.legalMoves.push(move); - if (board.canMoveTo(position, piece, CaptureOptions.RequiredCapture)) { - move = ObjectUtilities.deepCopy(move); - move.moveType! |= MoveType.Capture - this.capturableMoves.push(move); + } - move = { - destination: position, - moveType: MoveType.RangedCapture - } - this.capturableMoves.push(move); + if (board.canMoveTo(position, piece, CaptureOptions.RequiredCapture)) { + move.moveType! |= MoveType.Capture; + this.legalMoves.push(move) + move = { + destination: position, + moveType: MoveType.RangedCapture } + this.illegalMoves.push(move); } } } } - - } \ No newline at end of file From ce1296dba941d2062af8a62c90ed8804a990ac88 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Fri, 8 Sep 2023 18:48:39 +0200 Subject: [PATCH 14/35] Finished refactoring `Board`, `Tile` classes and `Movement` classes --- src/core/Board.ts | 99 +++++++++++++++++++++++++++++--------------- src/core/Lasgun.ts | 10 ++++- src/core/Tile.ts | 43 ++++++++++++++----- src/core/move.ts | 11 ++--- src/pieces/Mirror.ts | 2 +- src/pieces/Pawn.ts | 5 ++- 6 files changed, 117 insertions(+), 53 deletions(-) diff --git a/src/core/Board.ts b/src/core/Board.ts index eac2fc3..063b287 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -8,8 +8,9 @@ import { } from "@lc/core"; import { BoardVector2d, Direction, DirectionUtils, Rotation, Symmetry } from "@lc/geometry"; import { Pawn, Piece, PieceType } from "@lc/pieces"; -import { IllegalMoveError } from "@lc/utils"; +import { IllegalMoveError, Syntax } from "@lc/utils"; import { Lasgun } from "@lc/core"; +import { Mirror } from "pieces/Mirror.js"; export const enum CaptureOptions { @@ -22,8 +23,8 @@ export class Board { public readonly width: number; public readonly height: number; private readonly tiles: Map; - private readonly piecesOfType: Map; - private readonly kingsProtectors: [Piece[], Piece[]]; + private readonly piecesOfType: Map,Set]>; + private readonly kingsProtectors: [Set, Set]; private readonly movesHistory: [Move[], Move[]]; private readonly lasguns!: [Lasgun, Lasgun]; private _lastMove: Move | null; @@ -35,8 +36,8 @@ export class Board { this.width = width; this.height = height; this.tiles = new Map(); - this.piecesOfType = new Map(); - this.kingsProtectors = [[], []]; + this.piecesOfType = new Map,Set]>(); + this.kingsProtectors = [new Set, new Set]; this.movesHistory = [[], []]; this._lastMove = null; for (let i = 0; i < width; i++) { @@ -48,7 +49,7 @@ export class Board { for (const item in PieceType){ const pieceType: PieceType = PieceType[item as keyof typeof PieceType]; - this.piecesOfType.set(pieceType, []); + this.piecesOfType.set(pieceType, [new Set,new Set]); } @@ -62,22 +63,23 @@ export class Board { } } - public getPiecesOfPlayer(playerId: number): Piece[] { - let playerPieces: Piece[] = []; + public getPiecesOfPlayer(playerId: number): Set { + let playerPieces: Set = new Set; for (const type in PieceType) { const pieceType: PieceType = PieceType[type as keyof typeof PieceType]; - playerPieces = playerPieces.concat(this.piecesOfType.get(pieceType)![playerId]); + playerPieces = new Set([...playerPieces,...this.piecesOfType.get(pieceType)![playerId]]) } return playerPieces; } - public getKingProtectors(playerId: number): Piece[] { + public getKingProtectors(playerId: number): Set { return this.kingsProtectors[playerId]; } public isOutOfBounds(destination: BoardVector2d): boolean { return destination.x < 0 || destination.x >= this.width || destination.y < 0 || destination.y >= this.height; } + public getTile(position: BoardVector2d): Tile { const tile: Tile | undefined = this.tiles.get(position); if (tile === undefined) { @@ -116,9 +118,9 @@ export class Board { const tile: Tile = this.getTile(piece.position); tile.pieceOnTile = piece; - const pieceTypeArray: Piece[][] = this.piecesOfType.get(piece.type)!; - pieceTypeArray.length = Math.max(pieceTypeArray.length, piece.playerId + 1); - pieceTypeArray[piece.playerId].push(piece); + const pieceTypeSets: [Set, Set] = this.piecesOfType.get(piece.type)!; + + pieceTypeSets[piece.playerId].add(piece); } public removePiece(piece: Piece): void { @@ -136,11 +138,10 @@ export class Board { } public canRangeCapture(destination: BoardVector2d, piece: Piece): boolean { - return true; + return this.canMoveTo(destination, piece, CaptureOptions.RequiredCapture); } public canMoveTo(destination: BoardVector2d, piece: Piece, capture: CaptureOptions): boolean { - // const playerId: number = piece.playerId; // Check, if position after moving is in bounds of board. @@ -154,22 +155,19 @@ export class Board { const destinationPiece: Piece | null = this.getTile(destination)!.pieceOnTile; + if (destinationPiece === null){ - if (capture === CaptureOptions.RequiredCapture) { - return false; - } - return true; + return capture !== CaptureOptions.RequiredCapture; } + else if(!piece.isSameColor(destinationPiece)) { - if (capture === CaptureOptions.NoCapture) { - return false; - } - return true; + return capture !== CaptureOptions.NoCapture; } + return false; } - public getPiecesOfType(playerId: number, pieceType: PieceType): Piece[] { + public getPiecesOfType(playerId: number, pieceType: PieceType): Set { return this.piecesOfType.get(pieceType)![playerId]; } @@ -242,30 +240,32 @@ export class Board { throw new IllegalMoveError("Unable to perform such move."); } - private buildMove(piece: Piece, pieceMove: Partial, moveOrder: MoveOrder): Move { + private buildMove(piece: Piece, pieceMove: Partial, moveOrder: MoveOrder, promotedTo?: PieceType): Move { const ultimateMove: Move = { destination: pieceMove.destination ?? null, moveType: pieceMove.moveType!, rotation: pieceMove.rotation ?? null, origin: piece.position, piece: piece, - promotedTo: null, - captured: null + promotedTo: promotedTo ?? null, + captured: null, + laserFields: [new Set, new Set], + laserCaptures: new Set } - if ((MoveType.EnPassant & ultimateMove.moveType) === MoveType.EnPassant) { + if (Syntax.inAlternative(ultimateMove.moveType,MoveType.EnPassant)) { const directionVector: BoardVector2d = DirectionUtils.toBoardVector2d((piece as Pawn).direction!).opposite(); const enemyPositon: BoardVector2d = ultimateMove.destination!.add(directionVector); const enemyPiece: Piece = this.getPiece(enemyPositon)!; ultimateMove.captured = enemyPiece; } - else if ((MoveType.Capture & ultimateMove.moveType) === MoveType.Capture) { + else if (Syntax.inAlternative(ultimateMove.moveType,MoveType.Capture)) { const enemyPiece: Piece = this.getPiece(ultimateMove.destination!)!; ultimateMove.captured = enemyPiece; } - else if ((MoveType.RangedCapture & ultimateMove.moveType) === MoveType.RangedCapture) { + else if (Syntax.inAlternative(ultimateMove.moveType,MoveType.RangedCapture)) { const enemyPiece: Piece = this.getPiece(ultimateMove.destination!)!; ultimateMove.captured = enemyPiece; } @@ -273,16 +273,49 @@ export class Board { if (moveOrder.fireLaser === true) { ultimateMove.moveType |= MoveType.LaserFired } + //TODO Laser Fields, Laser Captures + //TODO CheckManager return ultimateMove; } - public move(move: MoveOrder, playerId: number): void { + public fulfillMove(move: Move) { + const typesOfMove: MoveType = move.moveType; + + + move.piece.move(move); + this._lastMove = move; + this.movesHistory[move.piece.playerId].push(move); + + if (Syntax.inAlternative(typesOfMove, MoveType.RangedCapture) || Syntax.inAlternative(typesOfMove, MoveType.Capture)) { + const captured: Piece = move.captured!; + this.getPiecesOfType(captured.playerId, captured.type).delete(captured); + this.getTile(captured.position).pieceOnTile = null; + } + + if (Syntax.inAlternative(typesOfMove, MoveType.Move)) { + const pieceToMove: Piece = move.piece; + this.getTile(pieceToMove.position).pieceOnTile = null; + this.getTile(move.destination!).pieceOnTile = pieceToMove; + } + + if (Syntax.inAlternative(typesOfMove, MoveType.Rotation)) { + (this.getTile(move.origin).pieceOnTile! as Mirror).turn(move.rotation!); + } + //TODO Laser Fields and other Move Types + } + + public move(move: MoveOrder, playerId: number, promotionTo?: PieceType): void { const moveFromPiece: Partial = this.getSpecificMove(move, playerId); + + if (Syntax.inAlternative(moveFromPiece.moveType!, MoveType.Promotion) && promotionTo === undefined) { + // Return some data, that would tell gui, that selected move is legal, + // and it needs to send PieceType in promotionTo. + } + const pieceToMove: Piece = this.getTile(move.origin).pieceOnTile!; const moveToAnalyze: Move = this.buildMove(pieceToMove, moveFromPiece, move); - - pieceToMove.move(moveToAnalyze); + this.fulfillMove(moveToAnalyze); } diff --git a/src/core/Lasgun.ts b/src/core/Lasgun.ts index 68ac661..374f30e 100644 --- a/src/core/Lasgun.ts +++ b/src/core/Lasgun.ts @@ -1,6 +1,11 @@ -import { Board } from "@lc/core"; +import { Board, MoveType } from "@lc/core"; import { BoardVector2d, Direction } from "@lc/geometry"; +export const enum LaserState { + LaserFired = 1 << 0, + LaserSustained = 1 << 1, + LaserOff = 1 << 2 +} export class Lasgun { private _maxToCharge?: number; @@ -39,6 +44,9 @@ export class Lasgun { return this.currentCharge; } + public get laserState(): LaserState { + return LaserState.LaserFired; + } public propagateLaser() { // TODO diff --git a/src/core/Tile.ts b/src/core/Tile.ts index 83188c9..6a0eded 100644 --- a/src/core/Tile.ts +++ b/src/core/Tile.ts @@ -10,8 +10,8 @@ export const enum MovesPredictionsType { export class Tile { private _coordinates: BoardVector2d; - private inMovesLegalOf: Set[]; - private inMovesIllegalOf: Set[]; + private inMovesLegalOf: [Set, Set]; + private inMovesIllegalOf: [Set, Set]; public pieceOnTile: Piece | null; public constructor(coordinates: BoardVector2d) { @@ -34,28 +34,49 @@ export class Tile { public addPieceMovesToTile(piece: Piece, movePredictionsType: MovesPredictionsType): void { if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Illegal)) { - + this.inMovesIllegalOf[piece.playerId].add(piece); + } + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Legal)) { + this.inMovesLegalOf[piece.playerId].add(piece); } } public removePieceMovesFromTile(piece: Piece, movePredictionsType: MovesPredictionsType): void { - + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Illegal)) { + this.inMovesIllegalOf[piece.playerId].delete(piece); + } + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Legal)) { + this.inMovesLegalOf[piece.playerId].delete(piece); + } } public checkIfPieceMovesInTile(piece: Piece, movePredictionsType: MovesPredictionsType): boolean { - + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Illegal)) { + return this.inMovesIllegalOf[piece.playerId].has(piece); + } + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Legal)) { + return this.inMovesLegalOf[piece.playerId].has(piece); + } + return false; } - public isPieceMovesEmpty(playerId: number, movePredictionsType: MovesPredictionsType): boolean{ + public isPieceMovesEmpty(playerId: number, movePredictionsType: MovesPredictionsType): boolean { + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Illegal)) { + return this.inMovesIllegalOf[playerId].size === 0; + } + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Legal)) { + return this.inMovesLegalOf[playerId].size === 0; + } + return true; } public getPieceMovesOfTile(playerId: number, movePredictionsType: MovesPredictionsType) { let piecesSet: Set = new Set; - for (const item in MovesPredictionsType){ - const movesEnumValue: MovesPredictionsType = MovesPredictionsType[item as keyof typeof MovesPredictionsType] - if ((movePredictionsType & movesEnumValue) === movesEnumValue) { - piecesSet = new Set([...piecesSet, ...this.setHashMap.get(movesEnumValue)![playerId]]) - } + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Illegal)) { + piecesSet = new Set(this.inMovesIllegalOf[playerId]); + } + if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Legal)) { + piecesSet = new Set([...this.inMovesIllegalOf[playerId],...this.inMovesLegalOf[playerId]]); } return piecesSet; } diff --git a/src/core/move.ts b/src/core/move.ts index 8772feb..f9b4206 100644 --- a/src/core/move.ts +++ b/src/core/move.ts @@ -11,13 +11,12 @@ export const enum MoveType { Rotation = 1 << 6, Promotion = 1 << 7, - Check = 1 << 8, + LaserFired = 1 << 8, Checkmate = 1 << 9, Stalemate = 1 << 10, - Draw = 1 << 11, - Lasermate = 1 << 12, - LaserFired = 1 << 13, - LaserCooldown = 1 << 14 + Lasermate = 1 << 11, + Draw = 1 << 12, + Check = 1 << 13, } export interface Move { @@ -29,6 +28,8 @@ export interface Move { promotedTo: PieceType | null piece: Piece, captured: Piece | null, + laserFields: [Set, Set], + laserCaptures: Set } export interface MoveOrder { diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index 512c276..0940d2f 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -29,7 +29,7 @@ export class Mirror extends DirectedPiece { this.direction = DirectionUtils.rotateDoubleAnticlockwise(this.direction!); } - private turn(rotation: Rotation): void { + public turn(rotation: Rotation): void { switch(rotation) { case Rotation.Anticlockwise: this.turnAnticlockwise(); diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index 6cab3d3..2da571d 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -51,8 +51,9 @@ export class PawnMovement extends PieceMovement { return otherPiece !== null && !otherPiece.isSameColor(piece) && otherPiece.type === PieceType.PAWN - && board.canMoveTo(destination, piece, CaptureOptions.RequiredCapture) + && board.canMoveTo(destination, piece, CaptureOptions.NoCapture) && board.lastMove?.piece !== null + && board.lastMove?.piece !== otherPiece && piece.isOnEnPassantPosition(); } @@ -122,7 +123,7 @@ export class PawnMovement extends PieceMovement { const tmpPosition: BoardVector2d = piece.position.add(position); const move: Partial = { destination: position, - moveType: MoveType.Move & MoveType.Capture + moveType: MoveType.Move | MoveType.Capture } if (this.isEnPassantLegal(tmpPosition)) { this.legalMoves.push(move); From 8657edba7c5b50b1da7a0852007655024bf725ee Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 10 Sep 2023 22:52:42 +0200 Subject: [PATCH 15/35] Change type of tiles field in `Board` to `Map` --- src/core/Board.ts | 86 ++++++++++++++------------------------- src/geometry/Direction.ts | 1 + 2 files changed, 32 insertions(+), 55 deletions(-) diff --git a/src/core/Board.ts b/src/core/Board.ts index 063b287..fc9d851 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -22,7 +22,7 @@ export const enum CaptureOptions { export class Board { public readonly width: number; public readonly height: number; - private readonly tiles: Map; + private readonly tiles: Map; private readonly piecesOfType: Map,Set]>; private readonly kingsProtectors: [Set, Set]; private readonly movesHistory: [Move[], Move[]]; @@ -35,17 +35,11 @@ export class Board { public constructor(width: number, height: number) { this.width = width; this.height = height; - this.tiles = new Map(); + this.tiles = new Map(); this.piecesOfType = new Map,Set]>(); this.kingsProtectors = [new Set, new Set]; this.movesHistory = [[], []]; this._lastMove = null; - for (let i = 0; i < width; i++) { - for (let j = 0; j < height; j++) { - const place: BoardVector2d = new BoardVector2d(i, j); - this.tiles.set(place, new Tile(place.copy())); - } - } for (const item in PieceType){ const pieceType: PieceType = PieceType[item as keyof typeof PieceType]; @@ -57,12 +51,6 @@ export class Board { // this.checkManager } - public updateAllTiles() { - for (let tile of this.tiles) { - tile[1].clearAllPredictions(); - } - } - public getPiecesOfPlayer(playerId: number): Set { let playerPieces: Set = new Set; for (const type in PieceType) { @@ -79,29 +67,17 @@ export class Board { return destination.x < 0 || destination.x >= this.width || destination.y < 0 || destination.y >= this.height; } - - public getTile(position: BoardVector2d): Tile { - const tile: Tile | undefined = this.tiles.get(position); - if (tile === undefined) { - throw new Error("There is no tile with coordinates of passed piece."); - } - return tile; + public changePosition(newPosition: BoardVector2d, piece: Piece) { + this.removePiece(piece); + this.tiles.set(newPosition, piece); } public getPiece(position: BoardVector2d): Piece | null { - return this.getTile(position).pieceOnTile; + return this.tiles.get(position) ?? null; } - public getTileOfPiece(piece: Piece): Tile { - return this.getTile(piece.position); - } - public isPieceAt(positon: BoardVector2d): boolean { - const tile: Tile | undefined = this.tiles.get(positon); - if (tile === undefined) { - return false; - } - return tile.pieceOnTile !== undefined; + return this.getPiece(positon) !== null; } public addPieces(pieces: Piece[]): void { @@ -114,23 +90,29 @@ export class Board { if (this.isPieceAt(piece.position)) { throw new Error("There is already piece at this position."); } - - const tile: Tile = this.getTile(piece.position); - tile.pieceOnTile = piece; - - const pieceTypeSets: [Set, Set] = this.piecesOfType.get(piece.type)!; - - pieceTypeSets[piece.playerId].add(piece); + this.tiles.set(piece.position, piece); + this.piecesOfType.get(piece.type)![piece.playerId].add(piece); } public removePiece(piece: Piece): void { - const tile: Tile | undefined = this.tiles.get(piece.position); - if (tile === undefined) { - return; + this.tiles.delete(piece.position); + this.piecesOfType.get(piece.type)![piece.playerId].delete(piece); + for (let protectors of this.kingsProtectors) { + protectors.delete(piece); } - if (tile.pieceOnTile === piece) { - tile.pieceOnTile = null; + } + + public shiftPiece(origin: BoardVector2d, destination: BoardVector2d) { + const piece: Piece | null = this.getPiece(origin); + if (piece === null) { + throw new Error("Unable to shift piece. There is no piece on origin."); } + this.tiles.delete(origin); + + if (this.getPiece(destination) === null) { + throw new Error("Unable to shift piece. There is already piece on destionation."); + } + this.tiles.set(destination, piece); } public canRotate(rotation: Rotation, piece: Piece): boolean { @@ -153,7 +135,7 @@ export class Board { // TODO Checks - const destinationPiece: Piece | null = this.getTile(destination)!.pieceOnTile; + const destinationPiece: Piece | null = this.getPiece(destination); if (destinationPiece === null){ @@ -172,7 +154,7 @@ export class Board { } private getSpecificMove(move: MoveOrder, playerId: number): Partial { - let pieceToMove: Piece | null = this.getTile(move.origin).pieceOnTile; + let pieceToMove: Piece | null = this.getPiece(move.origin); if (pieceToMove === null) { throw new IllegalMoveError("There is no piece on origin postion."); @@ -273,8 +255,7 @@ export class Board { if (moveOrder.fireLaser === true) { ultimateMove.moveType |= MoveType.LaserFired } - //TODO Laser Fields, Laser Captures - //TODO CheckManager + // Laser Fields, Laser Captures, and Check Manager flags should be set here return ultimateMove; } @@ -289,17 +270,12 @@ export class Board { if (Syntax.inAlternative(typesOfMove, MoveType.RangedCapture) || Syntax.inAlternative(typesOfMove, MoveType.Capture)) { const captured: Piece = move.captured!; this.getPiecesOfType(captured.playerId, captured.type).delete(captured); - this.getTile(captured.position).pieceOnTile = null; + this.removePiece(captured); } if (Syntax.inAlternative(typesOfMove, MoveType.Move)) { const pieceToMove: Piece = move.piece; - this.getTile(pieceToMove.position).pieceOnTile = null; - this.getTile(move.destination!).pieceOnTile = pieceToMove; - } - - if (Syntax.inAlternative(typesOfMove, MoveType.Rotation)) { - (this.getTile(move.origin).pieceOnTile! as Mirror).turn(move.rotation!); + this.shiftPiece(move.origin, move.destination!); } //TODO Laser Fields and other Move Types } @@ -312,7 +288,7 @@ export class Board { // and it needs to send PieceType in promotionTo. } - const pieceToMove: Piece = this.getTile(move.origin).pieceOnTile!; + const pieceToMove: Piece = this.getPiece(move.origin)!; const moveToAnalyze: Move = this.buildMove(pieceToMove, moveFromPiece, move); this.fulfillMove(moveToAnalyze); diff --git a/src/geometry/Direction.ts b/src/geometry/Direction.ts index 239b89e..c6c2cf9 100644 --- a/src/geometry/Direction.ts +++ b/src/geometry/Direction.ts @@ -7,6 +7,7 @@ export const enum Direction { BottomRightDiagonal = 5, BottomFile = 6, BottomLeftDiagonal = 7, + Last = 8 } export const enum Rotation { From 8223d511fd02360fda94ce57c134242ff82f15bb Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Mon, 11 Sep 2023 13:52:51 +0200 Subject: [PATCH 16/35] Updated tests for `Vector2d` and its subclasses --- jest.config.ts | 12 ------------ src/geometry/Vector2d.ts | 33 ++++++++++++++++++++++++--------- tests/geometry/vector.test.ts | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 21 deletions(-) delete mode 100644 jest.config.ts diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index 4f73ca4..0000000 --- a/jest.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { JestConfigWithTsJest } from "ts-jest"; -import { pathsToModuleNameMapper } from "ts-jest"; -import { compilerOptions } from "./tsconfig.json"; - -const jestConfig: JestConfigWithTsJest = { - preset: "ts-jest", - roots: [""], - modulePaths: [compilerOptions.baseUrl], - moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { useESM: true }) -}; - -export default jestConfig; diff --git a/src/geometry/Vector2d.ts b/src/geometry/Vector2d.ts index ac9fb90..99db34a 100644 --- a/src/geometry/Vector2d.ts +++ b/src/geometry/Vector2d.ts @@ -50,7 +50,7 @@ export class Vector2d { * It has to be done in order to ensure that subclass * will return its instance and not superclass instance. * - * @summary Method creates new `Vector2d` object. Shoudl be overriden by + * @summary Method creates new `Vector2d` object. Should be overriden by * subclass to return its instance. * @param {number} x - `number` that is ment to be first coordinate. * @param {number} y - `number` that is ment to be second coordinate. @@ -333,7 +333,7 @@ export class IntVector2d extends Vector2d { */ public createUnitVector(prioritizeAxisY?: boolean): T { if (Math.abs(this.x) === Math.abs(this.y)) { - if (typeof prioritizeAxisY === "undefined" || prioritizeAxisY === true) { + if (prioritizeAxisY !== undefined || prioritizeAxisY === true) { return this.createVector(0, Math.sign(this.y)); } return this.createVector(Math.sign(this.x), 0); @@ -455,6 +455,15 @@ export class BoardVector2d extends IntVector2d { return this.createVector(this.x, this.y) as T; } + /** + * Method creates array of `BoardVector2d` objects. First element of this array is copy of calling + * object. Following objects are created by adding multiples of `increment` values to calling object. + * + * @param {[number, number]} increment Tuple consisting of two integers that inform about direction + * in which new `BoardVector2d` should be propagated. + * @param board Instance of `Board` which sets up boundaries for moving. + * @returns Array of `BoardVector2d` created from calling object with direction given by `increment`. + */ public getDirectedMoveFromTuple(increment: [number, number], board: Board): BoardVector2d[] { const x: number = increment[0]; const y: number = increment[1]; @@ -465,12 +474,12 @@ export class BoardVector2d extends IntVector2d { const xCoordinates: number[] = []; const yCoordinates: number[] = []; if (x !== 0) { - for (let i = this.x; i < (x > 0 ? board.width : -1); i += x) { + for (let i = this.x; x > 0 ? i < board.width : i > -1; i += x) { xCoordinates.push(i); } } if (y !== 0) { - for (let i = this.y; i < (y > 0 ? board.width : -1); i += y) { + for (let i = this.y; y > 0 ? i < board.width : i > -1; i += y) { yCoordinates.push(i); } } @@ -486,15 +495,21 @@ export class BoardVector2d extends IntVector2d { } const moves: BoardVector2d[] = []; - for (const x of xCoordinates) { - for (const y of yCoordinates) { - moves.push(new BoardVector2d(x, y)); - } + const length: number = Math.min(xCoordinates.length, yCoordinates.length); + for (let i = 0; i { @@ -46,6 +47,16 @@ describe("Vector2d", () => { expect(new Vector2d(1.5, 2).copy()).not.toStrictEqual(new Vector2d(1, 2)); }); + test("Length", () => { + expect(new Vector2d(3, 4).getLength()).toStrictEqual(5); + }); + + test("Unit Vector", () => { + expect(new Vector2d(3, 4).createUnitVector()).toStrictEqual(new Vector2d(0.6, 0.8)); + }); + + + }); describe("IntVector2d", () => { @@ -75,6 +86,13 @@ describe("IntVector2d", () => { expect(new IntVector2d(1, 1).copy()).toStrictEqual(new IntVector2d(1, 1)); expect(new IntVector2d(1.5, 2).copy()).toStrictEqual(new IntVector2d(1, 2)); }); + + test("Unit Vector", () => { + expect(new IntVector2d(3, 4).createUnitVector()).toStrictEqual(new IntVector2d(0, 1)); + expect(new IntVector2d(-6, 4).createUnitVector()).toStrictEqual(new IntVector2d(-1, 0)); + expect(new IntVector2d(3, 3).createUnitVector()).toStrictEqual(new IntVector2d(1, 0)); + expect(new IntVector2d(3, 3).createUnitVector(true)).toStrictEqual(new IntVector2d(0, 1)); + }); }); describe("BoardVector2d", () => { @@ -102,6 +120,20 @@ describe("BoardVector2d", () => { expect(new BoardVector2d(1, 2).copy()).toStrictEqual(new BoardVector2d(1, 2)); }); + test("Getting moves", () => { + // vi.mock('@lc/core', () => { + // const Board = vi.fn(); + // Board.prototype.width = 8; + // Board.prototype.height = 8; + // return {Board}; + // }) + // const board: Board = new Board(); + const board: Board = new Board(8,8) + let vector: BoardVector2d = new BoardVector2d(7,7); + expect(vector.getDirectedMoveFromTuple([1,1],board)).toStrictEqual([new BoardVector2d(7,7)]); + vector = new BoardVector2d(2,4); + expect(vector.getDirectedMoveFromTuple([-1,1],board)).toStrictEqual([new BoardVector2d(2,4), new BoardVector2d(1,5),new BoardVector2d(0,6)]); + }) }); From c33a570010e5c2860015e7b8f5e863ced58d66f2 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Tue, 12 Sep 2023 22:07:53 +0200 Subject: [PATCH 17/35] Created `PawnPieceFactory` and `MirrorPieceFactory`. --- .../piece_factories/MirrorPieceFactory.ts | 0 .../piece_factories/PawnPieceFactory.ts | 21 ++++++++++++ .../piece_factories/StandardPieceFactory.ts | 32 +++++++++++++++++++ src/utils/syntax.ts | 4 +-- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/pieces/piece_factories/MirrorPieceFactory.ts create mode 100644 src/pieces/piece_factories/PawnPieceFactory.ts create mode 100644 src/pieces/piece_factories/StandardPieceFactory.ts diff --git a/src/pieces/piece_factories/MirrorPieceFactory.ts b/src/pieces/piece_factories/MirrorPieceFactory.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/pieces/piece_factories/PawnPieceFactory.ts b/src/pieces/piece_factories/PawnPieceFactory.ts new file mode 100644 index 0000000..9f3c6e6 --- /dev/null +++ b/src/pieces/piece_factories/PawnPieceFactory.ts @@ -0,0 +1,21 @@ +import { Piece, PieceType } from "pieces/Piece.js"; +import { StandardPieceData, StandardPieceFactory } from "./StandardPieceFactory.js"; +import { Direction } from "geometry/Direction.js"; +import { BoardVector2d } from "geometry/Vector2d.js"; +import { Pawn } from "pieces/Pawn.js"; + +export interface PawnPieceData extends StandardPieceData{ + direction: Direction + enPassantPosition: BoardVector2d, + promotionPosition: BoardVector2d, +} + +export class PawnPieceFactory { + public createPiece(pieceData: PawnPieceData): Piece { + const pawn: Pawn = new Pawn(pieceData.position, pieceData.playerId, pieceData.board); + pawn.direction = pieceData.direction; + pawn.enPassantPosition = pieceData.enPassantPosition; + pawn.promotionPosition = pieceData.promotionPosition; + return pawn; + } +} \ No newline at end of file diff --git a/src/pieces/piece_factories/StandardPieceFactory.ts b/src/pieces/piece_factories/StandardPieceFactory.ts new file mode 100644 index 0000000..921c595 --- /dev/null +++ b/src/pieces/piece_factories/StandardPieceFactory.ts @@ -0,0 +1,32 @@ +import { PieceType, Piece } from "pieces/Piece.js"; +import { AbstractPieceFactory, StandardPieceData } from "./AbstractPieceFactory.js"; +import { King } from "pieces/King.js"; +import { Queen } from "pieces/Queen.js"; +import { Knight } from "pieces/Knight.js"; +import { BoardVector2d } from "geometry/Vector2d.js"; +import { Board } from "core/Board.js"; + +export interface StandardPieceData { + position: BoardVector2d, + playerId: number, + board: Board +} + +export class StandardPieceFactory extends AbstractPieceFactory { + public createPiece(pieceData: StandardPieceData, type: PieceType): Piece { + switch(type) { + case PieceType.KING: + return new King(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.QUEEN: + return new Queen(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.BISHOP: + return new Bishop(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.ROOK: + return new Rook(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.KNIGHT: + return new Knight(pieceData.position, pieceData.playerId, pieceData.board); + } + throw new Error("Unable to create this type of piece using StandardPieceFactory.") + } + +} \ No newline at end of file diff --git a/src/utils/syntax.ts b/src/utils/syntax.ts index bc48a75..e649169 100644 --- a/src/utils/syntax.ts +++ b/src/utils/syntax.ts @@ -1,3 +1,3 @@ export function inAlternative(alternative: number, wanted: number): boolean { - return (alternative & wanted) === wanted; -} \ No newline at end of file + return (alternative & wanted) === wanted; +} From 40a71c5c69719b1f53bf6d42cd5396a4111ec4f8 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Wed, 13 Sep 2023 21:29:31 +0200 Subject: [PATCH 18/35] Created `PieceGenerator` instead of factories --- .../piece_factories/MirrorPieceFactory.ts | 0 .../piece_factories/PawnPieceFactory.ts | 21 ------------- ...ndardPieceFactory.ts => PieceGenerator.ts} | 31 +++++++++++++++++-- src/pieces/piece_factories/index.ts | 1 + 4 files changed, 29 insertions(+), 24 deletions(-) delete mode 100644 src/pieces/piece_factories/MirrorPieceFactory.ts delete mode 100644 src/pieces/piece_factories/PawnPieceFactory.ts rename src/pieces/piece_factories/{StandardPieceFactory.ts => PieceGenerator.ts} (50%) create mode 100644 src/pieces/piece_factories/index.ts diff --git a/src/pieces/piece_factories/MirrorPieceFactory.ts b/src/pieces/piece_factories/MirrorPieceFactory.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/pieces/piece_factories/PawnPieceFactory.ts b/src/pieces/piece_factories/PawnPieceFactory.ts deleted file mode 100644 index 9f3c6e6..0000000 --- a/src/pieces/piece_factories/PawnPieceFactory.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Piece, PieceType } from "pieces/Piece.js"; -import { StandardPieceData, StandardPieceFactory } from "./StandardPieceFactory.js"; -import { Direction } from "geometry/Direction.js"; -import { BoardVector2d } from "geometry/Vector2d.js"; -import { Pawn } from "pieces/Pawn.js"; - -export interface PawnPieceData extends StandardPieceData{ - direction: Direction - enPassantPosition: BoardVector2d, - promotionPosition: BoardVector2d, -} - -export class PawnPieceFactory { - public createPiece(pieceData: PawnPieceData): Piece { - const pawn: Pawn = new Pawn(pieceData.position, pieceData.playerId, pieceData.board); - pawn.direction = pieceData.direction; - pawn.enPassantPosition = pieceData.enPassantPosition; - pawn.promotionPosition = pieceData.promotionPosition; - return pawn; - } -} \ No newline at end of file diff --git a/src/pieces/piece_factories/StandardPieceFactory.ts b/src/pieces/piece_factories/PieceGenerator.ts similarity index 50% rename from src/pieces/piece_factories/StandardPieceFactory.ts rename to src/pieces/piece_factories/PieceGenerator.ts index 921c595..c6c0a6c 100644 --- a/src/pieces/piece_factories/StandardPieceFactory.ts +++ b/src/pieces/piece_factories/PieceGenerator.ts @@ -1,10 +1,12 @@ import { PieceType, Piece } from "pieces/Piece.js"; -import { AbstractPieceFactory, StandardPieceData } from "./AbstractPieceFactory.js"; import { King } from "pieces/King.js"; import { Queen } from "pieces/Queen.js"; import { Knight } from "pieces/Knight.js"; import { BoardVector2d } from "geometry/Vector2d.js"; import { Board } from "core/Board.js"; +import { Direction } from "geometry/Direction.js"; +import { Mirror } from "pieces/Mirror.js"; +import { Pawn } from "pieces/Pawn.js"; export interface StandardPieceData { position: BoardVector2d, @@ -12,8 +14,17 @@ export interface StandardPieceData { board: Board } -export class StandardPieceFactory extends AbstractPieceFactory { - public createPiece(pieceData: StandardPieceData, type: PieceType): Piece { +export interface DirectedPieceData extends StandardPieceData { + direction: Direction, +} + +export interface PawnPieceData extends DirectedPieceData { + enPassantPosition: BoardVector2d, + promotionPosition: BoardVector2d +} + +export class PieceGenerator { + public createStandardPiece(pieceData: StandardPieceData, type: PieceType): Piece { switch(type) { case PieceType.KING: return new King(pieceData.position, pieceData.playerId, pieceData.board); @@ -28,5 +39,19 @@ export class StandardPieceFactory extends AbstractPieceFactory { } throw new Error("Unable to create this type of piece using StandardPieceFactory.") } + + public createMirror(pieceData: DirectedPieceData): Mirror { + const piece: Mirror = new Mirror(pieceData.position, pieceData.playerId, pieceData.board); + piece.direction = pieceData.direction; + return piece; + } + + public createPawn(pieceData: PawnPieceData): Pawn { + const piece: Pawn = new Pawn(pieceData.position, pieceData.playerId, pieceData.board); + piece.direction = pieceData.direction; + piece.enPassantPosition = pieceData.enPassantPosition; + piece.promotionPosition = pieceData.promotionPosition; + return piece; + } } \ No newline at end of file diff --git a/src/pieces/piece_factories/index.ts b/src/pieces/piece_factories/index.ts new file mode 100644 index 0000000..48549a1 --- /dev/null +++ b/src/pieces/piece_factories/index.ts @@ -0,0 +1 @@ +export { PieceGenerator } from "./PieceGenerator.js" \ No newline at end of file From 88cd3db405342a017148fcff49a03a2efea7f36c Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Thu, 14 Sep 2023 21:32:43 +0200 Subject: [PATCH 19/35] Finished long range pieces. --- src/core/Board.ts | 15 +++-- src/pieces/Bishop.ts | 17 ++++++ src/pieces/Queen.ts | 6 +- src/pieces/Rook.ts | 17 ++++++ src/pieces/index.ts | 7 ++- src/pieces/movements/LongRangeMovement.ts | 62 ++++++++++++++------ src/pieces/piece_factories/PieceGenerator.ts | 21 ++++--- 7 files changed, 103 insertions(+), 42 deletions(-) diff --git a/src/core/Board.ts b/src/core/Board.ts index fc9d851..599d26a 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -1,16 +1,15 @@ import { CheckManager, PromotionManager, - Tile, + Move, MoveOrder, MoveType } from "@lc/core"; -import { BoardVector2d, Direction, DirectionUtils, Rotation, Symmetry } from "@lc/geometry"; +import { BoardVector2d, DirectionUtils, Rotation, Symmetry } from "@lc/geometry"; import { Pawn, Piece, PieceType } from "@lc/pieces"; import { IllegalMoveError, Syntax } from "@lc/utils"; import { Lasgun } from "@lc/core"; -import { Mirror } from "pieces/Mirror.js"; export const enum CaptureOptions { @@ -107,11 +106,11 @@ export class Board { if (piece === null) { throw new Error("Unable to shift piece. There is no piece on origin."); } - this.tiles.delete(origin); - - if (this.getPiece(destination) === null) { - throw new Error("Unable to shift piece. There is already piece on destionation."); + if (this.getPiece(destination) !== null) { + throw new Error("Unable to shift piece. There is already piece on destination."); } + piece.position = destination; + this.tiles.delete(origin); this.tiles.set(destination, piece); } @@ -285,7 +284,7 @@ export class Board { if (Syntax.inAlternative(moveFromPiece.moveType!, MoveType.Promotion) && promotionTo === undefined) { // Return some data, that would tell gui, that selected move is legal, - // and it needs to send PieceType in promotionTo. + // but it needs to send PieceType in promotionTo. } const pieceToMove: Piece = this.getPiece(move.origin)!; diff --git a/src/pieces/Bishop.ts b/src/pieces/Bishop.ts index e69de29..c85cb77 100644 --- a/src/pieces/Bishop.ts +++ b/src/pieces/Bishop.ts @@ -0,0 +1,17 @@ +import { Direction } from "@lc/geometry"; +import { Piece, PieceType } from "@lc/pieces"; +import { LongRangeMovement } from "@lc/piece-movements"; + +export class Bishop extends Piece { + public static DIRECTIONS = [ + Direction.UpperRightDiagonal, + Direction.BottomRightDiagonal, + Direction.BottomLeftDiagonal, + Direction.UpperLeftDiagonal + ]; + + protected override initType(): void { + this._type = PieceType.BISHOP; + this._movement = new LongRangeMovement(this, this.board, Bishop.DIRECTIONS); + } +} diff --git a/src/pieces/Queen.ts b/src/pieces/Queen.ts index 03849f4..45c680e 100644 --- a/src/pieces/Queen.ts +++ b/src/pieces/Queen.ts @@ -1,6 +1,6 @@ -import { Direction } from "geometry/Direction.js"; -import { Piece, PieceType } from "./Piece.js"; -import { LongRangeMovement } from "./movements/LongRangeMovement.js"; +import { Direction } from "@lc/geometry"; +import { Piece, PieceType } from "@lc/pieces"; +import { LongRangeMovement } from "@lc/piece-movements"; export class Queen extends Piece { public static DIRECTIONS = [ diff --git a/src/pieces/Rook.ts b/src/pieces/Rook.ts index e69de29..ddbd834 100644 --- a/src/pieces/Rook.ts +++ b/src/pieces/Rook.ts @@ -0,0 +1,17 @@ +import { Direction } from "@lc/geometry"; +import { Piece, PieceType } from "@lc/pieces"; +import { LongRangeMovement } from "@lc/piece-movements"; + +export class Rook extends Piece { + public static DIRECTIONS = [ + Direction.UpperFile, + Direction.RightRank, + Direction.BottomFile, + Direction.LeftRank, + ]; + + protected override initType(): void { + this._type = PieceType.ROOK; + this._movement = new LongRangeMovement(this, this.board, Rook.DIRECTIONS); + } +} diff --git a/src/pieces/index.ts b/src/pieces/index.ts index ad032e0..c62618b 100644 --- a/src/pieces/index.ts +++ b/src/pieces/index.ts @@ -1,8 +1,9 @@ export { Piece, PieceType, PieceOptions } from "./Piece.js"; export { DirectedPiece } from "./DirectedPiece.js"; export { King } from "./King.js"; -// export { Queen } from "./Queen.js"; -// export { Rook } from "./Rook.js"; -// export { Bishop } from "./Bishop.js"; +export { Queen } from "./Queen.js"; +export { Rook } from "./Rook.js"; +export { Bishop } from "./Bishop.js"; export { Knight } from "./Knight.js"; export { Pawn } from "./Pawn.js"; +export { Mirror } from "./Mirror.js" diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index 175b8ae..2746f00 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -1,12 +1,11 @@ -import { Board, Move } from "@lc/core"; -import { NotImplementedError } from "@lc/utils"; +import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; import { BoardVector2d, Direction, DirectionUtils } from "@lc/geometry"; import { Piece } from "@lc/pieces"; import { PieceMovement } from "@lc/piece-movements"; +import { Syntax } from "@lc/utils"; export class LongRangeMovement extends PieceMovement { - // All moves but grouped by its direction. - public allLongRangeMoves: Partial>> = {}; + public allLongRangeMoves: Partial[]>> = {}; public readonly directions: Direction[]; constructor(piece: Piece, board: Board, directions: Direction[]) { @@ -16,19 +15,36 @@ export class LongRangeMovement extends PieceMovement { protected override updateMoves(): void { this.preUpdateMoves(); + this.allLongRangeMoves = this.getAllLongRangeMoves(); + for (let direction of this.directions) { + let legal: boolean = true; + for (let move of this.allLongRangeMoves[direction]!) { + if (Syntax.inAlternative(move.moveType!, MoveType.Capture)) { + legal = false; + } + + if (legal) { + this.legalMoves.push(move); + } + else { + this.illegalMoves.push(move); + } + } + } } - private getAllLongRangeMoves(): Partial>> { - const moves: Partial>> = {}; + private getAllLongRangeMoves(): Partial[]>> { + const moves: Partial[]>> = {}; for (const direction of this.directions) { - const moveCoordinates = this.getAllCoordinatesByDirection(direction); + moves[direction] = this.getAllCoordinatesByDirection(direction); } return moves; } - private getAllCoordinatesByDirection(direction: Direction): BoardVector2d[] { - const x = this.piece.position.x, y = this.piece.position.y, + private getAllCoordinatesByDirection(direction: Direction): Partial[] { + const x = this.piece.position.x, + y = this.piece.position.y, tuple = DirectionUtils.toTuple(direction), step = { x: tuple[0], y: tuple[1] }; const maxMoveLength = { @@ -37,15 +53,23 @@ export class LongRangeMovement extends PieceMovement { }; const moveLength = Math.min(maxMoveLength.x, maxMoveLength.y); - return new Array(moveLength) - .map((_: unknown, i: number) => new BoardVector2d(x + i * step.x, y + i * step.y)); - } - - public getAllMoves(): BoardVector2d[][] { - throw new NotImplementedError("getAllMoves() method is not implemented yet"); - } - - public getLegalMoves(): BoardVector2d[][] { - throw new NotImplementedError("getLegalMoves() method is not implemented yet"); + const moveArray: Partial[] = []; + let i = 0; + for (;i < moveLength; i++) { + let vector: BoardVector2d = new BoardVector2d(x + i * step.x, y + i * step.y); + if (this.board.canMoveTo(vector, this.piece, CaptureOptions.NoCapture)) { + moveArray.push({ + destination: vector, + moveType: MoveType.Move + }) + } + else if (this.board.canMoveTo(vector, this.piece, CaptureOptions.RequiredCapture)) { + moveArray.push({ + destination: vector, + moveType: MoveType.Move | MoveType.Capture + }) + } + } + return moveArray } } \ No newline at end of file diff --git a/src/pieces/piece_factories/PieceGenerator.ts b/src/pieces/piece_factories/PieceGenerator.ts index c6c0a6c..7f9fd4d 100644 --- a/src/pieces/piece_factories/PieceGenerator.ts +++ b/src/pieces/piece_factories/PieceGenerator.ts @@ -1,12 +1,15 @@ -import { PieceType, Piece } from "pieces/Piece.js"; -import { King } from "pieces/King.js"; -import { Queen } from "pieces/Queen.js"; -import { Knight } from "pieces/Knight.js"; -import { BoardVector2d } from "geometry/Vector2d.js"; -import { Board } from "core/Board.js"; -import { Direction } from "geometry/Direction.js"; -import { Mirror } from "pieces/Mirror.js"; -import { Pawn } from "pieces/Pawn.js"; +import { + PieceType, + Piece, + King, + Queen, + Knight, + Mirror, + Pawn, + Bishop, + Rook } from "@lc/pieces"; +import { BoardVector2d, Direction } from "@lc/geometry"; +import { Board } from "@lc/core"; export interface StandardPieceData { position: BoardVector2d, From 0ab3890d5bdcea34759472856ada560f1446a306 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Thu, 14 Sep 2023 23:05:59 +0200 Subject: [PATCH 20/35] Created tests for `DirectionUtils` --- package-lock.json | 3028 +++++++------------------ src/geometry/Direction.ts | 3 +- src/geometry/DirectionUtils.ts | 9 +- src/geometry/Vector2d.ts | 22 + tests/geometry/DirectionUtils.test.ts | 67 + 5 files changed, 973 insertions(+), 2156 deletions(-) create mode 100644 tests/geometry/DirectionUtils.test.ts diff --git a/package-lock.json b/package-lock.json index b6dc3c6..f4ccc0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,451 +1,203 @@ { "name": "typescript-chess-engine", "version": "0.6.0", - "lockfileVersion": 3, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "typescript-chess-engine", - "version": "0.6.0", - "license": "ISC", - "dependencies": { - "chalk": "^5.3.0", - "jsdoc": "^4.0.2", - "ts-node": "^10.9.1" - }, - "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.4.1", - "@typescript-eslint/parser": "^6.4.1", - "eslint": "^8.47.0", - "typedoc": "^0.24.8", - "typescript": "^5.1.6", - "vite-tsconfig-paths": "^4.2.0", - "vitest": "^0.34.3", - "webpack": "^5.88.1" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { + "dependencies": { + "@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/@babel/parser": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", - "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } + "@babel/parser": { + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==" }, - "node_modules/@cspotcode/source-map-support": { + "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dependencies": { + "requires": { "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@esbuild/android-arm": { + "@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/android-arm64": { + "@esbuild/android-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/android-x64": { + "@esbuild/android-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/darwin-arm64": { + "@esbuild/darwin-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/darwin-x64": { + "@esbuild/darwin-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/freebsd-arm64": { + "@esbuild/freebsd-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/freebsd-x64": { + "@esbuild/freebsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-arm": { + "@esbuild/linux-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-arm64": { + "@esbuild/linux-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-ia32": { + "@esbuild/linux-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-loong64": { + "@esbuild/linux-loong64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-mips64el": { + "@esbuild/linux-mips64el": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-ppc64": { + "@esbuild/linux-ppc64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-riscv64": { + "@esbuild/linux-riscv64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-s390x": { + "@esbuild/linux-s390x": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/linux-x64": { + "@esbuild/linux-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/netbsd-x64": { + "@esbuild/netbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/openbsd-x64": { + "@esbuild/openbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/sunos-x64": { + "@esbuild/sunos-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/win32-arm64": { + "@esbuild/win32-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/win32-ia32": { + "@esbuild/win32-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@esbuild/win32-x64": { + "@esbuild/win32-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } + "optional": true }, - "node_modules/@eslint-community/eslint-utils": { + "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "dependencies": { + "requires": { "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz", - "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } + "@eslint-community/regexpp": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", + "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", + "dev": true }, - "node_modules/@eslint/eslintrc": { + "@eslint/eslintrc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, - "dependencies": { + "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", @@ -455,689 +207,487 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "@eslint/js": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", + "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", "dev": true }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "@humanwhocodes/config-array": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", - "dev": true, - "dependencies": { + "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/module-importer": { + "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } + "dev": true }, - "node_modules/@humanwhocodes/object-schema": { + "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "node_modules/@jest/schemas": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", - "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, - "dependencies": { + "requires": { "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/gen-mapping": { + "@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, - "dependencies": { + "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "engines": { - "node": ">=6.0.0" - } + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" }, - "node_modules/@jridgewell/set-array": { + "@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } + "dev": true }, - "node_modules/@jridgewell/source-map": { + "@jridgewell/source-map": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, - "dependencies": { + "requires": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@jsdoc/salty": { + "@jsdoc/salty": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.5.tgz", "integrity": "sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==", - "dependencies": { + "requires": { "lodash": "^4.17.21" - }, - "engines": { - "node": ">=v12.0.0" } }, - "node_modules/@nodelib/fs.scandir": { + "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "dependencies": { + "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" } }, - "node_modules/@nodelib/fs.stat": { + "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } + "dev": true }, - "node_modules/@nodelib/fs.walk": { + "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "dependencies": { + "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" } }, - "node_modules/@sinclair/typebox": { + "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "node_modules/@tsconfig/node10": { + "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, - "node_modules/@tsconfig/node12": { + "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, - "node_modules/@tsconfig/node14": { + "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, - "node_modules/@tsconfig/node16": { + "@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, - "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "@types/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==", "dev": true }, - "node_modules/@types/chai-subset": { + "@types/chai-subset": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", "dev": true, - "dependencies": { + "requires": { "@types/chai": "*" } }, - "node_modules/@types/eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-gsF+c/0XOguWgaOgvFs+xnnRqt9GwgTvIks36WpE6ueeI4KCEHHd8K/CKHqhOqrJKsYH8m27kRzQEvWXAwXUTw==", + "@types/eslint": { + "version": "8.44.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", + "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", "dev": true, - "dependencies": { + "requires": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { + "@types/eslint-scope": { "version": "3.7.4", "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "dev": true, - "dependencies": { + "requires": { "@types/eslint": "*", "@types/estree": "*" } }, - "node_modules/@types/estree": { + "@types/estree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, - "node_modules/@types/json-schema": { + "@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, - "node_modules/@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==" + "@types/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-pTjcqY9E4nOI55Wgpz7eiI8+LzdYnw3qxXCfHyBDdPbYvbyLgWLJGh8EdPvqawwMK1Uo1794AUkkR38Fr0g+2g==" }, - "node_modules/@types/markdown-it": { + "@types/markdown-it": { "version": "12.2.3", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", - "dependencies": { + "requires": { "@types/linkify-it": "*", "@types/mdurl": "*" } }, - "node_modules/@types/mdurl": { + "@types/mdurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" }, - "node_modules/@types/node": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.0.tgz", - "integrity": "sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==" + "@types/node": { + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", + "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "@types/semver": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", "dev": true }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.1.tgz", - "integrity": "sha512-3F5PtBzUW0dYlq77Lcqo13fv+58KDwUib3BddilE8ajPJT+faGgxmI9Sw+I8ZS22BYwoir9ZhNXcLi+S+I2bkw==", + "@typescript-eslint/eslint-plugin": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", + "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", "dev": true, - "dependencies": { + "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/type-utils": "6.4.1", - "@typescript-eslint/utils": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/type-utils": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/parser": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.1.tgz", - "integrity": "sha512-610G6KHymg9V7EqOaNBMtD1GgpAmGROsmfHJPXNLCU9bfIuLrkdOygltK784F6Crboyd5tBFayPB7Sf0McrQwg==", + "@typescript-eslint/parser": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", + "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/typescript-estree": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "requires": { + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", - "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", + "@typescript-eslint/scope-manager": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", + "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "requires": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.1.tgz", - "integrity": "sha512-7ON8M8NXh73SGZ5XvIqWHjgX2f+vvaOarNliGhjrJnv1vdjG0LVIz+ToYfPirOoBi56jxAKLfsLm40+RvxVVXA==", + "@typescript-eslint/type-utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", + "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.4.1", - "@typescript-eslint/utils": "6.4.1", + "requires": { + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/utils": "6.7.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/types": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", - "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "@typescript-eslint/types": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", + "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", + "dev": true }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", - "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", + "@typescript-eslint/typescript-estree": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", + "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "requires": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.1.tgz", - "integrity": "sha512-F/6r2RieNeorU0zhqZNv89s9bDZSovv3bZQpUNOmmQK1L80/cV4KEu95YUJWi75u5PhboFoKUJBnZ4FQcoqhDw==", + "@typescript-eslint/utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", "dev": true, - "dependencies": { + "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/typescript-estree": "6.4.1", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", - "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", + "@typescript-eslint/visitor-keys": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", + "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.1", + "requires": { + "@typescript-eslint/types": "6.7.0", "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vitest/expect": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.3.tgz", - "integrity": "sha512-F8MTXZUYRBVsYL1uoIft1HHWhwDbSzwAU9Zgh8S6WFC3YgVb4AnFV2GXO3P5Em8FjEYaZtTnQYoNwwBrlOMXgg==", + "@vitest/expect": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.4.tgz", + "integrity": "sha512-XlMKX8HyYUqB8dsY8Xxrc64J2Qs9pKMt2Z8vFTL4mBWXJsg4yoALHzJfDWi8h5nkO4Zua4zjqtapQ/IluVkSnA==", "dev": true, - "dependencies": { - "@vitest/spy": "0.34.3", - "@vitest/utils": "0.34.3", + "requires": { + "@vitest/spy": "0.34.4", + "@vitest/utils": "0.34.4", "chai": "^4.3.7" - }, - "funding": { - "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.3.tgz", - "integrity": "sha512-lYNq7N3vR57VMKMPLVvmJoiN4bqwzZ1euTW+XXYH5kzr3W/+xQG3b41xJn9ChJ3AhYOSoweu974S1V3qDcFESA==", + "@vitest/runner": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.4.tgz", + "integrity": "sha512-hwwdB1StERqUls8oV8YcpmTIpVeJMe4WgYuDongVzixl5hlYLT2G8afhcdADeDeqCaAmZcSgLTLtqkjPQF7x+w==", "dev": true, - "dependencies": { - "@vitest/utils": "0.34.3", + "requires": { + "@vitest/utils": "0.34.4", "p-limit": "^4.0.0", "pathe": "^1.1.1" }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } } }, - "node_modules/@vitest/snapshot": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.3.tgz", - "integrity": "sha512-QyPaE15DQwbnIBp/yNJ8lbvXTZxS00kRly0kfFgAD5EYmCbYcA+1EEyRalc93M0gosL/xHeg3lKAClIXYpmUiQ==", + "@vitest/snapshot": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.4.tgz", + "integrity": "sha512-GCsh4coc3YUSL/o+BPUo7lHQbzpdttTxL6f4q0jRx2qVGoYz/cyTRDJHbnwks6TILi6560bVWoBpYC10PuTLHw==", "dev": true, - "dependencies": { + "requires": { "magic-string": "^0.30.1", "pathe": "^1.1.1", "pretty-format": "^29.5.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/spy": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.3.tgz", - "integrity": "sha512-N1V0RFQ6AI7CPgzBq9kzjRdPIgThC340DGjdKdPSE8r86aUSmeliTUgkTqLSgtEwWWsGfBQ+UetZWhK0BgJmkQ==", + "@vitest/spy": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.4.tgz", + "integrity": "sha512-PNU+fd7DUPgA3Ya924b1qKuQkonAW6hL7YUjkON3wmBwSTIlhOSpy04SJ0NrRsEbrXgMMj6Morh04BMf8k+w0g==", "dev": true, - "dependencies": { + "requires": { "tinyspy": "^2.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/utils": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.3.tgz", - "integrity": "sha512-kiSnzLG6m/tiT0XEl4U2H8JDBjFtwVlaE8I3QfGiMFR0QvnRDfYfdP3YvTBWM/6iJDAyaPY6yVQiCTUc7ZzTHA==", + "@vitest/utils": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.4.tgz", + "integrity": "sha512-yR2+5CHhp/K4ySY0Qtd+CAL9f5Yh1aXrKfAT42bq6CtlGPh92jIDDDSg7ydlRow1CP+dys4TrOrbELOyNInHSg==", "dev": true, - "dependencies": { + "requires": { "diff-sequences": "^29.4.3", "loupe": "^2.3.6", "pretty-format": "^29.5.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" } }, - "node_modules/@webassemblyjs/ast": { + "@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { + "@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, - "node_modules/@webassemblyjs/helper-api-error": { + "@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, - "node_modules/@webassemblyjs/helper-buffer": { + "@webassemblyjs/helper-buffer": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, - "node_modules/@webassemblyjs/helper-numbers": { + "@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, - "node_modules/@webassemblyjs/helper-wasm-section": { + "@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/wasm-gen": "1.11.6" } }, - "node_modules/@webassemblyjs/ieee754": { + "@webassemblyjs/ieee754": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, - "dependencies": { + "requires": { "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/@webassemblyjs/leb128": { + "@webassemblyjs/leb128": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, - "dependencies": { + "requires": { "@xtuc/long": "4.2.2" } }, - "node_modules/@webassemblyjs/utf8": { + "@webassemblyjs/utf8": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, - "node_modules/@webassemblyjs/wasm-edit": { + "@webassemblyjs/wasm-edit": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -1148,12 +698,12 @@ "@webassemblyjs/wast-printer": "1.11.6" } }, - "node_modules/@webassemblyjs/wasm-gen": { + "@webassemblyjs/wasm-gen": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", @@ -1161,24 +711,24 @@ "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/@webassemblyjs/wasm-opt": { + "@webassemblyjs/wasm-opt": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", "@webassemblyjs/wasm-gen": "1.11.6", "@webassemblyjs/wasm-parser": "1.11.6" } }, - "node_modules/@webassemblyjs/wasm-parser": { + "@webassemblyjs/wasm-parser": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -1187,269 +737,191 @@ "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/@webassemblyjs/wast-printer": { + "@webassemblyjs/wast-printer": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, - "dependencies": { + "requires": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, - "node_modules/@xtuc/ieee754": { + "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "dev": true }, - "node_modules/@xtuc/long": { + "@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "node_modules/acorn": { + "acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" }, - "node_modules/acorn-import-assertions": { + "acorn-import-assertions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } + "dev": true }, - "node_modules/acorn-jsx": { + "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } + "dev": true }, - "node_modules/acorn-walk": { + "acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "engines": { - "node": ">=0.4.0" - } + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, - "node_modules/ajv": { + "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "dependencies": { + "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-keywords": { + "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } + "dev": true }, - "node_modules/ansi-regex": { + "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", - "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", + "ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", "dev": true }, - "node_modules/ansi-styles": { + "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "dependencies": { + "requires": { "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arg": { + "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, - "node_modules/array-union": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/assertion-error": { + "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } + "dev": true }, - "node_modules/balanced-match": { + "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/bluebird": { + "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "node_modules/brace-expansion": { + "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "dependencies": { + "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/braces": { + "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "dependencies": { + "requires": { "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" } }, - "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "browserslist": { + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", + "requires": { + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", "update-browserslist-db": "^1.0.11" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer-from": { + "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/cac": { + "cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/callsites": { + "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } + "dev": true }, - "node_modules/caniuse-lite": { - "version": "1.0.30001513", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001513.tgz", - "integrity": "sha512-pnjGJo7SOOjAGytZZ203Em95MRM8Cr6jhCXNF/FAXTpCTRTECnqQWLpiTRqrFtdYcth8hf4WECUpkezuYsMVww==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] + "caniuse-lite": { + "version": "1.0.30001534", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz", + "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==", + "dev": true }, - "node_modules/catharsis": { + "catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dependencies": { + "requires": { "lodash": "^4.17.15" - }, - "engines": { - "node": ">= 10" } }, - "node_modules/chai": { + "chai": { "version": "4.3.8", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", "dev": true, - "dependencies": { + "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^4.1.2", @@ -1457,211 +929,154 @@ "loupe": "^2.3.1", "pathval": "^1.1.1", "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" } }, - "node_modules/chalk": { + "chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" }, - "node_modules/check-error": { + "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "engines": { - "node": "*" - } + "dev": true }, - "node_modules/chrome-trace-event": { + "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } + "dev": true }, - "node_modules/color-convert": { + "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "dependencies": { + "requires": { "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" } }, - "node_modules/color-name": { + "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/commander": { + "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/concat-map": { + "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/create-require": { + "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, - "node_modules/cross-spawn": { + "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "dependencies": { + "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" } }, - "node_modules/debug": { + "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "dependencies": { + "requires": { "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } } }, - "node_modules/deep-eql": { + "deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, - "dependencies": { + "requires": { "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" } }, - "node_modules/deep-is": { + "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/diff": { + "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "engines": { - "node": ">=0.3.1" - } + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, - "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } + "diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true }, - "node_modules/dir-glob": { + "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "dependencies": { + "requires": { "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" } }, - "node_modules/doctrine": { + "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "dependencies": { + "requires": { "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.454", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.454.tgz", - "integrity": "sha512-pmf1rbAStw8UEQ0sr2cdJtWl48ZMuPD9Sto8HVQOq9vx9j2WgDEN6lYoaqFvqEHYOmGA9oRGn7LqWI9ta0YugQ==", + "electron-to-chromium": { + "version": "1.4.520", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.520.tgz", + "integrity": "sha512-Frfus2VpYADsrh1lB3v/ft/WVFlVzOIm+Q0p7U7VqHI6qr7NWHYKe+Wif3W50n7JAFoBsWVsoU0+qDks6WQ60g==", "dev": true }, - "node_modules/enhanced-resolve": { + "enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, - "dependencies": { + "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" } }, - "node_modules/entities": { + "entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==" }, - "node_modules/es-module-lexer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", - "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", + "es-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", + "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", "dev": true }, - "node_modules/esbuild": { + "esbuild": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { + "requires": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", @@ -1686,34 +1101,28 @@ "@esbuild/win32-x64": "0.18.20" } }, - "node_modules/escalade": { + "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } + "dev": true }, - "node_modules/escape-string-regexp": { + "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" }, - "node_modules/eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "eslint": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", + "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", "dev": true, - "dependencies": { + "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/js": "8.49.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", @@ -1747,625 +1156,391 @@ "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + } } }, - "node_modules/eslint/node_modules/eslint-scope": { + "eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "dependencies": { + "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true }, - "node_modules/espree": { + "espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "dependencies": { + "requires": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" } }, - "node_modules/esquery": { + "esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "dependencies": { + "requires": { "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" } }, - "node_modules/esrecurse": { + "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "dependencies": { + "requires": { "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } + "dev": true }, - "node_modules/esutils": { + "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/events": { + "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } + "dev": true }, - "node_modules/fast-deep-equal": { + "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-glob": { + "fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, - "dependencies": { + "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" } }, - "node_modules/fast-json-stable-stringify": { + "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "node_modules/fast-levenshtein": { + "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/fastq": { + "fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, - "dependencies": { + "requires": { "reusify": "^1.0.4" } }, - "node_modules/file-entry-cache": { + "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "dependencies": { + "requires": { "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/fill-range": { + "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "dependencies": { + "requires": { "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "dependencies": { - "flatted": "^3.1.0", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "dev": true, + "requires": { + "flatted": "^3.2.7", + "keyv": "^4.5.3", "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flatted": { + "flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/fs.realpath": { + "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "optional": true }, - "node_modules/get-func-name": { + "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "engines": { - "node": "*" - } + "dev": true }, - "node_modules/glob": { + "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "dependencies": { + "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" + "requires": { + "is-glob": "^4.0.1" } }, - "node_modules/glob-to-regexp": { + "glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "node_modules/globby": { + "globals": { + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "dependencies": { + "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globrex": { + "globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, - "node_modules/graceful-fs": { + "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/graphemer": { + "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/has-flag": { + "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/ignore": { + "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } + "dev": true }, - "node_modules/import-fresh": { + "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "dependencies": { + "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" } }, - "node_modules/imurmurhash": { + "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } + "dev": true }, - "node_modules/inflight": { + "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "dependencies": { + "requires": { "once": "^1.3.0", "wrappy": "1" } }, - "node_modules/inherits": { + "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/is-extglob": { + "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/is-glob": { + "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "dependencies": { + "requires": { "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" } }, - "node_modules/is-number": { + "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } + "dev": true }, - "node_modules/is-path-inside": { + "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/isexe": { + "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/jest-worker": { + "jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, - "dependencies": { + "requires": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, - "engines": { - "node": ">= 10.13.0" + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" } }, - "node_modules/js2xmlparser": { + "js2xmlparser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "dependencies": { + "requires": { "xmlcreate": "^2.0.4" } }, - "node_modules/jsdoc": { + "jsdoc": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", - "dependencies": { + "requires": { "@babel/parser": "^7.20.15", "@jsdoc/salty": "^0.2.1", "@types/markdown-it": "^12.2.3", @@ -2381,952 +1556,709 @@ "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "underscore": "~1.13.2" - }, - "bin": { - "jsdoc": "jsdoc.js" - }, - "engines": { - "node": ">=12.0.0" } }, - "node_modules/json-parse-even-better-errors": { + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/json-schema-traverse": { + "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/json-stable-stringify-without-jsonify": { + "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/jsonc-parser": { + "jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, - "node_modules/klaw": { + "keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dependencies": { + "requires": { "graceful-fs": "^4.1.9" } }, - "node_modules/levn": { + "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "dependencies": { + "requires": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" } }, - "node_modules/linkify-it": { + "linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", - "dependencies": { + "requires": { "uc.micro": "^1.0.1" } }, - "node_modules/loader-runner": { + "loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } + "dev": true }, - "node_modules/local-pkg": { + "local-pkg": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "requires": { + "p-locate": "^5.0.0" } }, - "node_modules/lodash": { + "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash.merge": { + "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/loupe": { + "loupe": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, - "dependencies": { + "requires": { "get-func-name": "^2.0.0" } }, - "node_modules/lru-cache": { + "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "dependencies": { + "requires": { "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" } }, - "node_modules/lunr": { + "lunr": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true }, - "node_modules/magic-string": { + "magic-string": { "version": "0.30.3", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", "dev": true, - "dependencies": { + "requires": { "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" } }, - "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/make-error": { + "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, - "node_modules/markdown-it": { + "markdown-it": { "version": "12.3.2", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "dependencies": { + "requires": { "argparse": "^2.0.1", "entities": "~2.1.0", "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" } }, - "node_modules/markdown-it-anchor": { + "markdown-it-anchor": { "version": "8.6.7", "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", - "peerDependencies": { - "@types/markdown-it": "*", - "markdown-it": "*" - } - }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==" }, - "node_modules/marked": { + "marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==" }, - "node_modules/mdurl": { + "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, - "node_modules/merge-stream": { + "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "node_modules/merge2": { + "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } + "dev": true }, - "node_modules/micromatch": { + "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "dependencies": { + "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" } }, - "node_modules/mime-db": { + "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "dev": true }, - "node_modules/mime-types": { + "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, - "dependencies": { + "requires": { "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" } }, - "node_modules/minimatch": { + "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "dependencies": { + "requires": { "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" } }, - "node_modules/mkdirp": { + "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, - "node_modules/mlly": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.1.tgz", - "integrity": "sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==", + "mlly": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz", + "integrity": "sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==", "dev": true, - "dependencies": { + "requires": { "acorn": "^8.10.0", "pathe": "^1.1.1", "pkg-types": "^1.0.3", "ufo": "^1.3.0" } }, - "node_modules/ms": { + "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true }, - "node_modules/natural-compare": { + "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/neo-async": { + "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/node-releases": { + "node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, - "node_modules/once": { + "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "dependencies": { + "requires": { "wrappy": "1" } }, - "node_modules/optionator": { + "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "dependencies": { + "requires": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" } }, - "node_modules/p-limit": { + "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "dependencies": { + "requires": { "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parent-module": { + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "dependencies": { + "requires": { "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" } }, - "node_modules/path-exists": { + "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/path-is-absolute": { + "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/path-key": { + "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/path-type": { + "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/pathe": { + "pathe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", "dev": true }, - "node_modules/pathval": { + "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } + "dev": true }, - "node_modules/picocolors": { + "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/picomatch": { + "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "dev": true }, - "node_modules/pkg-types": { + "pkg-types": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", "dev": true, - "dependencies": { + "requires": { "jsonc-parser": "^3.2.0", "mlly": "^1.2.0", "pathe": "^1.1.0" } }, - "node_modules/postcss": { - "version": "8.4.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz", - "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==", + "postcss": { + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { + "requires": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" } }, - "node_modules/prelude-ls": { + "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } + "dev": true }, - "node_modules/pretty-format": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", - "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.0", + "requires": { + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, - "node_modules/punycode": { + "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } + "dev": true }, - "node_modules/queue-microtask": { + "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true }, - "node_modules/randombytes": { + "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "dependencies": { + "requires": { "safe-buffer": "^5.1.0" } }, - "node_modules/react-is": { + "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/requizzle": { + "requizzle": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", - "dependencies": { + "requires": { "lodash": "^4.17.21" } }, - "node_modules/reusify": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/rimraf": { + "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "dependencies": { + "requires": { "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rollup": { - "version": "3.28.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", - "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", + "rollup": { + "version": "3.29.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.1.tgz", + "integrity": "sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg==", "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { + "requires": { "fsevents": "~2.3.2" } }, - "node_modules/run-parallel": { + "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { + "requires": { "queue-microtask": "^1.2.2" } }, - "node_modules/safe-buffer": { + "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true }, - "node_modules/schema-utils": { + "schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, - "dependencies": { + "requires": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" } }, - "node_modules/semver": { + "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "dependencies": { + "requires": { "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, - "node_modules/serialize-javascript": { + "serialize-javascript": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, - "dependencies": { + "requires": { "randombytes": "^2.1.0" } }, - "node_modules/shebang-command": { + "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "dependencies": { + "requires": { "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" } }, - "node_modules/shebang-regex": { + "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/shiki": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", - "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", + "shiki": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz", + "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==", "dev": true, - "dependencies": { + "requires": { "ansi-sequence-parser": "^1.1.0", "jsonc-parser": "^3.2.0", "vscode-oniguruma": "^1.7.0", "vscode-textmate": "^8.0.0" } }, - "node_modules/siginfo": { + "siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, - "node_modules/slash": { + "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } + "dev": true }, - "node_modules/source-map": { + "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/source-map-js": { + "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/source-map-support": { + "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "dependencies": { + "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "node_modules/stackback": { + "stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, - "node_modules/std-env": { + "std-env": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.4.3.tgz", "integrity": "sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==", "dev": true }, - "node_modules/strip-ansi": { + "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "dependencies": { + "requires": { "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" } }, - "node_modules/strip-json-comments": { + "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, - "node_modules/strip-literal": { + "strip-literal": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", "dev": true, - "dependencies": { + "requires": { "acorn": "^8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "dependencies": { + "requires": { "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/tapable": { + "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } + "dev": true }, - "node_modules/terser": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.2.tgz", - "integrity": "sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w==", + "terser": { + "version": "5.19.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz", + "integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==", "dev": true, - "dependencies": { + "requires": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" } }, - "node_modules/terser-webpack-plugin": { + "terser-webpack-plugin": { "version": "5.3.9", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, - "dependencies": { + "requires": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", "terser": "^5.16.8" }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } } } }, - "node_modules/text-table": { + "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/tinybench": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", - "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", + "tinybench": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", + "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==", "dev": true }, - "node_modules/tinypool": { + "tinypool": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } + "dev": true }, - "node_modules/tinyspy": { + "tinyspy": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz", "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } + "dev": true }, - "node_modules/to-regex-range": { + "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "dependencies": { + "requires": { "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" } }, - "node_modules/ts-api-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", - "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } + "ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true }, - "node_modules/ts-node": { + "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dependencies": { + "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", @@ -3340,299 +2272,164 @@ "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } } }, - "node_modules/tsconfck": { + "tsconfck": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-2.1.2.tgz", "integrity": "sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==", - "dev": true, - "bin": { - "tsconfck": "bin/tsconfck.js" - }, - "engines": { - "node": "^14.13.1 || ^16 || >=18" - }, - "peerDependencies": { - "typescript": "^4.3.5 || ^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } + "dev": true }, - "node_modules/type-check": { + "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "dependencies": { + "requires": { "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" } }, - "node_modules/type-detect": { + "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } + "dev": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true }, - "node_modules/typedoc": { + "typedoc": { "version": "0.24.8", "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.8.tgz", "integrity": "sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==", "dev": true, - "dependencies": { + "requires": { "lunr": "^2.3.9", "marked": "^4.3.0", "minimatch": "^9.0.0", "shiki": "^0.14.1" }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 14.14" - }, - "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x" - } - }, - "node_modules/typedoc/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/typedoc/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, - "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } + "typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true }, - "node_modules/uc.micro": { + "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, - "node_modules/ufo": { + "ufo": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.0.tgz", "integrity": "sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==", "dev": true }, - "node_modules/underscore": { + "underscore": { "version": "1.13.6", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" }, - "node_modules/update-browserslist-db": { + "update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { + "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" } }, - "node_modules/uri-js": { + "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "dependencies": { + "requires": { "punycode": "^2.1.0" } }, - "node_modules/v8-compile-cache-lib": { + "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, - "node_modules/vite": { + "vite": { "version": "4.4.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", "dev": true, - "dependencies": { + "requires": { "esbuild": "^0.18.10", + "fsevents": "~2.3.2", "postcss": "^8.4.27", "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } } }, - "node_modules/vite-node": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.3.tgz", - "integrity": "sha512-+0TzJf1g0tYXj6tR2vEyiA42OPq68QkRZCu/ERSo2PtsDJfBpDyEfuKbRvLmZqi/CgC7SCBtyC+WjTGNMRIaig==", + "vite-node": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.4.tgz", + "integrity": "sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==", "dev": true, - "dependencies": { + "requires": { "cac": "^6.7.14", "debug": "^4.3.4", "mlly": "^1.4.0", "pathe": "^1.1.1", "picocolors": "^1.0.0", "vite": "^3.0.0 || ^4.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==", + "vite-tsconfig-paths": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.1.tgz", + "integrity": "sha512-GNUI6ZgPqT3oervkvzU+qtys83+75N/OuDaQl7HmOqFTb0pjZsuARrRipsyJhJ3enqV8beI1xhGbToR4o78nSQ==", "dev": true, - "dependencies": { + "requires": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^2.1.0" - }, - "peerDependencies": { - "vite": "*" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } } }, - "node_modules/vitest": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.3.tgz", - "integrity": "sha512-7+VA5Iw4S3USYk+qwPxHl8plCMhA5rtfwMjgoQXMT7rO5ldWcdsdo3U1QD289JgglGK4WeOzgoLTsGFu6VISyQ==", + "vitest": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.4.tgz", + "integrity": "sha512-SE/laOsB6995QlbSE6BtkpXDeVNLJc1u2LHRG/OpnN4RsRzM3GQm4nm3PQCK5OBtrsUqnhzLdnT7se3aeNGdlw==", "dev": true, - "dependencies": { + "requires": { "@types/chai": "^4.3.5", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.34.3", - "@vitest/runner": "0.34.3", - "@vitest/snapshot": "0.34.3", - "@vitest/spy": "0.34.3", - "@vitest/utils": "0.34.3", + "@vitest/expect": "0.34.4", + "@vitest/runner": "0.34.4", + "@vitest/snapshot": "0.34.4", + "@vitest/spy": "0.34.4", + "@vitest/utils": "0.34.4", "acorn": "^8.9.0", "acorn-walk": "^8.2.0", "cac": "^6.7.14", @@ -3646,87 +2443,39 @@ "strip-literal": "^1.0.1", "tinybench": "^2.5.0", "tinypool": "^0.7.0", - "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.34.3", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", + "vite-node": "0.34.4", "why-is-node-running": "^2.2.2" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@vitest/browser": "*", - "@vitest/ui": "*", - "happy-dom": "*", - "jsdom": "*", - "playwright": "*", - "safaridriver": "*", - "webdriverio": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "playwright": { - "optional": true - }, - "safaridriver": { - "optional": true - }, - "webdriverio": { - "optional": true - } } }, - "node_modules/vscode-oniguruma": { + "vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", "dev": true }, - "node_modules/vscode-textmate": { + "vscode-textmate": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", "dev": true }, - "node_modules/watchpack": { + "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, - "dependencies": { + "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" } }, - "node_modules/webpack": { - "version": "5.88.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", - "integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==", + "webpack": { + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "dev": true, - "dependencies": { + "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", "@webassemblyjs/ast": "^1.11.5", @@ -3752,98 +2501,77 @@ "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true } } }, - "node_modules/webpack-sources": { + "webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } + "dev": true }, - "node_modules/which": { + "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "dependencies": { + "requires": { "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" } }, - "node_modules/why-is-node-running": { + "why-is-node-running": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", "dev": true, - "dependencies": { + "requires": { "siginfo": "^2.0.0", "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" } }, - "node_modules/wrappy": { + "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/xmlcreate": { + "xmlcreate": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==" }, - "node_modules/yallist": { + "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/yn": { + "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "engines": { - "node": ">=6" - } + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" }, - "node_modules/yocto-queue": { + "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "dev": true } } } diff --git a/src/geometry/Direction.ts b/src/geometry/Direction.ts index c6c2cf9..f7684a0 100644 --- a/src/geometry/Direction.ts +++ b/src/geometry/Direction.ts @@ -1,4 +1,4 @@ -export const enum Direction { +export enum Direction { LeftRank = 0, UpperLeftDiagonal = 1, UpperFile = 2, @@ -7,7 +7,6 @@ export const enum Direction { BottomRightDiagonal = 5, BottomFile = 6, BottomLeftDiagonal = 7, - Last = 8 } export const enum Rotation { diff --git a/src/geometry/DirectionUtils.ts b/src/geometry/DirectionUtils.ts index e2a7d68..5c693af 100644 --- a/src/geometry/DirectionUtils.ts +++ b/src/geometry/DirectionUtils.ts @@ -1,12 +1,13 @@ import { BoardVector2d, Direction } from "@lc/geometry"; export function rotate(direction: Direction, steps: number): Direction { + const enumSize = Object.keys(Direction).length / 2; if (steps >= 0) { - return (direction + steps) % Direction.Last as Direction; + return (direction + steps) % enumSize as Direction; } else { - const notNormalizedDirection = (direction + steps) % Direction.Last; - const normalizedDirection = Direction.Last - notNormalizedDirection; + const notNormalizedDirection = (direction + steps) % enumSize; + const normalizedDirection = enumSize + notNormalizedDirection; return normalizedDirection; } } @@ -27,7 +28,7 @@ export function rotateDoubleAnticlockwise(direction: Direction): Direction { return rotate(direction, -2); } -export function fromCoords(coordinates: BoardVector2d | [number, number]): Direction { +export function fromCoordinates(coordinates: BoardVector2d | [number, number]): Direction { if (coordinates instanceof BoardVector2d) { coordinates = coordinates.toTuple(); } diff --git a/src/geometry/Vector2d.ts b/src/geometry/Vector2d.ts index 99db34a..0fde6cc 100644 --- a/src/geometry/Vector2d.ts +++ b/src/geometry/Vector2d.ts @@ -299,6 +299,17 @@ export class IntVector2d extends Vector2d { return this.createVector(this.x, this.y) } + /** + * Method creates new `IntVector2d` object from tuple. + * first element of tuple if first coordinate, second element + * is second coordinate. + * @param {[number, number]} coordinates Tuple of numbers to be used for coordinates. + * @returns New `IntVector2d` object created from `coordinates`. + */ + public static fromTuple(coordinates: [number, number]): IntVector2d { + return new IntVector2d(coordinates[0], coordinates[1]); + } + /** * Method checks if two objects are equal. * @@ -455,6 +466,17 @@ export class BoardVector2d extends IntVector2d { return this.createVector(this.x, this.y) as T; } + /** + * Method creates new `BoardVector2d` object from tuple. + * first element of tuple if first coordinate, second element + * is second coordinate. + * @param {[number, number]} coordinates Tuple of numbers to be used for coordinates. + * @returns New `BoardVector2d` object created from `coordinates`. + */ + public static fromTuple(coordinates: [number, number]): BoardVector2d { + return new BoardVector2d(coordinates[0], coordinates[1]); + } + /** * Method creates array of `BoardVector2d` objects. First element of this array is copy of calling * object. Following objects are created by adding multiples of `increment` values to calling object. diff --git a/tests/geometry/DirectionUtils.test.ts b/tests/geometry/DirectionUtils.test.ts new file mode 100644 index 0000000..0ebc21f --- /dev/null +++ b/tests/geometry/DirectionUtils.test.ts @@ -0,0 +1,67 @@ +import { BoardVector2d, Direction, DirectionUtils } from "@lc/geometry"; + +describe("DirectionUtils", () => { + test("rotate",() => { + expect(DirectionUtils.rotate(Direction.LeftRank,3)).toBe(Direction.UpperRightDiagonal); + expect(DirectionUtils.rotate(Direction.UpperFile,-3)).toBe(Direction.BottomLeftDiagonal); + expect(DirectionUtils.rotate(Direction.UpperFile, 20)).toBe(Direction.BottomFile); + }) + test("rotateClockwise",() => { + expect(DirectionUtils.rotateClockwise(Direction.LeftRank)).toBe(Direction.UpperLeftDiagonal); + }) + test("rotateAnticlockwise",() => { + expect(DirectionUtils.rotateAnticlockwise(Direction.LeftRank)).toBe(Direction.BottomLeftDiagonal); + }) + test("rotateDoubleClockwise",() => { + expect(DirectionUtils.rotateDoubleClockwise(Direction.LeftRank)).toBe(Direction.UpperFile); + }) + test("rotateDoubleAnticlockwise",() => { + expect(DirectionUtils.rotateDoubleAnticlockwise(Direction.LeftRank)).toBe(Direction.BottomFile); + }) + test("formCoordinates", () => { + const coordinates: [[number, number], Direction][] = [ + [[-1, 0], Direction.LeftRank], + [[1, 0], Direction.RightRank], + [[0, 1], Direction.UpperFile], + [[0, -1], Direction.BottomFile], + [[-1, 1], Direction.UpperLeftDiagonal], + [[1, 1], Direction.UpperRightDiagonal], + [[1, -1], Direction.BottomRightDiagonal], + [[-1, -1],Direction.BottomLeftDiagonal] + ] + for (let corresponding of coordinates) { + expect(DirectionUtils.fromCoordinates(corresponding[0])).toBe(corresponding[1]); + } + }) + test("toTuple", () => { + const coordinates: [[number, number], Direction][] = [ + [[-1, 0], Direction.LeftRank], + [[1, 0], Direction.RightRank], + [[0, 1], Direction.UpperFile], + [[0, -1], Direction.BottomFile], + [[-1, 1], Direction.UpperLeftDiagonal], + [[1, 1], Direction.UpperRightDiagonal], + [[1, -1], Direction.BottomRightDiagonal], + [[-1, -1],Direction.BottomLeftDiagonal] + ] + for (let corresponding of coordinates) { + expect(DirectionUtils.toTuple(corresponding[1])).toStrictEqual(corresponding[0]); + } + }) + test("toBoardVector2d", () => { + const coordinates: Direction[] = [ + Direction.LeftRank, + Direction.RightRank, + Direction.UpperFile, + Direction.BottomFile, + Direction.UpperLeftDiagonal, + Direction.UpperRightDiagonal, + Direction.BottomRightDiagonal, + Direction.BottomLeftDiagonal + ] + + for (let corresponding of coordinates) { + expect(DirectionUtils.toBoardVector2d(corresponding)).toStrictEqual(BoardVector2d.fromTuple(DirectionUtils.toTuple(corresponding))); + } + }) +}); \ No newline at end of file From 043f0f4e1aacc66f27979f322038bb962d11b2cb Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sat, 16 Sep 2023 22:18:54 +0200 Subject: [PATCH 21/35] Refactored vectors classes, by setting their return type to `typeof this` --- src/core/index.ts | 3 +- .../piece_generator.ts} | 10 ++- src/geometry/Vector2d.ts | 70 ++++++++++--------- src/pieces/Piece.ts | 3 - src/pieces/piece_factories/index.ts | 1 - 5 files changed, 42 insertions(+), 45 deletions(-) rename src/{pieces/piece_factories/PieceGenerator.ts => core/piece_generator.ts} (82%) delete mode 100644 src/pieces/piece_factories/index.ts diff --git a/src/core/index.ts b/src/core/index.ts index e680acf..f8f82df 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -4,4 +4,5 @@ export { CheckManager } from "./CheckManager.js"; export { PromotionManager } from "./PromotionManager.js"; export { MoveType, Move, MoveOrder } from "./move.js"; export { Tile, MovesPredictionsType } from "./Tile.js"; -export { Lasgun } from "./Lasgun.js" +export { Lasgun } from "./Lasgun.js"; +export * as Generator from "./piece_generator.js"; diff --git a/src/pieces/piece_factories/PieceGenerator.ts b/src/core/piece_generator.ts similarity index 82% rename from src/pieces/piece_factories/PieceGenerator.ts rename to src/core/piece_generator.ts index 7f9fd4d..89322ab 100644 --- a/src/pieces/piece_factories/PieceGenerator.ts +++ b/src/core/piece_generator.ts @@ -26,8 +26,7 @@ export interface PawnPieceData extends DirectedPieceData { promotionPosition: BoardVector2d } -export class PieceGenerator { - public createStandardPiece(pieceData: StandardPieceData, type: PieceType): Piece { +export function createStandardPiece(pieceData: StandardPieceData, type: PieceType): Piece { switch(type) { case PieceType.KING: return new King(pieceData.position, pieceData.playerId, pieceData.board); @@ -40,16 +39,16 @@ export class PieceGenerator { case PieceType.KNIGHT: return new Knight(pieceData.position, pieceData.playerId, pieceData.board); } - throw new Error("Unable to create this type of piece using StandardPieceFactory.") + throw new Error("Unable to create this type of piece using PieceGenerator.createStandardPiece.") } - public createMirror(pieceData: DirectedPieceData): Mirror { + export function createMirror(pieceData: DirectedPieceData): Mirror { const piece: Mirror = new Mirror(pieceData.position, pieceData.playerId, pieceData.board); piece.direction = pieceData.direction; return piece; } - public createPawn(pieceData: PawnPieceData): Pawn { + export function createPawn(pieceData: PawnPieceData): Pawn { const piece: Pawn = new Pawn(pieceData.position, pieceData.playerId, pieceData.board); piece.direction = pieceData.direction; piece.enPassantPosition = pieceData.enPassantPosition; @@ -57,4 +56,3 @@ export class PieceGenerator { return piece; } -} \ No newline at end of file diff --git a/src/geometry/Vector2d.ts b/src/geometry/Vector2d.ts index 0fde6cc..cf64883 100644 --- a/src/geometry/Vector2d.ts +++ b/src/geometry/Vector2d.ts @@ -1,6 +1,7 @@ import { Direction, DirectionUtils } from "@lc/geometry"; import { Integer } from "@lc/utils"; import { Board } from "@lc/core"; +import { Type } from "typescript"; /** * Enum that represents possible symmetry transformation @@ -32,6 +33,7 @@ export class Vector2d { * its subclasses. */ public readonly y: number; + public l = Vector2d /** * Basic constructor that allows to create new `Vector2d` object. @@ -103,7 +105,7 @@ export class Vector2d { if (!(other instanceof Vector2d)) { return false; } - return this.x == other.x && this.y == other.y; + return this.x === other.x && this.y === other.y; } /** @@ -111,8 +113,8 @@ export class Vector2d { * @param {Vector2d} other - `Vector2d` object to be added to calling object of `Vector2d`. * @returns {Vector2d} New `Vector2d` object created by addition of two `Vector2d` objects. */ - public add(other: Vector2d): T { - return this.createVector(this.x + other.x, this.y + other.y) as T; + public add(other: Vector2d): typeof this { + return this.createVector(this.x + other.x, this.y + other.y) as typeof this; } /** @@ -120,8 +122,8 @@ export class Vector2d { * @param {Vector2d} other - `Vector2d` object to be substracted from calling object of `Vector2d`. * @returns {Vector2d} New `Vector2d` object created by substraction of two `Vector2d` objects. */ - public sub(other: Vector2d): T { - return this.createVector(this.x - other.x, this.y - other.y) as T + public sub(other: Vector2d): typeof this { + return this.createVector(this.x - other.x, this.y - other.y) as typeof this; } /** @@ -139,11 +141,11 @@ export class Vector2d { * @returns {Vector2d} - New `Vector2d` object created by substraction of two `Vector2d` objects, or `Vector2d` * object and `number`. */ - public mul(other: Vector2d | number): T { + public mul(other: Vector2d | number): typeof this { if (other instanceof Vector2d) { - return this.createVector(this.x * other.x, this.y * other.y) as T; + return this.createVector(this.x * other.x, this.y * other.y) as typeof this; } - return this.createVector(this.x * other, this.y * other) as T; + return this.createVector(this.x * other, this.y * other) as typeof this; } /** * Method performs dividing operation of two `Vector2d` objects, @@ -162,7 +164,7 @@ export class Vector2d { * @returns {Vector2d} - New `Vector2d` object created by division of two `Vector2d` objects, or `Vector2d` * object and `number`. */ - public div(other: Vector2d | number): T { + public div(other: Vector2d | number): typeof this { if (other instanceof Vector2d) { if (other.x == 0) { throw new Error("First (x) coordinate of divider vector is equal to 0."); @@ -170,12 +172,12 @@ export class Vector2d { if (other.y == 0) { throw new Error("Second (y) coordinate of divider vector is equal to 0."); } - return this.createVector(this.x / other.x, this.y / other.y) as T; + return this.createVector(this.x / other.x, this.y / other.y) as typeof this; } if (other === 0) { throw new Error("Divider is equal to 0"); } - return this.createVector(this.x / other, this.y / other) as T; + return this.createVector(this.x / other, this.y / other) as typeof this; } /** * Method returns `Vector2d` object opposite to calling object. @@ -183,8 +185,8 @@ export class Vector2d { * * @returns New `Vector2d` object created by negating calling object coordinates. */ - public opposite(): T { - return this.createVector(-this.x, -this.y) as T; + public opposite(): typeof this { + return this.createVector(-this.x, -this.y) as typeof this; } /** @@ -192,8 +194,8 @@ export class Vector2d { * * @returns New `Vector2d` object that is copy of calling object. */ - public copy(): T { - return this.createVector(this.x, this.y) as T; + public copy(): typeof this { + return this.createVector(this.x, this.y) as typeof this; } /** @@ -208,14 +210,14 @@ export class Vector2d { * @param {Symmetry} symmetry - {@linkcode Symmetry} enum to be used to create new object. * @returns */ - public applySymmetry(symmetry: Symmetry): T { + public applySymmetry(symmetry: Symmetry): typeof this { switch (symmetry) { case Symmetry.Origin: return this.opposite(); case Symmetry.XAxis: - return this.createVector(this.x, -this.y) as T; + return this.createVector(this.x, -this.y) as typeof this; case Symmetry.YAxis: - return this.createVector(-this.x, this.y) as T; + return this.createVector(-this.x, this.y) as typeof this; case Symmetry.None: return this.copy(); } @@ -226,8 +228,8 @@ export class Vector2d { * * @returns New `Vector2d` object with swapped coordinates. */ - public reverseAxis(): T { - return this.createVector(this.y, this.x) as T; + public reverseAxis(): typeof this { + return this.createVector(this.y, this.x) as typeof this; } /** @@ -246,7 +248,7 @@ export class Vector2d { * * @returns `Vector2d` object that is {@link https://en.wikipedia.org/wiki/Unit_vector unit vector}. */ - public createUnitVector(): T { + public createUnitVector(): typeof this { return this.div(this.getLength()); } @@ -286,8 +288,8 @@ export class IntVector2d extends Vector2d { * @param {number} y - `number` that is ment to be second coordinate. * @returns {IntVector2d} New `IntVector2d` object created with given coordinates. */ - protected createVector(x: number, y: number): T { - return new IntVector2d(x, y) as unknown as T; + protected createVector(x: number, y: number): IntVector2d { + return new IntVector2d(x, y); } /** @@ -295,8 +297,8 @@ export class IntVector2d extends Vector2d { * * @returns New `IntVector2d` object that is copy of calling object. */ - public copy(): T { - return this.createVector(this.x, this.y) + public copy(): typeof this { + return this.createVector(this.x, this.y) as typeof this } /** @@ -342,17 +344,17 @@ export class IntVector2d extends Vector2d { * as more important, when absolute value of coordinates is equal. * @returns `IntVector2d` object that is {@link https://en.wikipedia.org/wiki/Unit_vector unit vector}. */ - public createUnitVector(prioritizeAxisY?: boolean): T { + public createUnitVector(prioritizeAxisY?: boolean): typeof this { if (Math.abs(this.x) === Math.abs(this.y)) { if (prioritizeAxisY !== undefined || prioritizeAxisY === true) { - return this.createVector(0, Math.sign(this.y)); + return this.createVector(0, Math.sign(this.y)) as typeof this; } - return this.createVector(Math.sign(this.x), 0); + return this.createVector(Math.sign(this.x), 0) as typeof this; } if (Math.abs(this.x) > Math.abs(this.y)) { - return this.createVector(Math.sign(this.x), 0); + return this.createVector(Math.sign(this.x), 0) as typeof this; } - return this.createVector(0, Math.sign(this.y)); + return this.createVector(0, Math.sign(this.y)) as typeof this; } } @@ -374,8 +376,8 @@ export class BoardVector2d extends IntVector2d { * @param {number} y - `number` that is ment to be second coordinate. * @returns {IntVector2d} New `BoardVector2d` object created with given coordinates. */ - protected createVector(x: number, y: number): T { - return new BoardVector2d(x, y) as unknown as T; + protected createVector(x: number, y: number): BoardVector2d { + return new BoardVector2d(x, y); } /** @@ -462,8 +464,8 @@ export class BoardVector2d extends IntVector2d { * * @returns New `BoardVector2d` object that is copy of calling object. */ - public copy(): T { - return this.createVector(this.x, this.y) as T; + public copy(): typeof this { + return this.createVector(this.x, this.y) as typeof this; } /** diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index e52e3b3..ab88f1c 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -28,8 +28,6 @@ export abstract class Piece { public readonly defendsKingsFrom: [Piece | null, Piece | null]; public position: BoardVector2d; protected moveCounter: number; - - public constructor(position: BoardVector2d, playerId: number, board: Board) { this.initialPosition = position; this.position = position; @@ -37,7 +35,6 @@ export abstract class Piece { this.moveCounter = 0; this.board = board; this.defendsKingsFrom = [null, null]; - this.initType(); } diff --git a/src/pieces/piece_factories/index.ts b/src/pieces/piece_factories/index.ts deleted file mode 100644 index 48549a1..0000000 --- a/src/pieces/piece_factories/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { PieceGenerator } from "./PieceGenerator.js" \ No newline at end of file From 215b8ba46eba0ebd3c76a266f989e6802cf1bea4 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sat, 16 Sep 2023 23:32:17 +0200 Subject: [PATCH 22/35] Added tests for`Generator`. --- tests/geometry/PieceGenerator.test.ts | 60 +++++++++++++++++++++++++++ tests/geometry/vector.test.ts | 7 ---- 2 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 tests/geometry/PieceGenerator.test.ts diff --git a/tests/geometry/PieceGenerator.test.ts b/tests/geometry/PieceGenerator.test.ts new file mode 100644 index 0000000..0c63123 --- /dev/null +++ b/tests/geometry/PieceGenerator.test.ts @@ -0,0 +1,60 @@ +import { Board, Generator } from "@lc/core" +import { BoardVector2d, Direction } from "@lc/geometry"; +import { Bishop, King, Knight, Mirror, Pawn, Piece, Queen, Rook } from "@lc/pieces"; +import { PieceType } from "@lc/pieces"; + + + + +describe("PieceGenerator", () => { + const board: Board = new Board(8, 8); + + + test("createStandardPiece", () => { + let data: Generator.StandardPieceData = { + position: new BoardVector2d(1, 1), + playerId: 0, + board: board, + } + const constructors = [King, Queen, Bishop, Rook, Knight]; + let enumValues: PieceType[] = [PieceType.KING, PieceType.QUEEN, PieceType.BISHOP, PieceType.ROOK, PieceType.KNIGHT]; + for(let zip of constructors.map((e, i) => {return [e, enumValues[i]] as [any, PieceType]})) { + expect(Generator.createStandardPiece(data, zip[1])).toStrictEqual(new zip[0](data.position,data.playerId,data.board)); + } + enumValues = [PieceType.MIRROR, PieceType.PAWN]; + for(let single of enumValues) { + expect(() => Generator.createStandardPiece(data, single)).toThrowError(Error); + } + }) + + + + test("createMirror", () => { + let data: Generator.DirectedPieceData = { + position: new BoardVector2d(1, 1), + playerId: 0, + board: board, + direction: Direction.BottomLeftDiagonal + } + const mirror: Mirror = new Mirror(data.position,data.playerId,data.board); + mirror.direction = data.direction; + expect(Generator.createMirror(data)).toStrictEqual(mirror); + }) + + test("createPawn", () => { + let data: Generator.PawnPieceData = { + position: new BoardVector2d(1, 1), + playerId: 0, + board: board, + direction: Direction.UpperFile, + enPassantPosition: new BoardVector2d(2, 3), + promotionPosition: new BoardVector2d(5, 5) + } + const pawn: Pawn = new Pawn(data.position,data.playerId,data.board); + pawn.direction = data.direction; + pawn.enPassantPosition = data.enPassantPosition; + pawn.promotionPosition = data.promotionPosition + expect(Generator.createPawn(data)).toStrictEqual(pawn); + }) +} +) \ No newline at end of file diff --git a/tests/geometry/vector.test.ts b/tests/geometry/vector.test.ts index ac2dd8b..d5931ac 100644 --- a/tests/geometry/vector.test.ts +++ b/tests/geometry/vector.test.ts @@ -121,13 +121,6 @@ describe("BoardVector2d", () => { }); test("Getting moves", () => { - // vi.mock('@lc/core', () => { - // const Board = vi.fn(); - // Board.prototype.width = 8; - // Board.prototype.height = 8; - // return {Board}; - // }) - // const board: Board = new Board(); const board: Board = new Board(8,8) let vector: BoardVector2d = new BoardVector2d(7,7); expect(vector.getDirectedMoveFromTuple([1,1],board)).toStrictEqual([new BoardVector2d(7,7)]); From a55fe098063a30c0f482b268fcecf4023773ed4d Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 17 Sep 2023 16:12:27 +0200 Subject: [PATCH 23/35] Added tests for `Integer` --- src/utils/int.ts | 2 +- .../{geometry => core}/PieceGenerator.test.ts | 5 +---- tests/utils/int.test.ts | 21 +++++++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) rename tests/{geometry => core}/PieceGenerator.test.ts (99%) create mode 100644 tests/utils/int.test.ts diff --git a/src/utils/int.ts b/src/utils/int.ts index 9229a2a..75a03ee 100644 --- a/src/utils/int.ts +++ b/src/utils/int.ts @@ -1,7 +1,7 @@ /** * Module containing functions connected that facilates - * simulation numbers of integer type. + * simulation of numbers of integer type. */ /** diff --git a/tests/geometry/PieceGenerator.test.ts b/tests/core/PieceGenerator.test.ts similarity index 99% rename from tests/geometry/PieceGenerator.test.ts rename to tests/core/PieceGenerator.test.ts index 0c63123..b6f9a34 100644 --- a/tests/geometry/PieceGenerator.test.ts +++ b/tests/core/PieceGenerator.test.ts @@ -9,7 +9,6 @@ import { PieceType } from "@lc/pieces"; describe("PieceGenerator", () => { const board: Board = new Board(8, 8); - test("createStandardPiece", () => { let data: Generator.StandardPieceData = { position: new BoardVector2d(1, 1), @@ -25,10 +24,8 @@ describe("PieceGenerator", () => { for(let single of enumValues) { expect(() => Generator.createStandardPiece(data, single)).toThrowError(Error); } - }) + }) - - test("createMirror", () => { let data: Generator.DirectedPieceData = { position: new BoardVector2d(1, 1), diff --git a/tests/utils/int.test.ts b/tests/utils/int.test.ts new file mode 100644 index 0000000..4bbd397 --- /dev/null +++ b/tests/utils/int.test.ts @@ -0,0 +1,21 @@ +import { Integer } from "@lc/utils" + +describe("Integer", () => { + test("create", () => { + expect(Integer.create(2)).toBe(2); + expect(Integer.create(2.2)).toBe(2); + expect(Integer.create(2.9)).toBe(2); + expect(Integer.create(-2.3)).toBe(-2); + }) + + test("toInt", () => { + expect(Integer.toInt("23")).toBe(23); + expect(Integer.toInt("23.534")).toBe(23); + }) + + test("checkIsInt", () => { + expect(Integer.checkIsInt(1.2)).toBe(false); + expect(Integer.checkIsInt(2)).toBe(true); + }) + +}) \ No newline at end of file From 06f8559780a8de04ac5e03adc7edd271c114f381 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 17 Sep 2023 18:00:34 +0200 Subject: [PATCH 24/35] Added tests for`Tile` class. --- src/core/index.ts | 1 + src/utils/int.ts | 4 ++++ tests/core/Tile.test.ts | 48 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 tests/core/Tile.test.ts diff --git a/src/core/index.ts b/src/core/index.ts index f8f82df..4b10aa5 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -6,3 +6,4 @@ export { MoveType, Move, MoveOrder } from "./move.js"; export { Tile, MovesPredictionsType } from "./Tile.js"; export { Lasgun } from "./Lasgun.js"; export * as Generator from "./piece_generator.js"; +export { Player } from "./Player.js"; \ No newline at end of file diff --git a/src/utils/int.ts b/src/utils/int.ts index 75a03ee..ea49130 100644 --- a/src/utils/int.ts +++ b/src/utils/int.ts @@ -4,6 +4,10 @@ * simulation of numbers of integer type. */ +import { Board } from "core/Board.js"; +import { BoardVector2d } from "geometry/Vector2d.js"; +import { King } from "pieces/King.js"; + /** * Function that creates `number` from any number. * diff --git a/tests/core/Tile.test.ts b/tests/core/Tile.test.ts new file mode 100644 index 0000000..d550811 --- /dev/null +++ b/tests/core/Tile.test.ts @@ -0,0 +1,48 @@ +import { Board, Generator, MovesPredictionsType, Tile } from "@lc/core" +import { Player } from "@lc/core" +import { BoardVector2d } from "geometry/Vector2d.js" +import { King, PieceType, Queen } from "@lc/pieces" + +describe("Tile", () => { + let board: Board = new Board(8, 8); + + let data: Generator.StandardPieceData = { + position: new BoardVector2d(2, 2), + playerId: Player.White, + board: board + } + let piece1: King = Generator.createStandardPiece(data, PieceType.KING) as King; + + data.playerId = Player.Black + let piece2: Queen = Generator.createStandardPiece(data, PieceType.QUEEN) as Queen; + + let tile = new Tile(new BoardVector2d(2,2)); + + test("addPieceMovesToTile", () => { + tile.addPieceMovesToTile(piece1,MovesPredictionsType.Illegal); + expect(tile.checkIfPieceMovesInTile(piece1, MovesPredictionsType.Illegal)).toBe(true); + expect(tile.checkIfPieceMovesInTile(piece1, MovesPredictionsType.Legal)).toBe(false); + }) + + test("removePieceMovesFromTile", () => { + tile.addPieceMovesToTile(piece2, MovesPredictionsType.Legal); + tile.removePieceMovesFromTile(piece1, MovesPredictionsType.Illegal); + expect(tile.checkIfPieceMovesInTile(piece1, MovesPredictionsType.Illegal)).toBe(false); + expect(tile.checkIfPieceMovesInTile(piece2, MovesPredictionsType.Legal)).toBe(true); + }) + + test("isPieceMovesEmpty", () => { + expect(tile.isPieceMovesEmpty(piece2.playerId, MovesPredictionsType.Legal)).toBe(false); + expect(tile.isPieceMovesEmpty(piece2.playerId, MovesPredictionsType.Illegal)).toBe(true); + }) + + test("getPieceMovesOfTile", () => { + expect(tile.getPieceMovesOfTile(piece2.playerId, MovesPredictionsType.Illegal| MovesPredictionsType.Legal).size).toBe(1) + }) + + test("clearAllPredictions", () => { + tile.addPieceMovesToTile(piece1,MovesPredictionsType.Illegal); + tile.clearAllPredictions(); + expect(tile.getPieceMovesOfTile(piece1.playerId, MovesPredictionsType.Illegal | MovesPredictionsType.Legal).size).toBe(0); + }) +}) \ No newline at end of file From 73d0ddceab09aa3cb23f5f5b6436de0ddd9a2f8c Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Tue, 19 Sep 2023 17:22:39 +0200 Subject: [PATCH 25/35] Added `isMoveCommandLegal` in `Board` --- src/core/Board.ts | 66 ++++++++-------------- src/core/index.ts | 2 +- src/core/move.ts | 2 +- src/game.ts | 4 +- src/pieces/DirectedPiece.ts | 2 +- src/pieces/King.ts | 8 ++- src/pieces/Knight.ts | 2 +- src/pieces/LongRangePiece.ts | 3 - src/pieces/Pawn.ts | 20 +++++-- src/pieces/Piece.ts | 31 +++++++++- src/pieces/index.ts | 2 +- src/pieces/movements/CloseRangeMovement.ts | 2 +- src/pieces/movements/LongRangeMovement.ts | 2 +- src/pieces/movements/PieceMovement.ts | 28 --------- src/pieces/movements/index.ts | 1 - src/utils/int.ts | 4 -- 16 files changed, 80 insertions(+), 99 deletions(-) delete mode 100644 src/pieces/LongRangePiece.ts delete mode 100644 src/pieces/movements/PieceMovement.ts diff --git a/src/core/Board.ts b/src/core/Board.ts index 599d26a..6baaf49 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -1,15 +1,15 @@ import { CheckManager, PromotionManager, - Move, - MoveOrder, - MoveType + MoveType, + Player } from "@lc/core"; import { BoardVector2d, DirectionUtils, Rotation, Symmetry } from "@lc/geometry"; import { Pawn, Piece, PieceType } from "@lc/pieces"; import { IllegalMoveError, Syntax } from "@lc/utils"; import { Lasgun } from "@lc/core"; +import { MoveCommand } from "@lc/core"; export const enum CaptureOptions { @@ -152,51 +152,31 @@ export class Board { return this.piecesOfType.get(pieceType)![playerId]; } - private getSpecificMove(move: MoveOrder, playerId: number): Partial { + private isMoveCommandLegal(move: MoveCommand, playerId: Player): boolean { let pieceToMove: Piece | null = this.getPiece(move.origin); + return !( + pieceToMove === null || + (move.destination !== null && move.rotation !== null) || + (move.rotation === null && move.destination === null) || + (move.destination !== null && move.rotation !== null) || + (move.rangedCapture === true && move.rotation !== null) || + (move.fireLaser === true && !this.lasguns[playerId].isLoaded()) || + !pieceToMove.isSameColor(playerId) || + (pieceToMove.type !== PieceType.KNIGHT && move.rangedCapture === true) || + (pieceToMove.type !== PieceType.MIRROR && move.rotation !== null) + ) + } - if (pieceToMove === null) { - throw new IllegalMoveError("There is no piece on origin postion."); - } - - if (move.destination !== null && move.rotation !== null) { - throw new IllegalMoveError("Unable to roatate and move piece at once."); - } - - if (move.rotation === null && move.destination === null) { - throw new IllegalMoveError("Piece have to either rotate or move."); - } - - if (move.destination !== null && move.rotation !== null) { - throw new IllegalMoveError("Unable to roatate and move piece at once."); - } - - if (move.rangedCapture === true && move.rotation !== null) { - throw new IllegalMoveError("Piece cannot rotate and range capture a piece in one move."); - } - - if (move.fireLaser === true && !this.lasguns[playerId].isLoaded()) { - throw new IllegalMoveError("Lasgun is not loaded yet."); - } - - if (pieceToMove === null) { - throw new IllegalMoveError("There is no piece that has this position."); + private getSpecificMove(move: MoveCommand, playerId: number): Partial { + if (!this.isMoveCommandLegal(move, playerId)) { + throw new IllegalMoveError(`This MoveCommand is illegal with playerId equal to ${playerId}`); } - if (!pieceToMove.isSameColor(playerId)) { - throw new IllegalMoveError("Piece standing on origin position is enemy's piece."); - } - if (pieceToMove.type !== PieceType.KNIGHT && move.rangedCapture === true) { - throw new IllegalMoveError("Only knight can capture without moving."); - } + let pieceToMove: Piece = this.getPiece(move.origin)!; - if (pieceToMove.type !== PieceType.MIRROR && move.rotation !== null) { - throw new IllegalMoveError("Only mirror can rotate."); - } - if (move.rangedCapture === true) { for (let predictedMove of pieceToMove.movement.legalMoves) { - if ((predictedMove.moveType! & MoveType.RangedCapture) === MoveType.RangedCapture && move.destination === predictedMove.destination) { + if (Syntax.inAlternative(predictedMove.moveType!, MoveType.RangedCapture) && move.destination === predictedMove.destination) { return predictedMove; } } @@ -221,7 +201,7 @@ export class Board { throw new IllegalMoveError("Unable to perform such move."); } - private buildMove(piece: Piece, pieceMove: Partial, moveOrder: MoveOrder, promotedTo?: PieceType): Move { + private buildMove(piece: Piece, pieceMove: Partial, moveOrder: MoveCommand, promotedTo?: PieceType): Move { const ultimateMove: Move = { destination: pieceMove.destination ?? null, moveType: pieceMove.moveType!, @@ -279,7 +259,7 @@ export class Board { //TODO Laser Fields and other Move Types } - public move(move: MoveOrder, playerId: number, promotionTo?: PieceType): void { + public move(move: MoveCommand, playerId: number, promotionTo?: PieceType): void { const moveFromPiece: Partial = this.getSpecificMove(move, playerId); if (Syntax.inAlternative(moveFromPiece.moveType!, MoveType.Promotion) && promotionTo === undefined) { diff --git a/src/core/index.ts b/src/core/index.ts index 4b10aa5..8d8251d 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -2,7 +2,7 @@ export { Game } from "../game.js"; export { Board, CaptureOptions } from "./Board.js"; export { CheckManager } from "./CheckManager.js"; export { PromotionManager } from "./PromotionManager.js"; -export { MoveType, Move, MoveOrder } from "./move.js"; +export { MoveType, Move, MoveCommand } from "./move.js"; export { Tile, MovesPredictionsType } from "./Tile.js"; export { Lasgun } from "./Lasgun.js"; export * as Generator from "./piece_generator.js"; diff --git a/src/core/move.ts b/src/core/move.ts index f9b4206..1dafb0b 100644 --- a/src/core/move.ts +++ b/src/core/move.ts @@ -32,7 +32,7 @@ export interface Move { laserCaptures: Set } -export interface MoveOrder { +export interface MoveCommand { origin: BoardVector2d, destination: BoardVector2d | null, fireLaser: boolean, diff --git a/src/game.ts b/src/game.ts index deb7050..ff91624 100644 --- a/src/game.ts +++ b/src/game.ts @@ -1,4 +1,4 @@ -import { Board, MoveOrder } from "@lc/core"; +import { Board, MoveCommand } from "@lc/core"; export class Game { private _currentPlayer: number; @@ -27,7 +27,7 @@ export class Game { return (playerId + 1) % 2; } - public move(move: MoveOrder): void { + public move(move: MoveCommand): void { this.board.move(move, this._currentPlayer); this._currentPlayer = Game.getEnemyId(this._currentPlayer); } diff --git a/src/pieces/DirectedPiece.ts b/src/pieces/DirectedPiece.ts index 1a79bbb..7dee90d 100644 --- a/src/pieces/DirectedPiece.ts +++ b/src/pieces/DirectedPiece.ts @@ -2,7 +2,7 @@ import { Direction } from "@lc/geometry"; import { Piece } from "@lc/pieces"; export abstract class DirectedPiece extends Piece { - protected _direction?: Direction; + protected _direction!: Direction; public get direction(): Direction | undefined { if (this._direction === undefined) { diff --git a/src/pieces/King.ts b/src/pieces/King.ts index 15ef42b..820d106 100644 --- a/src/pieces/King.ts +++ b/src/pieces/King.ts @@ -14,11 +14,11 @@ export class King extends Piece { this._movement = new KingMovement(this, this.board); } - public set kingRook(rook: Piece) { + public set kingRook(rook: Piece | undefined) { this._kingRook = this.kingRook; } - public set queenRook(rook: Piece) { + public set queenRook(rook: Piece | undefined) { this._queenRook = this.kingRook; } @@ -47,6 +47,10 @@ export class KingMovement extends CloseRangeMovement { return false; } + if (potentialRook === undefined) { + return false; + } + if ( potentialRook.type === PieceType.ROOK && !potentialRook.wasMoved() diff --git a/src/pieces/Knight.ts b/src/pieces/Knight.ts index dc1bd2a..f195758 100644 --- a/src/pieces/Knight.ts +++ b/src/pieces/Knight.ts @@ -1,7 +1,7 @@ import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; import { BoardVector2d, Symmetry } from "@lc/geometry"; import { Piece, PieceType } from "@lc/pieces"; -import { PieceMovement } from "@lc/piece-movements"; +import { PieceMovement } from "@lc/pieces"; export class Knight extends Piece { protected override initType(): void { diff --git a/src/pieces/LongRangePiece.ts b/src/pieces/LongRangePiece.ts deleted file mode 100644 index f4bbf1b..0000000 --- a/src/pieces/LongRangePiece.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Piece } from "@lc/pieces"; - -abstract class LongRangePiece extends Piece { } diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index 2da571d..90f2ab6 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -1,7 +1,7 @@ import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; import { BoardVector2d, Direction, DirectionUtils } from "@lc/geometry"; import { DirectedPiece, PieceType, Piece } from "@lc/pieces"; -import { PieceMovement } from "@lc/piece-movements"; +import { PieceMovement } from "@lc/pieces"; export class Pawn extends DirectedPiece { private _enPassantPosition?: BoardVector2d; @@ -19,10 +19,6 @@ export class Pawn extends DirectedPiece { super._direction = direction; } - public get direction(): Direction | undefined { - return this._direction; - } - public set enPassantPosition(position: BoardVector2d) { this._enPassantPosition = position; } @@ -31,7 +27,19 @@ export class Pawn extends DirectedPiece { this._promotionPosition = position; } - + public get enPassantPosition(): BoardVector2d { + if (this.enPassantPosition === undefined){ + throw new Error("enPassantPosition is not initialised."); + } + return this._enPassantPosition!; + } + + public get promotionPosition(): BoardVector2d { + if (this.promotionPosition === undefined){ + throw new Error("promotionPosition is not initialised."); + } + return this._promotionPosition!; + } public isOnEnPassantPosition(): boolean { return this._enPassantPosition === this.position; diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index ab88f1c..8a5c6be 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -1,6 +1,5 @@ import { Board, Move } from "@lc/core"; import { BoardVector2d } from "@lc/geometry"; -import { PieceMovement } from "@lc/piece-movements"; export enum PieceType { @@ -28,6 +27,7 @@ export abstract class Piece { public readonly defendsKingsFrom: [Piece | null, Piece | null]; public position: BoardVector2d; protected moveCounter: number; + public constructor(position: BoardVector2d, playerId: number, board: Board) { this.initialPosition = position; this.position = position; @@ -42,14 +42,14 @@ export abstract class Piece { public get type(): PieceType { if (!this._type) { - throw new Error("Piece type is not initialised"); + throw new Error("Piece type is not initialised."); } return this._type; } public get movement(): PieceMovement { if (!this._movement) { - throw new Error("Piece movement is not initialised"); + throw new Error("Piece movement is not initialised."); } return this._movement; } @@ -86,3 +86,28 @@ export abstract class Piece { this.moveCounter++; } } + +export abstract class PieceMovement { + protected board: Board; + protected piece: Piece; + public illegalMoves: Partial[]; + public legalMoves: Partial[]; + + public constructor(piece: Piece, board: Board) { + this.piece = piece; + this.board = board; + this.legalMoves = []; + this.illegalMoves = []; + } + + protected clearMoves(): void { + this.legalMoves.length = 0; + this.illegalMoves.length = 0; + } + + protected preUpdateMoves(): void { + this.clearMoves(); + } + + protected abstract updateMoves(): void; +} diff --git a/src/pieces/index.ts b/src/pieces/index.ts index c62618b..b67252d 100644 --- a/src/pieces/index.ts +++ b/src/pieces/index.ts @@ -1,4 +1,4 @@ -export { Piece, PieceType, PieceOptions } from "./Piece.js"; +export { Piece, PieceType, PieceOptions, PieceMovement } from "./Piece.js"; export { DirectedPiece } from "./DirectedPiece.js"; export { King } from "./King.js"; export { Queen } from "./Queen.js"; diff --git a/src/pieces/movements/CloseRangeMovement.ts b/src/pieces/movements/CloseRangeMovement.ts index d2bbe3f..906e72e 100644 --- a/src/pieces/movements/CloseRangeMovement.ts +++ b/src/pieces/movements/CloseRangeMovement.ts @@ -1,7 +1,7 @@ import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; import { BoardVector2d } from "@lc/geometry"; import { Piece } from "@lc/pieces"; -import { PieceMovement } from "@lc/piece-movements"; +import { PieceMovement } from "@lc/pieces"; export class CloseRangeMovement extends PieceMovement { // This method sets all around moves as capturableMoves. diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index 2746f00..6291e8d 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -1,7 +1,7 @@ import { Board, CaptureOptions, Move, MoveType } from "@lc/core"; import { BoardVector2d, Direction, DirectionUtils } from "@lc/geometry"; import { Piece } from "@lc/pieces"; -import { PieceMovement } from "@lc/piece-movements"; +import { PieceMovement } from "@lc/pieces"; import { Syntax } from "@lc/utils"; export class LongRangeMovement extends PieceMovement { diff --git a/src/pieces/movements/PieceMovement.ts b/src/pieces/movements/PieceMovement.ts deleted file mode 100644 index dad843b..0000000 --- a/src/pieces/movements/PieceMovement.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Board, Move } from "@lc/core"; -import { Piece } from "@lc/pieces"; - - -export abstract class PieceMovement { - protected board: Board; - protected piece: Piece; - public illegalMoves: Partial[]; - public legalMoves: Partial[]; - - public constructor(piece: Piece, board: Board) { - this.piece = piece; - this.board = board; - this.legalMoves = []; - this.illegalMoves = []; - } - - protected clearMoves(): void { - this.legalMoves.length = 0; - this.illegalMoves.length = 0; - } - - protected preUpdateMoves(): void { - this.clearMoves(); - } - - protected abstract updateMoves(): void; -} diff --git a/src/pieces/movements/index.ts b/src/pieces/movements/index.ts index 5900a97..246f484 100644 --- a/src/pieces/movements/index.ts +++ b/src/pieces/movements/index.ts @@ -1,3 +1,2 @@ -export { PieceMovement } from "./PieceMovement.js"; export { CloseRangeMovement } from "./CloseRangeMovement.js"; export { LongRangeMovement } from "./LongRangeMovement.js"; diff --git a/src/utils/int.ts b/src/utils/int.ts index ea49130..75a03ee 100644 --- a/src/utils/int.ts +++ b/src/utils/int.ts @@ -4,10 +4,6 @@ * simulation of numbers of integer type. */ -import { Board } from "core/Board.js"; -import { BoardVector2d } from "geometry/Vector2d.js"; -import { King } from "pieces/King.js"; - /** * Function that creates `number` from any number. * From d1e18b3941db54df3e5ceac24986295e7c67b746 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Tue, 19 Sep 2023 18:16:34 +0200 Subject: [PATCH 26/35] Added basic test for `Knight`, covering abstract class `Piece` methods. --- src/core/Board.ts | 1 + src/pieces/Piece.ts | 25 +++++++++------ src/pieces/index.ts | 8 ++--- tests/pieces/Knight.test.ts | 64 +++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 tests/pieces/Knight.test.ts diff --git a/src/core/Board.ts b/src/core/Board.ts index 6baaf49..6527372 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -69,6 +69,7 @@ export class Board { public changePosition(newPosition: BoardVector2d, piece: Piece) { this.removePiece(piece); this.tiles.set(newPosition, piece); + piece.position = newPosition; } public getPiece(position: BoardVector2d): Piece | null { diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index 8a5c6be..616d452 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -54,18 +54,22 @@ export abstract class Piece { return this._movement; } - public equals(other: unknown): boolean { - if (!(other instanceof Piece)) { - return false; - } - return this.initialPosition === other.initialPosition - && this.position === other.position - && this.playerId === other.playerId - && this.moveCounter === other.playerId - && this._movement === other.movement - && this.type === other.type + public get moveCount(): number { + return this.moveCounter; } + // public equals(other: unknown): boolean { + // if (!(other instanceof Piece)) { + // return false; + // } + // return this.initialPosition === other.initialPosition + // && this.position === other.position + // && this.playerId === other.playerId + // && this.moveCounter === other.playerId + // && this._movement === other.movement + // && this.type === other.type + // } + public toString(): string { return this.type.valueOf(); } @@ -85,6 +89,7 @@ export abstract class Piece { this.position = move.destination!.copy(); this.moveCounter++; } + } export abstract class PieceMovement { diff --git a/src/pieces/index.ts b/src/pieces/index.ts index b67252d..8581510 100644 --- a/src/pieces/index.ts +++ b/src/pieces/index.ts @@ -1,9 +1,9 @@ export { Piece, PieceType, PieceOptions, PieceMovement } from "./Piece.js"; export { DirectedPiece } from "./DirectedPiece.js"; -export { King } from "./King.js"; +export { King, KingMovement } from "./King.js"; export { Queen } from "./Queen.js"; export { Rook } from "./Rook.js"; export { Bishop } from "./Bishop.js"; -export { Knight } from "./Knight.js"; -export { Pawn } from "./Pawn.js"; -export { Mirror } from "./Mirror.js" +export { Knight, KnightMovement } from "./Knight.js"; +export { Pawn, PawnMovement } from "./Pawn.js"; +export { Mirror, MirrorMovement } from "./Mirror.js" diff --git a/tests/pieces/Knight.test.ts b/tests/pieces/Knight.test.ts new file mode 100644 index 0000000..82a103a --- /dev/null +++ b/tests/pieces/Knight.test.ts @@ -0,0 +1,64 @@ +import { Board, Generator, Move, Player } from "@lc/core" +import { BoardVector2d } from "@lc/geometry" +import { KnightMovement } from "@lc/pieces"; +import { PieceType } from "@lc/pieces"; + +describe("Knight", () => { + const board: Board = new Board(8, 8); + const data: Generator.StandardPieceData = { + position: new BoardVector2d(4, 0), + playerId: Player.White, + board: board + } + + const knigth1 = Generator.createStandardPiece(data, PieceType.KNIGHT); + // const knigth2 = Generator.createStandardPiece(data, PieceType.KNIGHT); + + test("type", () => { + expect(knigth1.type).toBe(PieceType.KNIGHT); + }) + + test("movement", () => { + expect(knigth1.movement).toBeInstanceOf(KnightMovement); + }) + + test("toString", () => { + expect(knigth1.toString()).toBe("N"); + }) + + test("wasMoved", () => { + expect(knigth1.wasMoved()).toBeFalsy(); + + let move: Move = { + destination: new BoardVector2d(2, 2) + } as Move; + knigth1.move(move); + + expect(knigth1.wasMoved()).toBeTruthy(); + }) + + test("isSameColor", () => { + expect(knigth1.isSameColor(Player.Black)).toBeFalsy(); + expect(knigth1.isSameColor(Player.White)).toBeTruthy(); + + const knigth2 = Generator.createStandardPiece(data, PieceType.KNIGHT); + data.playerId = Player.Black; + const knigth3 = Generator.createStandardPiece(data, PieceType.KNIGHT); + + expect(knigth1.isSameColor(knigth2)).toBeTruthy(); + expect(knigth1.isSameColor(knigth3)).toBeFalsy(); + }) + + test("move", () => { + let move: Move = { + destination: new BoardVector2d(5, 5) + } as Move; + knigth1.move(move); + + expect(knigth1.position).toStrictEqual(new BoardVector2d(5, 5)); + expect(knigth1.moveCount).toStrictEqual(1); + }) + +}) + + From 968818ac7708af67be3d6dcead4eefd157c82228 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Fri, 22 Sep 2023 14:43:13 +0200 Subject: [PATCH 27/35] Finished tests for `Knight`, created tests for `Mirror` --- package-lock.json | 3814 +++++++++++++++++++- src/core/Board.ts | 33 +- src/core/Tile.ts | 2 +- src/core/move.ts | 5 +- src/geometry/DirectionUtils.ts | 8 +- src/pieces/King.ts | 2 +- src/pieces/Knight.ts | 24 +- src/pieces/Mirror.ts | 10 +- src/pieces/Pawn.ts | 2 +- src/pieces/Piece.ts | 8 +- src/pieces/movements/CloseRangeMovement.ts | 2 +- src/pieces/movements/LongRangeMovement.ts | 8 +- tests/pieces/Knight.test.ts | 77 +- tests/pieces/Mirror.test.ts | 115 + 14 files changed, 4045 insertions(+), 65 deletions(-) create mode 100644 tests/pieces/Mirror.test.ts diff --git a/package-lock.json b/package-lock.json index f4ccc0f..a29fe92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,3792 @@ { "name": "typescript-chess-engine", "version": "0.6.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "typescript-chess-engine", + "version": "0.6.0", + "license": "ISC", + "dependencies": { + "chalk": "^5.3.0", + "jsdoc": "^4.0.2", + "ts-node": "^10.9.1" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^6.4.1", + "@typescript-eslint/parser": "^6.4.1", + "eslint": "^8.47.0", + "typedoc": "^0.24.8", + "typescript": "^5.1.6", + "vite-tsconfig-paths": "^4.2.0", + "vitest": "^0.34.3", + "webpack": "^5.88.1" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", + "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", + "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@jsdoc/salty": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.5.tgz", + "integrity": "sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==", + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==", + "dev": true + }, + "node_modules/@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", + "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "node_modules/@types/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-pTjcqY9E4nOI55Wgpz7eiI8+LzdYnw3qxXCfHyBDdPbYvbyLgWLJGh8EdPvqawwMK1Uo1794AUkkR38Fr0g+2g==" + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" + }, + "node_modules/@types/node": { + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" + }, + "node_modules/@types/semver": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", + "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/type-utils": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", + "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", + "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", + "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", + "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", + "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", + "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitest/expect": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.4.tgz", + "integrity": "sha512-XlMKX8HyYUqB8dsY8Xxrc64J2Qs9pKMt2Z8vFTL4mBWXJsg4yoALHzJfDWi8h5nkO4Zua4zjqtapQ/IluVkSnA==", + "dev": true, + "dependencies": { + "@vitest/spy": "0.34.4", + "@vitest/utils": "0.34.4", + "chai": "^4.3.7" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.4.tgz", + "integrity": "sha512-hwwdB1StERqUls8oV8YcpmTIpVeJMe4WgYuDongVzixl5hlYLT2G8afhcdADeDeqCaAmZcSgLTLtqkjPQF7x+w==", + "dev": true, + "dependencies": { + "@vitest/utils": "0.34.4", + "p-limit": "^4.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.4.tgz", + "integrity": "sha512-GCsh4coc3YUSL/o+BPUo7lHQbzpdttTxL6f4q0jRx2qVGoYz/cyTRDJHbnwks6TILi6560bVWoBpYC10PuTLHw==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "pretty-format": "^29.5.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.4.tgz", + "integrity": "sha512-PNU+fd7DUPgA3Ya924b1qKuQkonAW6hL7YUjkON3wmBwSTIlhOSpy04SJ0NrRsEbrXgMMj6Morh04BMf8k+w0g==", + "dev": true, + "dependencies": { + "tinyspy": "^2.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.4.tgz", + "integrity": "sha512-yR2+5CHhp/K4ySY0Qtd+CAL9f5Yh1aXrKfAT42bq6CtlGPh92jIDDDSg7ydlRow1CP+dys4TrOrbELOyNInHSg==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.4.3", + "loupe": "^2.3.6", + "pretty-format": "^29.5.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001534", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz", + "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/chai": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", + "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.520", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.520.tgz", + "integrity": "sha512-Frfus2VpYADsrh1lB3v/ft/WVFlVzOIm+Q0p7U7VqHI6qr7NWHYKe+Wif3W50n7JAFoBsWVsoU0+qDks6WQ60g==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", + "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", + "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.49.0", + "@humanwhocodes/config-array": "^0.11.11", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "dev": true, + "dependencies": { + "flatted": "^3.2.7", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/globals": { + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsdoc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/local-pkg": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", + "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "node_modules/magic-string": { + "version": "0.30.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", + "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mlly": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz", + "integrity": "sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==", + "dev": true, + "dependencies": { + "acorn": "^8.10.0", + "pathe": "^1.1.1", + "pkg-types": "^1.0.3", + "ufo": "^1.3.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", + "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, + "node_modules/postcss": { + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "3.29.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.1.tgz", + "integrity": "sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz", + "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.4.3.tgz", + "integrity": "sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==", + "dev": true + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", + "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "dev": true, + "dependencies": { + "acorn": "^8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.19.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz", + "integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/tinybench": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", + "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", + "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz", + "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfck": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-2.1.2.tgz", + "integrity": "sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==", + "dev": true, + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^14.13.1 || ^16 || >=18" + }, + "peerDependencies": { + "typescript": "^4.3.5 || ^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedoc": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.8.tgz", + "integrity": "sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.0", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 14.14" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, + "node_modules/ufo": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.0.tgz", + "integrity": "sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==", + "dev": true + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/vite": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.4.tgz", + "integrity": "sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "mlly": "^1.4.0", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^3.0.0 || ^4.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.1.tgz", + "integrity": "sha512-GNUI6ZgPqT3oervkvzU+qtys83+75N/OuDaQl7HmOqFTb0pjZsuARrRipsyJhJ3enqV8beI1xhGbToR4o78nSQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^2.1.0" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.4.tgz", + "integrity": "sha512-SE/laOsB6995QlbSE6BtkpXDeVNLJc1u2LHRG/OpnN4RsRzM3GQm4nm3PQCK5OBtrsUqnhzLdnT7se3aeNGdlw==", + "dev": true, + "dependencies": { + "@types/chai": "^4.3.5", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "@vitest/expect": "0.34.4", + "@vitest/runner": "0.34.4", + "@vitest/snapshot": "0.34.4", + "@vitest/spy": "0.34.4", + "@vitest/utils": "0.34.4", + "acorn": "^8.9.0", + "acorn-walk": "^8.2.0", + "cac": "^6.7.14", + "chai": "^4.3.7", + "debug": "^4.3.4", + "local-pkg": "^0.4.3", + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.3.3", + "strip-literal": "^1.0.1", + "tinybench": "^2.5.0", + "tinypool": "^0.7.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", + "vite-node": "0.34.4", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*", + "playwright": "*", + "safaridriver": "*", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "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.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, "dependencies": { "@aashutoshrathi/word-wrap": { "version": "1.2.6", @@ -422,8 +4206,7 @@ "@types/node": { "version": "20.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", - "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", - "dev": true + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" }, "@types/semver": { "version": "7.5.2", @@ -768,13 +4551,15 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true + "dev": true, + "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "8.2.0", @@ -797,7 +4582,8 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "ansi-regex": { "version": "5.0.1", @@ -1708,7 +5494,8 @@ "markdown-it-anchor": { "version": "8.6.7", "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==" + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "requires": {} }, "marked": { "version": "4.3.0", @@ -2252,7 +6039,8 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", - "dev": true + "dev": true, + "requires": {} }, "ts-node": { "version": "10.9.1", @@ -2278,7 +6066,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-2.1.2.tgz", "integrity": "sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==", - "dev": true + "dev": true, + "requires": {} }, "type-check": { "version": "0.4.0", @@ -2334,10 +6123,9 @@ } }, "typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==" }, "uc.micro": { "version": "1.0.6", diff --git a/src/core/Board.ts b/src/core/Board.ts index 6527372..35020f4 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -10,6 +10,7 @@ import { Pawn, Piece, PieceType } from "@lc/pieces"; import { IllegalMoveError, Syntax } from "@lc/utils"; import { Lasgun } from "@lc/core"; import { MoveCommand } from "@lc/core"; +import { Map as ValueMap, Set as ValueSet } from "immutable"; export const enum CaptureOptions { @@ -21,7 +22,7 @@ export const enum CaptureOptions { export class Board { public readonly width: number; public readonly height: number; - private readonly tiles: Map; + private readonly tiles: Map; private readonly piecesOfType: Map,Set]>; private readonly kingsProtectors: [Set, Set]; private readonly movesHistory: [Move[], Move[]]; @@ -34,7 +35,7 @@ export class Board { public constructor(width: number, height: number) { this.width = width; this.height = height; - this.tiles = new Map(); + this.tiles = new Map(); this.piecesOfType = new Map,Set]>(); this.kingsProtectors = [new Set, new Set]; this.movesHistory = [[], []]; @@ -68,12 +69,12 @@ export class Board { public changePosition(newPosition: BoardVector2d, piece: Piece) { this.removePiece(piece); - this.tiles.set(newPosition, piece); + this.tiles.set(newPosition.toString(), piece); piece.position = newPosition; } public getPiece(position: BoardVector2d): Piece | null { - return this.tiles.get(position) ?? null; + return this.tiles.get(position.toString()) ?? null; } public isPieceAt(positon: BoardVector2d): boolean { @@ -90,14 +91,14 @@ export class Board { if (this.isPieceAt(piece.position)) { throw new Error("There is already piece at this position."); } - this.tiles.set(piece.position, piece); + this.tiles.set(piece.position.toString(), piece); this.piecesOfType.get(piece.type)![piece.playerId].add(piece); } public removePiece(piece: Piece): void { - this.tiles.delete(piece.position); + this.tiles.delete(piece.position.toString()); this.piecesOfType.get(piece.type)![piece.playerId].delete(piece); - for (let protectors of this.kingsProtectors) { + for (const protectors of this.kingsProtectors) { protectors.delete(piece); } } @@ -111,8 +112,8 @@ export class Board { throw new Error("Unable to shift piece. There is already piece on destination."); } piece.position = destination; - this.tiles.delete(origin); - this.tiles.set(destination, piece); + this.tiles.delete(origin.toString()); + this.tiles.set(destination.toString(), piece); } public canRotate(rotation: Rotation, piece: Piece): boolean { @@ -154,7 +155,7 @@ export class Board { } private isMoveCommandLegal(move: MoveCommand, playerId: Player): boolean { - let pieceToMove: Piece | null = this.getPiece(move.origin); + const pieceToMove: Piece | null = this.getPiece(move.origin); return !( pieceToMove === null || (move.destination !== null && move.rotation !== null) || @@ -173,10 +174,10 @@ export class Board { throw new IllegalMoveError(`This MoveCommand is illegal with playerId equal to ${playerId}`); } - let pieceToMove: Piece = this.getPiece(move.origin)!; + const pieceToMove: Piece = this.getPiece(move.origin)!; if (move.rangedCapture === true) { - for (let predictedMove of pieceToMove.movement.legalMoves) { + for (const predictedMove of pieceToMove.movement.legalMoves) { if (Syntax.inAlternative(predictedMove.moveType!, MoveType.RangedCapture) && move.destination === predictedMove.destination) { return predictedMove; } @@ -184,7 +185,7 @@ export class Board { } if (move.rotation !== null) { - for (let predictedMove of pieceToMove.movement.legalMoves) { + for (const predictedMove of pieceToMove.movement.legalMoves) { if (move.rotation === predictedMove.rotation) { return predictedMove; } @@ -192,7 +193,7 @@ export class Board { } if (move.destination !== null) { - for (let predictedMove of pieceToMove.movement.legalMoves) { + for (const predictedMove of pieceToMove.movement.legalMoves) { if (move.destination === predictedMove.destination) { return predictedMove; } @@ -211,8 +212,8 @@ export class Board { piece: piece, promotedTo: promotedTo ?? null, captured: null, - laserFields: [new Set, new Set], - laserCaptures: new Set + laserFields: [new Set, new Set], + laserCaptures: new Set } if (Syntax.inAlternative(ultimateMove.moveType,MoveType.EnPassant)) { diff --git a/src/core/Tile.ts b/src/core/Tile.ts index 6a0eded..192ffb6 100644 --- a/src/core/Tile.ts +++ b/src/core/Tile.ts @@ -26,7 +26,7 @@ export class Tile { } public clearAllPredictions(): void { - for (let i=0;i<1;i++) { + for (const i=0;i<1;i++) { this.inMovesIllegalOf[i].clear(); this.inMovesLegalOf[i].clear(); } diff --git a/src/core/move.ts b/src/core/move.ts index 1dafb0b..9542338 100644 --- a/src/core/move.ts +++ b/src/core/move.ts @@ -1,5 +1,6 @@ import { BoardVector2d, Rotation } from "@lc/geometry"; import { Piece, PieceType } from "@lc/pieces"; +import { Set as ValueSet } from "immutable"; export const enum MoveType { Move = 1 << 0, @@ -28,8 +29,8 @@ export interface Move { promotedTo: PieceType | null piece: Piece, captured: Piece | null, - laserFields: [Set, Set], - laserCaptures: Set + laserFields: [Set, Set], + laserCaptures: Set } export interface MoveCommand { diff --git a/src/geometry/DirectionUtils.ts b/src/geometry/DirectionUtils.ts index 5c693af..2502ca5 100644 --- a/src/geometry/DirectionUtils.ts +++ b/src/geometry/DirectionUtils.ts @@ -6,8 +6,12 @@ export function rotate(direction: Direction, steps: number): Direction { return (direction + steps) % enumSize as Direction; } else { - const notNormalizedDirection = (direction + steps) % enumSize; - const normalizedDirection = enumSize + notNormalizedDirection; + const notNormalizedDirection = direction + steps; + if (notNormalizedDirection > 0){ + return notNormalizedDirection; + } + const rest = Math.abs(notNormalizedDirection) % enumSize; + const normalizedDirection = enumSize - rest; return normalizedDirection; } } diff --git a/src/pieces/King.ts b/src/pieces/King.ts index 820d106..d5999e3 100644 --- a/src/pieces/King.ts +++ b/src/pieces/King.ts @@ -59,7 +59,7 @@ export class KingMovement extends CloseRangeMovement { const fromKingUnitVector: BoardVector2d = this.piece.position.sub(potentialRook.position).createUnitVector(); let currentPosition: BoardVector2d = this.piece.position; - for (let i = 0; i < 2; i++) { + for (const i = 0; i < 2; i++) { // if (this.board.isCheckAt(currentPosition, this.piece.playerId)) { // return false; // } diff --git a/src/pieces/Knight.ts b/src/pieces/Knight.ts index f195758..b79f49f 100644 --- a/src/pieces/Knight.ts +++ b/src/pieces/Knight.ts @@ -22,7 +22,7 @@ export class Knight extends Piece { export class KnightMovement extends PieceMovement { - protected updateMoves(): void { + public override updateMoves(): void { this.preUpdateMoves(); const piece: Knight = this.piece as Knight; @@ -38,11 +38,12 @@ export class KnightMovement extends PieceMovement { } for (const position of positions) { - let move: Partial = { - destination: position, - moveType: MoveType.Move - } + let move: Partial; if (!board.isOutOfBounds(position)) { + move = { + destination: position, + moveType: MoveType.Move + } if (board.canMoveTo(position, piece, CaptureOptions.NoCapture)) { this.legalMoves.push(move); } @@ -50,11 +51,16 @@ export class KnightMovement extends PieceMovement { move.moveType! |= MoveType.Capture; this.legalMoves.push(move) } + else { + this.illegalMoves.push(move); + } + + move = { + destination: position, + moveType: MoveType.RangedCapture + } if (board.canRangeCapture(position, piece)) { - move = { - destination: position, - moveType: MoveType.RangedCapture - } + this.legalMoves.push(move); } else { diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index 0940d2f..c3fc407 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -29,12 +29,12 @@ export class Mirror extends DirectedPiece { this.direction = DirectionUtils.rotateDoubleAnticlockwise(this.direction!); } - public turn(rotation: Rotation): void { + private turn(rotation: Rotation): void { switch(rotation) { case Rotation.Anticlockwise: this.turnAnticlockwise(); break; - case Rotation.Anticlockwise: + case Rotation.Clockwise: this.turnClockwise(); break; } @@ -54,12 +54,12 @@ export class Mirror extends DirectedPiece { export class MirrorMovement extends CloseRangeMovement { - public updateMoves(): void { + public override updateMoves(): void { super.updateMoves(); const capturable: Partial[] = this.legalMoves.filter((move) => Syntax.inAlternative(move.moveType!, MoveType.Capture)); this.illegalMoves = this.illegalMoves.concat(capturable); - this.legalMoves = this.legalMoves.filter((move) => !capturable.some((captureMove) => captureMove === move)); - + this.legalMoves = this.legalMoves.filter((move) => !capturable.includes(move)); + let move: Partial = { rotation: Rotation.Anticlockwise } diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index 90f2ab6..4727dab 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -65,7 +65,7 @@ export class PawnMovement extends PieceMovement { && piece.isOnEnPassantPosition(); } - protected updateMoves(): void { + public override updateMoves(): void { this.preUpdateMoves(); const piece: Pawn = this.piece as Pawn; diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index 616d452..d951469 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -105,14 +105,10 @@ export abstract class PieceMovement { this.illegalMoves = []; } - protected clearMoves(): void { + protected preUpdateMoves(): void { this.legalMoves.length = 0; this.illegalMoves.length = 0; } - protected preUpdateMoves(): void { - this.clearMoves(); - } - - protected abstract updateMoves(): void; + public abstract updateMoves(): void; } diff --git a/src/pieces/movements/CloseRangeMovement.ts b/src/pieces/movements/CloseRangeMovement.ts index 906e72e..6a6db96 100644 --- a/src/pieces/movements/CloseRangeMovement.ts +++ b/src/pieces/movements/CloseRangeMovement.ts @@ -3,7 +3,7 @@ import { BoardVector2d } from "@lc/geometry"; import { Piece } from "@lc/pieces"; import { PieceMovement } from "@lc/pieces"; -export class CloseRangeMovement extends PieceMovement { +export abstract class CloseRangeMovement extends PieceMovement { // This method sets all around moves as capturableMoves. public override updateMoves(): void { this.preUpdateMoves(); diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index 6291e8d..4d2d30a 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -13,13 +13,13 @@ export class LongRangeMovement extends PieceMovement { this.directions = directions; } - protected override updateMoves(): void { + public override updateMoves(): void { this.preUpdateMoves(); this.allLongRangeMoves = this.getAllLongRangeMoves(); - for (let direction of this.directions) { - let legal: boolean = true; - for (let move of this.allLongRangeMoves[direction]!) { + for (const direction of this.directions) { + const legal: boolean = true; + for (const move of this.allLongRangeMoves[direction]!) { if (Syntax.inAlternative(move.moveType!, MoveType.Capture)) { legal = false; } diff --git a/tests/pieces/Knight.test.ts b/tests/pieces/Knight.test.ts index 82a103a..c49b225 100644 --- a/tests/pieces/Knight.test.ts +++ b/tests/pieces/Knight.test.ts @@ -1,4 +1,4 @@ -import { Board, Generator, Move, Player } from "@lc/core" +import { Board, Generator, Move, MoveType, Player } from "@lc/core" import { BoardVector2d } from "@lc/geometry" import { KnightMovement } from "@lc/pieces"; import { PieceType } from "@lc/pieces"; @@ -12,7 +12,6 @@ describe("Knight", () => { } const knigth1 = Generator.createStandardPiece(data, PieceType.KNIGHT); - // const knigth2 = Generator.createStandardPiece(data, PieceType.KNIGHT); test("type", () => { expect(knigth1.type).toBe(PieceType.KNIGHT); @@ -51,14 +50,84 @@ describe("Knight", () => { test("move", () => { let move: Move = { - destination: new BoardVector2d(5, 5) + destination: new BoardVector2d(5, 5), + moveType: MoveType.Move | MoveType.Capture } as Move; knigth1.move(move); expect(knigth1.position).toStrictEqual(new BoardVector2d(5, 5)); - expect(knigth1.moveCount).toStrictEqual(1); + expect(knigth1.moveCount).toStrictEqual(2); + + move = { + destination: new BoardVector2d(5, 5), + moveType: MoveType.RangedCapture + } as Move; + knigth1.move(move); + expect(knigth1.position).toStrictEqual(new BoardVector2d(5, 5)); + expect(knigth1.moveCount).toStrictEqual(3); }) + describe("Knight movement", () => { + describe("updateMoves",() => { + const data: Generator.StandardPieceData = { + position: new BoardVector2d(4, 4), + playerId: Player.White, + board: board + } + + const knigthMovementTest = Generator.createStandardPiece(data, PieceType.KNIGHT); + + test("No other pieces",() => { + const moves: Set> = new Set( + [ + {destination: new BoardVector2d(3, 2), moveType: MoveType.Move}, + {destination: new BoardVector2d(2, 3), moveType: MoveType.Move}, + {destination: new BoardVector2d(3, 6), moveType: MoveType.Move}, + {destination: new BoardVector2d(2, 5), moveType: MoveType.Move}, + {destination: new BoardVector2d(5, 2), moveType: MoveType.Move}, + {destination: new BoardVector2d(6, 3), moveType: MoveType.Move}, + {destination: new BoardVector2d(5, 6), moveType: MoveType.Move}, + {destination: new BoardVector2d(6, 5), moveType: MoveType.Move}, + ] + ) + knigthMovementTest.movement.updateMoves(); + let k = knigthMovementTest.movement.legalMoves + for(let move of moves) { + expect(knigthMovementTest.movement.legalMoves).toContainEqual(move); + } + for(let move of moves) { + move.moveType = MoveType.RangedCapture + expect(knigthMovementTest.movement.illegalMoves).toContainEqual(move); + } + }) + + test("Enemy and friendly piece",() => { + const friendly = Generator.createStandardPiece({ + position: new BoardVector2d(3,2), + playerId: Player.White, + board: board + }, PieceType.KNIGHT); + const enemy = Generator.createStandardPiece({ + position: new BoardVector2d(2,3), + playerId: Player.Black, + board: board + }, PieceType.KNIGHT); + + board.addPieces([friendly, enemy]); + knigthMovementTest.movement.updateMoves(); + + + expect(knigthMovementTest.movement.illegalMoves).toContainEqual( {destination: new BoardVector2d(3, 2), moveType: MoveType.Move},); + expect(knigthMovementTest.movement.legalMoves).toContainEqual( {destination: new BoardVector2d(2, 3), moveType: MoveType.Move | MoveType.Capture},); + expect(knigthMovementTest.movement.legalMoves).toContainEqual( {destination: new BoardVector2d(2, 3), moveType: MoveType.RangedCapture},); + + }) + + } + + ) + }) + }) diff --git a/tests/pieces/Mirror.test.ts b/tests/pieces/Mirror.test.ts new file mode 100644 index 0000000..5f91fec --- /dev/null +++ b/tests/pieces/Mirror.test.ts @@ -0,0 +1,115 @@ +import { Board, Generator, Move, MoveType, Player } from "@lc/core" +import { Direction, Rotation } from "geometry/Direction.js"; +import { BoardVector2d } from "geometry/Vector2d.js" +import { Mirror } from "pieces/Mirror.js"; +import { PieceType } from "pieces/Piece.js"; + +describe("Mirror", () => { + const board: Board = new Board(8, 8); + + test("direction", () => { + const mirror: Mirror = Generator.createMirror( + { + position: new BoardVector2d(2, 3), + playerId: Player.White, + board: board, + direction: Direction.BottomLeftDiagonal + } + ) + expect(mirror.direction).toBe(Direction.BottomLeftDiagonal); + expect(() => {mirror.direction = Direction.BottomFile}).toThrow(); + }) + + test("move", () => { + const mirror: Mirror = Generator.createMirror( + { + position: new BoardVector2d(2, 3), + playerId: Player.White, + board: board, + direction: Direction.BottomLeftDiagonal + } + ) + let move: Move = { + moveType: MoveType.Rotation, + rotation: Rotation.Anticlockwise + } as Move + + mirror.move(move); + expect(mirror.direction).toBe(Direction.BottomRightDiagonal); + move.rotation = Rotation.Clockwise; + mirror.move(move); + expect(mirror.direction).toBe(Direction.BottomLeftDiagonal); + + move = { + moveType: MoveType.Move, + destination: new BoardVector2d(3, 4) + } as Move; + mirror.move(move); + expect(mirror.position).toStrictEqual(new BoardVector2d(3, 4)); + }) + + describe("movement", () => { + describe("updateMoves", () => { + test("No other pieces", () => { + const mirror: Mirror = Generator.createMirror( + { + position: new BoardVector2d(3, 4), + playerId: Player.White, + board: board, + direction: Direction.BottomLeftDiagonal + } + ) + mirror.movement.updateMoves(); + const moves: Set> = new Set( + [ + {destination: new BoardVector2d(2, 3), moveType: MoveType.Move}, + {destination: new BoardVector2d(3, 3), moveType: MoveType.Move}, + {destination: new BoardVector2d(4, 3), moveType: MoveType.Move}, + {destination: new BoardVector2d(4, 4), moveType: MoveType.Move}, + {destination: new BoardVector2d(4, 5), moveType: MoveType.Move}, + {destination: new BoardVector2d(3, 5), moveType: MoveType.Move}, + {destination: new BoardVector2d(2, 5), moveType: MoveType.Move}, + {destination: new BoardVector2d(2, 4), moveType: MoveType.Move}, + {rotation: Rotation.Clockwise}, + {rotation: Rotation.Anticlockwise} + ] + ) + for (const move of moves) { + expect(mirror.movement.legalMoves).toContainEqual(move) + } + }) + test("Enemy/Friendly", () => { + const mirror: Mirror = Generator.createMirror( + { + position: new BoardVector2d(3, 4), + playerId: Player.White, + board: board, + direction: Direction.BottomLeftDiagonal + } + ) + const friend = Generator.createStandardPiece( + { + position: new BoardVector2d(2, 3), + playerId: Player.White, + board: board, + }, + PieceType.KNIGHT + ) + const enemy = Generator.createStandardPiece( + { + position: new BoardVector2d(3, 3), + playerId: Player.Black, + board: board, + }, + PieceType.KNIGHT + ) + board.addPieces([friend, enemy]); + mirror.movement.updateMoves(); + let m1 = {destination: new BoardVector2d(2, 3), moveType: MoveType.Move} + let m2 = {destination: new BoardVector2d(3, 3), moveType: MoveType.Move | MoveType.Capture} + expect(mirror.movement.illegalMoves).toContainEqual(m1); + expect(mirror.movement.illegalMoves).toContainEqual(m2); + }) + }) + }) +}) \ No newline at end of file From 7f980504a67c0ecc3d52da717e2093c66e969769 Mon Sep 17 00:00:00 2001 From: Jakub Szaredko Date: Fri, 22 Sep 2023 21:01:48 +0200 Subject: [PATCH 28/35] Fix Vitest VSCode extension --- .gitignore | 11 +++++++++-- .vscode/settings.json | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 854890b..b05f4b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # Dependency directories node_modules/ jspm_packages/ -bower_components +bower_components/ # dotenv environment variable files .env @@ -14,6 +14,13 @@ bower_components *.tsbuildinfo # Visual Studio Code -.vscode/ +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets +.history/ +*.vsix build/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..70347ea --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "vitest.commandLine": "npx vitest" +} From 350793c4e9c59f243987a7cc615b094f9bec337e Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Fri, 22 Sep 2023 23:38:58 +0200 Subject: [PATCH 29/35] Created tests for `Pawn`. --- .eslintrc.json | 2 +- package-lock.json | 2 +- package.json | 2 +- src/core/Board.ts | 63 +++++++++---------- src/core/CheckManager.ts | 2 +- src/core/Lasgun.ts | 8 +-- src/core/PromotionManager.ts | 2 +- src/core/Tile.ts | 14 ++--- src/core/move.ts | 35 ++++++----- src/core/piece_generator.ts | 71 +++++++++++----------- src/game.ts | 8 +-- src/geometry/Direction.ts | 18 +++--- src/geometry/DirectionUtils.ts | 4 +- src/geometry/Vector2d.ts | 55 ++++++++--------- src/pieces/Bishop.ts | 2 +- src/pieces/DirectedPiece.ts | 4 +- src/pieces/King.ts | 12 ++-- src/pieces/Knight.ts | 4 +- src/pieces/Mirror.ts | 22 +++---- src/pieces/Pawn.ts | 24 +++++--- src/pieces/Piece.ts | 30 ++++----- src/pieces/Queen.ts | 2 +- src/pieces/Rook.ts | 2 +- src/pieces/movements/CloseRangeMovement.ts | 2 +- src/pieces/movements/LongRangeMovement.ts | 16 ++--- tests/core/PieceGenerator.test.ts | 24 ++++---- tests/core/Tile.test.ts | 30 ++++----- tests/geometry/DirectionUtils.test.ts | 24 ++++---- tests/geometry/vector.test.ts | 16 ++--- tests/pieces/Knight.test.ts | 55 ++++++++--------- tests/pieces/Mirror.test.ts | 26 ++++---- tests/pieces/Pawn.test.ts | 70 +++++++++++++++++++++ tsconfig.json | 24 ++++++-- tsconfig.prod.json | 4 +- vitest.config.ts | 2 +- 35 files changed, 387 insertions(+), 294 deletions(-) create mode 100644 tests/pieces/Pawn.test.ts diff --git a/.eslintrc.json b/.eslintrc.json index 0ae0d78..1b45f17 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,4 +16,4 @@ "@typescript-eslint" ], "rules": {} -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a29fe92..b2a5a61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6362,4 +6362,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index b568207..edcc24c 100644 --- a/package.json +++ b/package.json @@ -29,4 +29,4 @@ "jsdoc": "^4.0.2", "ts-node": "^10.9.1" } -} +} \ No newline at end of file diff --git a/src/core/Board.ts b/src/core/Board.ts index 35020f4..4ae1826 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -5,12 +5,12 @@ import { MoveType, Player } from "@lc/core"; -import { BoardVector2d, DirectionUtils, Rotation, Symmetry } from "@lc/geometry"; +import { BoardVector2d, DirectionUtils, Rotation } from "@lc/geometry"; import { Pawn, Piece, PieceType } from "@lc/pieces"; import { IllegalMoveError, Syntax } from "@lc/utils"; import { Lasgun } from "@lc/core"; import { MoveCommand } from "@lc/core"; -import { Map as ValueMap, Set as ValueSet } from "immutable"; + export const enum CaptureOptions { @@ -22,8 +22,8 @@ export const enum CaptureOptions { export class Board { public readonly width: number; public readonly height: number; - private readonly tiles: Map; - private readonly piecesOfType: Map,Set]>; + private readonly tiles: Map; + private readonly piecesOfType: Map, Set]>; private readonly kingsProtectors: [Set, Set]; private readonly movesHistory: [Move[], Move[]]; private readonly lasguns!: [Lasgun, Lasgun]; @@ -35,15 +35,15 @@ export class Board { public constructor(width: number, height: number) { this.width = width; this.height = height; - this.tiles = new Map(); - this.piecesOfType = new Map,Set]>(); + this.tiles = new Map(); + this.piecesOfType = new Map, Set]>(); this.kingsProtectors = [new Set, new Set]; this.movesHistory = [[], []]; this._lastMove = null; - for (const item in PieceType){ + for (const item in PieceType) { const pieceType: PieceType = PieceType[item as keyof typeof PieceType]; - this.piecesOfType.set(pieceType, [new Set,new Set]); + this.piecesOfType.set(pieceType, [new Set, new Set]); } @@ -55,11 +55,11 @@ export class Board { let playerPieces: Set = new Set; for (const type in PieceType) { const pieceType: PieceType = PieceType[type as keyof typeof PieceType]; - playerPieces = new Set([...playerPieces,...this.piecesOfType.get(pieceType)![playerId]]) + playerPieces = new Set([...playerPieces, ...this.piecesOfType.get(pieceType)![playerId]]) } return playerPieces; } - + public getKingProtectors(playerId: number): Set { return this.kingsProtectors[playerId]; } @@ -117,6 +117,8 @@ export class Board { } public canRotate(rotation: Rotation, piece: Piece): boolean { + rotation; + piece; return true; } @@ -139,12 +141,12 @@ export class Board { const destinationPiece: Piece | null = this.getPiece(destination); - if (destinationPiece === null){ + if (destinationPiece === null) { return capture !== CaptureOptions.RequiredCapture; } - else if(!piece.isSameColor(destinationPiece)) { - return capture !== CaptureOptions.NoCapture; + else if (!piece.isSameColor(destinationPiece)) { + return capture !== CaptureOptions.NoCapture; } return false; @@ -157,16 +159,16 @@ export class Board { private isMoveCommandLegal(move: MoveCommand, playerId: Player): boolean { const pieceToMove: Piece | null = this.getPiece(move.origin); return !( - pieceToMove === null || - (move.destination !== null && move.rotation !== null) || - (move.rotation === null && move.destination === null) || - (move.destination !== null && move.rotation !== null) || - (move.rangedCapture === true && move.rotation !== null) || - (move.fireLaser === true && !this.lasguns[playerId].isLoaded()) || - !pieceToMove.isSameColor(playerId) || - (pieceToMove.type !== PieceType.KNIGHT && move.rangedCapture === true) || - (pieceToMove.type !== PieceType.MIRROR && move.rotation !== null) - ) + pieceToMove === null || + (move.destination !== null && move.rotation !== null) || + (move.rotation === null && move.destination === null) || + (move.destination !== null && move.rotation !== null) || + (move.rangedCapture === true && move.rotation !== null) || + (move.fireLaser === true && !this.lasguns[playerId].isLoaded()) || + !pieceToMove.isSameColor(playerId) || + (pieceToMove.type !== PieceType.KNIGHT && move.rangedCapture === true) || + (pieceToMove.type !== PieceType.MIRROR && move.rotation !== null) + ) } private getSpecificMove(move: MoveCommand, playerId: number): Partial { @@ -212,23 +214,23 @@ export class Board { piece: piece, promotedTo: promotedTo ?? null, captured: null, - laserFields: [new Set, new Set], - laserCaptures: new Set + laserFields: [new Set, new Set], + laserCaptures: new Set } - if (Syntax.inAlternative(ultimateMove.moveType,MoveType.EnPassant)) { + if (Syntax.inAlternative(ultimateMove.moveType, MoveType.EnPassant)) { const directionVector: BoardVector2d = DirectionUtils.toBoardVector2d((piece as Pawn).direction!).opposite(); const enemyPositon: BoardVector2d = ultimateMove.destination!.add(directionVector); const enemyPiece: Piece = this.getPiece(enemyPositon)!; ultimateMove.captured = enemyPiece; } - else if (Syntax.inAlternative(ultimateMove.moveType,MoveType.Capture)) { + else if (Syntax.inAlternative(ultimateMove.moveType, MoveType.Capture)) { const enemyPiece: Piece = this.getPiece(ultimateMove.destination!)!; ultimateMove.captured = enemyPiece; } - - else if (Syntax.inAlternative(ultimateMove.moveType,MoveType.RangedCapture)) { + + else if (Syntax.inAlternative(ultimateMove.moveType, MoveType.RangedCapture)) { const enemyPiece: Piece = this.getPiece(ultimateMove.destination!)!; ultimateMove.captured = enemyPiece; } @@ -255,7 +257,6 @@ export class Board { } if (Syntax.inAlternative(typesOfMove, MoveType.Move)) { - const pieceToMove: Piece = move.piece; this.shiftPiece(move.origin, move.destination!); } //TODO Laser Fields and other Move Types @@ -269,7 +270,7 @@ export class Board { // but it needs to send PieceType in promotionTo. } - const pieceToMove: Piece = this.getPiece(move.origin)!; + const pieceToMove: Piece = this.getPiece(move.origin)!; const moveToAnalyze: Move = this.buildMove(pieceToMove, moveFromPiece, move); this.fulfillMove(moveToAnalyze); diff --git a/src/core/CheckManager.ts b/src/core/CheckManager.ts index 8db1a07..c46cb7d 100644 --- a/src/core/CheckManager.ts +++ b/src/core/CheckManager.ts @@ -5,7 +5,7 @@ import { Piece, PieceType, King } from "@lc/pieces"; export class CheckManager { public board: Board; - + public constructor(board: Board) { this.board = board; } diff --git a/src/core/Lasgun.ts b/src/core/Lasgun.ts index 374f30e..d0e8d3e 100644 --- a/src/core/Lasgun.ts +++ b/src/core/Lasgun.ts @@ -1,10 +1,10 @@ -import { Board, MoveType } from "@lc/core"; +import { Board } from "@lc/core"; import { BoardVector2d, Direction } from "@lc/geometry"; export const enum LaserState { - LaserFired = 1 << 0, + LaserFired = 1 << 0, LaserSustained = 1 << 1, - LaserOff = 1 << 2 + LaserOff = 1 << 2 } export class Lasgun { @@ -43,7 +43,7 @@ export class Lasgun { public get currentCharge(): number { return this.currentCharge; } - + public get laserState(): LaserState { return LaserState.LaserFired; } diff --git a/src/core/PromotionManager.ts b/src/core/PromotionManager.ts index 56ed5f9..09073aa 100644 --- a/src/core/PromotionManager.ts +++ b/src/core/PromotionManager.ts @@ -1,3 +1,3 @@ export class PromotionManager { - + } diff --git a/src/core/Tile.ts b/src/core/Tile.ts index 192ffb6..faa9d1d 100644 --- a/src/core/Tile.ts +++ b/src/core/Tile.ts @@ -3,17 +3,17 @@ import { Piece } from "@lc/pieces"; import { Syntax } from "@lc/utils"; export const enum MovesPredictionsType { - Legal = 1 << 1, - Illegal = 1 << 2 + Legal = 1 << 1, + Illegal = 1 << 2 } export class Tile { - + private _coordinates: BoardVector2d; private inMovesLegalOf: [Set, Set]; private inMovesIllegalOf: [Set, Set]; public pieceOnTile: Piece | null; - + public constructor(coordinates: BoardVector2d) { this._coordinates = coordinates; this.inMovesLegalOf = [new Set(), new Set()]; @@ -24,9 +24,9 @@ export class Tile { public get coordinates(): BoardVector2d { return this._coordinates; } - + public clearAllPredictions(): void { - for (const i=0;i<1;i++) { + for (let i = 0; i < 1; i++) { this.inMovesIllegalOf[i].clear(); this.inMovesLegalOf[i].clear(); } @@ -76,7 +76,7 @@ export class Tile { piecesSet = new Set(this.inMovesIllegalOf[playerId]); } if (Syntax.inAlternative(movePredictionsType, MovesPredictionsType.Legal)) { - piecesSet = new Set([...this.inMovesIllegalOf[playerId],...this.inMovesLegalOf[playerId]]); + piecesSet = new Set([...this.inMovesIllegalOf[playerId], ...this.inMovesLegalOf[playerId]]); } return piecesSet; } diff --git a/src/core/move.ts b/src/core/move.ts index 9542338..b812baf 100644 --- a/src/core/move.ts +++ b/src/core/move.ts @@ -1,36 +1,35 @@ import { BoardVector2d, Rotation } from "@lc/geometry"; import { Piece, PieceType } from "@lc/pieces"; -import { Set as ValueSet } from "immutable"; export const enum MoveType { - Move = 1 << 0, - Capture = 1 << 1, - RangedCapture = 1 << 2, - EnPassant = 1 << 3, - KingSideCastling = 1 << 4, + Move = 1 << 0, + Capture = 1 << 1, + RangedCapture = 1 << 2, + EnPassant = 1 << 3, + KingSideCastling = 1 << 4, QueenSideCastling = 1 << 5, - Rotation = 1 << 6, - Promotion = 1 << 7, - - LaserFired = 1 << 8, - Checkmate = 1 << 9, - Stalemate = 1 << 10, - Lasermate = 1 << 11, - Draw = 1 << 12, - Check = 1 << 13, + Rotation = 1 << 6, + Promotion = 1 << 7, + + LaserFired = 1 << 8, + Checkmate = 1 << 9, + Stalemate = 1 << 10, + Lasermate = 1 << 11, + Draw = 1 << 12, + Check = 1 << 13, } export interface Move { destination: BoardVector2d | null, moveType: MoveType, rotation: Rotation | null, - + origin: BoardVector2d, promotedTo: PieceType | null piece: Piece, captured: Piece | null, - laserFields: [Set, Set], - laserCaptures: Set + laserFields: [Set, Set], + laserCaptures: Set } export interface MoveCommand { diff --git a/src/core/piece_generator.ts b/src/core/piece_generator.ts index 89322ab..0ca2e07 100644 --- a/src/core/piece_generator.ts +++ b/src/core/piece_generator.ts @@ -1,13 +1,14 @@ -import { +import { PieceType, - Piece, - King, - Queen, - Knight, - Mirror, - Pawn, - Bishop, - Rook } from "@lc/pieces"; + Piece, + King, + Queen, + Knight, + Mirror, + Pawn, + Bishop, + Rook +} from "@lc/pieces"; import { BoardVector2d, Direction } from "@lc/geometry"; import { Board } from "@lc/core"; @@ -27,32 +28,32 @@ export interface PawnPieceData extends DirectedPieceData { } export function createStandardPiece(pieceData: StandardPieceData, type: PieceType): Piece { - switch(type) { - case PieceType.KING: - return new King(pieceData.position, pieceData.playerId, pieceData.board); - case PieceType.QUEEN: - return new Queen(pieceData.position, pieceData.playerId, pieceData.board); - case PieceType.BISHOP: - return new Bishop(pieceData.position, pieceData.playerId, pieceData.board); - case PieceType.ROOK: - return new Rook(pieceData.position, pieceData.playerId, pieceData.board); - case PieceType.KNIGHT: - return new Knight(pieceData.position, pieceData.playerId, pieceData.board); - } - throw new Error("Unable to create this type of piece using PieceGenerator.createStandardPiece.") + switch (type) { + case PieceType.KING: + return new King(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.QUEEN: + return new Queen(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.BISHOP: + return new Bishop(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.ROOK: + return new Rook(pieceData.position, pieceData.playerId, pieceData.board); + case PieceType.KNIGHT: + return new Knight(pieceData.position, pieceData.playerId, pieceData.board); } + throw new Error("Unable to create this type of piece using PieceGenerator.createStandardPiece.") +} - export function createMirror(pieceData: DirectedPieceData): Mirror { - const piece: Mirror = new Mirror(pieceData.position, pieceData.playerId, pieceData.board); - piece.direction = pieceData.direction; - return piece; - } +export function createMirror(pieceData: DirectedPieceData): Mirror { + const piece: Mirror = new Mirror(pieceData.position, pieceData.playerId, pieceData.board); + piece.direction = pieceData.direction; + return piece; +} + +export function createPawn(pieceData: PawnPieceData): Pawn { + const piece: Pawn = new Pawn(pieceData.position, pieceData.playerId, pieceData.board); + piece.direction = pieceData.direction; + piece.enPassantPosition = pieceData.enPassantPosition; + piece.promotionPosition = pieceData.promotionPosition; + return piece; +} - export function createPawn(pieceData: PawnPieceData): Pawn { - const piece: Pawn = new Pawn(pieceData.position, pieceData.playerId, pieceData.board); - piece.direction = pieceData.direction; - piece.enPassantPosition = pieceData.enPassantPosition; - piece.promotionPosition = pieceData.promotionPosition; - return piece; - } - diff --git a/src/game.ts b/src/game.ts index ff91624..09289e4 100644 --- a/src/game.ts +++ b/src/game.ts @@ -4,15 +4,15 @@ export class Game { private _currentPlayer: number; private _board?: Board; - public constructor(){ + public constructor() { this._currentPlayer = 0; } - public set board(board: Board){ + public set board(board: Board) { this._board = board; } - - public get board(): Board{ + + public get board(): Board { if (this._board === undefined) { throw new Error("Board is undefined."); } diff --git a/src/geometry/Direction.ts b/src/geometry/Direction.ts index f7684a0..c8866f5 100644 --- a/src/geometry/Direction.ts +++ b/src/geometry/Direction.ts @@ -1,15 +1,15 @@ export enum Direction { - LeftRank = 0, - UpperLeftDiagonal = 1, - UpperFile = 2, - UpperRightDiagonal = 3, - RightRank = 4, + LeftRank = 0, + UpperLeftDiagonal = 1, + UpperFile = 2, + UpperRightDiagonal = 3, + RightRank = 4, BottomRightDiagonal = 5, - BottomFile = 6, - BottomLeftDiagonal = 7, + BottomFile = 6, + BottomLeftDiagonal = 7, } export const enum Rotation { - Clockwise = 0, - Anticlockwise = 1 + Clockwise = 0, + Anticlockwise = 1 } diff --git a/src/geometry/DirectionUtils.ts b/src/geometry/DirectionUtils.ts index 2502ca5..d02d3bf 100644 --- a/src/geometry/DirectionUtils.ts +++ b/src/geometry/DirectionUtils.ts @@ -7,8 +7,8 @@ export function rotate(direction: Direction, steps: number): Direction { } else { const notNormalizedDirection = direction + steps; - if (notNormalizedDirection > 0){ - return notNormalizedDirection; + if (notNormalizedDirection > 0) { + return notNormalizedDirection; } const rest = Math.abs(notNormalizedDirection) % enumSize; const normalizedDirection = enumSize - rest; diff --git a/src/geometry/Vector2d.ts b/src/geometry/Vector2d.ts index cf64883..f2f3a3e 100644 --- a/src/geometry/Vector2d.ts +++ b/src/geometry/Vector2d.ts @@ -1,7 +1,6 @@ import { Direction, DirectionUtils } from "@lc/geometry"; import { Integer } from "@lc/utils"; import { Board } from "@lc/core"; -import { Type } from "typescript"; /** * Enum that represents possible symmetry transformation @@ -11,9 +10,9 @@ import { Type } from "typescript"; */ export const enum Symmetry { Origin = 0, - XAxis = 1, - YAxis = 2, - None = 3 + XAxis = 1, + YAxis = 2, + None = 3 } /** @@ -185,7 +184,7 @@ export class Vector2d { * * @returns New `Vector2d` object created by negating calling object coordinates. */ - public opposite(): typeof this { + public opposite(): typeof this { return this.createVector(-this.x, -this.y) as typeof this; } @@ -194,7 +193,7 @@ export class Vector2d { * * @returns New `Vector2d` object that is copy of calling object. */ - public copy(): typeof this { + public copy(): typeof this { return this.createVector(this.x, this.y) as typeof this; } @@ -238,7 +237,7 @@ export class Vector2d { * @returns `Number` that represents length of vector. */ public getLength(): number { - return Math.sqrt(this.x*this.x+this.y*this.y); + return Math.sqrt(this.x * this.x + this.y * this.y); } /** @@ -253,7 +252,7 @@ export class Vector2d { } - + } @@ -326,24 +325,24 @@ export class IntVector2d extends Vector2d { return this.x == other.x && this.y == other.y; } - /** - * Method creates new `IntVector2d` object that is - * {@link https://en.wikipedia.org/wiki/Unit_vector unit vector} - * of calling object. This method differs from {@link Vector2d.createUnitVector}, - * as it creates new `IntVector2d` with one coordinate equal to 0, and one equal - * to -1 or 1. In most cases, new object have certain coordinate equal to 1 or -1, if this - * coordinate had greater absolute value than other coordinate of calling object. - * If absolute values of both coordinates of calling object are equal, then - * `prioritizeAxisY` decides which coordinate is more important(, by default - * more important is x axis). - * - * @summary Method creates new `IntVector2d` object that is - * {@link https://en.wikipedia.org/wiki/Unit_vector unit vector} - * of calling object. - * @param {boolean} prioritizeAxisY - bool value that decides which axis should be considered - * as more important, when absolute value of coordinates is equal. - * @returns `IntVector2d` object that is {@link https://en.wikipedia.org/wiki/Unit_vector unit vector}. - */ + /** + * Method creates new `IntVector2d` object that is + * {@link https://en.wikipedia.org/wiki/Unit_vector unit vector} + * of calling object. This method differs from {@link Vector2d.createUnitVector}, + * as it creates new `IntVector2d` with one coordinate equal to 0, and one equal + * to -1 or 1. In most cases, new object have certain coordinate equal to 1 or -1, if this + * coordinate had greater absolute value than other coordinate of calling object. + * If absolute values of both coordinates of calling object are equal, then + * `prioritizeAxisY` decides which coordinate is more important(, by default + * more important is x axis). + * + * @summary Method creates new `IntVector2d` object that is + * {@link https://en.wikipedia.org/wiki/Unit_vector unit vector} + * of calling object. + * @param {boolean} prioritizeAxisY - bool value that decides which axis should be considered + * as more important, when absolute value of coordinates is equal. + * @returns `IntVector2d` object that is {@link https://en.wikipedia.org/wiki/Unit_vector unit vector}. + */ public createUnitVector(prioritizeAxisY?: boolean): typeof this { if (Math.abs(this.x) === Math.abs(this.y)) { if (prioritizeAxisY !== undefined || prioritizeAxisY === true) { @@ -478,7 +477,7 @@ export class BoardVector2d extends IntVector2d { public static fromTuple(coordinates: [number, number]): BoardVector2d { return new BoardVector2d(coordinates[0], coordinates[1]); } - + /** * Method creates array of `BoardVector2d` objects. First element of this array is copy of calling * object. Following objects are created by adding multiples of `increment` values to calling object. @@ -520,7 +519,7 @@ export class BoardVector2d extends IntVector2d { const moves: BoardVector2d[] = []; const length: number = Math.min(xCoordinates.length, yCoordinates.length); - for (let i = 0; i = { destination: this.piece.position.add(new BoardVector2d(2, 0)) as BoardVector2d, diff --git a/src/pieces/Knight.ts b/src/pieces/Knight.ts index b79f49f..d97e52b 100644 --- a/src/pieces/Knight.ts +++ b/src/pieces/Knight.ts @@ -6,7 +6,7 @@ import { PieceMovement } from "@lc/pieces"; export class Knight extends Piece { protected override initType(): void { this._type = PieceType.KNIGHT; - this._movement = new KnightMovement(this, this.board); + this._movement = new KnightMovement(this, this.board); } @@ -54,7 +54,7 @@ export class KnightMovement extends PieceMovement { else { this.illegalMoves.push(move); } - + move = { destination: position, moveType: MoveType.RangedCapture diff --git a/src/pieces/Mirror.ts b/src/pieces/Mirror.ts index c3fc407..1862afd 100644 --- a/src/pieces/Mirror.ts +++ b/src/pieces/Mirror.ts @@ -7,7 +7,7 @@ import { Syntax } from "@lc/utils"; export class Mirror extends DirectedPiece { protected override initType(): void { this._type = PieceType.MIRROR; - this._movement = new MirrorMovement(this, this.board); + this._movement = new MirrorMovement(this, this.board); } public set direction(direction: Direction) { @@ -17,10 +17,10 @@ export class Mirror extends DirectedPiece { this._direction = direction; } - public get direction(): Direction | undefined { - return this._direction; + public get direction(): Direction { + return super.direction; } - + private turnClockwise(): void { this.direction = DirectionUtils.rotateDoubleClockwise(this.direction!); } @@ -30,13 +30,13 @@ export class Mirror extends DirectedPiece { } private turn(rotation: Rotation): void { - switch(rotation) { + switch (rotation) { case Rotation.Anticlockwise: this.turnAnticlockwise(); - break; + break; case Rotation.Clockwise: this.turnClockwise(); - break; + break; } } @@ -62,8 +62,8 @@ export class MirrorMovement extends CloseRangeMovement { let move: Partial = { rotation: Rotation.Anticlockwise - } - if(this.board.canRotate(Rotation.Anticlockwise, this.piece)) { + } + if (this.board.canRotate(Rotation.Anticlockwise, this.piece)) { this.legalMoves.push(move); } else { @@ -72,8 +72,8 @@ export class MirrorMovement extends CloseRangeMovement { move = { rotation: Rotation.Clockwise - } - if(this.board.canRotate(Rotation.Anticlockwise, this.piece)) { + } + if (this.board.canRotate(Rotation.Anticlockwise, this.piece)) { this.legalMoves.push(move); } else { diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index 4727dab..1d735ce 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -9,14 +9,18 @@ export class Pawn extends DirectedPiece { protected override initType(): void { this._type = PieceType.PAWN; - this._movement = new PawnMovement(this, this.board); + this._movement = new PawnMovement(this, this.board); + } + + public get direction(): Direction { + return super.direction; } public set direction(direction: Direction) { if (direction % 2 === 1) { throw new Error("Direction for PawnPiece mustn't be diagonal."); } - super._direction = direction; + this._direction = direction; } public set enPassantPosition(position: BoardVector2d) { @@ -28,24 +32,30 @@ export class Pawn extends DirectedPiece { } public get enPassantPosition(): BoardVector2d { - if (this.enPassantPosition === undefined){ + if (this._enPassantPosition === undefined) { throw new Error("enPassantPosition is not initialised."); } return this._enPassantPosition!; } public get promotionPosition(): BoardVector2d { - if (this.promotionPosition === undefined){ + if (this._promotionPosition === undefined) { throw new Error("promotionPosition is not initialised."); } return this._promotionPosition!; } public isOnEnPassantPosition(): boolean { - return this._enPassantPosition === this.position; + if (this._enPassantPosition === undefined) { + throw new Error("enPassantPosition is not initialised."); + } + return this._enPassantPosition!.equals(this.position); } public isOnPromotionPosition(): boolean { + if (this._promotionPosition === undefined) { + throw new Error("promotionPosition is not initialised."); + } return this._promotionPosition!.y === this.position.y; } } @@ -81,7 +91,7 @@ export class PawnMovement extends PieceMovement { const move: Partial = { destination: piece.position.add(direction) as BoardVector2d, moveType: MoveType.Move - } + } if (board.canMoveTo(piece.position.add(direction), piece, CaptureOptions.NoCapture)) { this.legalMoves.push(move); } @@ -143,7 +153,7 @@ export class PawnMovement extends PieceMovement { } // Promotion flag - const commonMoves: Partial[] = [...this.legalMoves,...this.illegalMoves]; + const commonMoves: Partial[] = [...this.legalMoves, ...this.illegalMoves]; for (const move of commonMoves) { if ((this.piece as Pawn).promotionPosition.y === move.destination!.y) { move.moveType! |= MoveType.Promotion; diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index d951469..4d76fee 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -3,11 +3,11 @@ import { BoardVector2d } from "@lc/geometry"; export enum PieceType { - KING = "K", - QUEEN = "Q", - PAWN = "", + KING = "K", + QUEEN = "Q", + PAWN = "", BISHOP = "B", - ROOK = "R", + ROOK = "R", KNIGHT = "N", MIRROR = "M", } @@ -27,13 +27,13 @@ export abstract class Piece { public readonly defendsKingsFrom: [Piece | null, Piece | null]; public position: BoardVector2d; protected moveCounter: number; - + public constructor(position: BoardVector2d, playerId: number, board: Board) { - this.initialPosition = position; - this.position = position; - this.playerId = playerId; - this.moveCounter = 0; - this.board = board; + this.initialPosition = position; + this.position = position; + this.playerId = playerId; + this.moveCounter = 0; + this.board = board; this.defendsKingsFrom = [null, null]; this.initType(); } @@ -99,14 +99,14 @@ export abstract class PieceMovement { public legalMoves: Partial[]; public constructor(piece: Piece, board: Board) { - this.piece = piece; - this.board = board; - this.legalMoves = []; - this.illegalMoves = []; + this.piece = piece; + this.board = board; + this.legalMoves = []; + this.illegalMoves = []; } protected preUpdateMoves(): void { - this.legalMoves.length = 0; + this.legalMoves.length = 0; this.illegalMoves.length = 0; } diff --git a/src/pieces/Queen.ts b/src/pieces/Queen.ts index 45c680e..ac55aa8 100644 --- a/src/pieces/Queen.ts +++ b/src/pieces/Queen.ts @@ -15,7 +15,7 @@ export class Queen extends Piece { ]; protected override initType(): void { - this._type = PieceType.QUEEN; + this._type = PieceType.QUEEN; this._movement = new LongRangeMovement(this, this.board, Queen.DIRECTIONS); } } diff --git a/src/pieces/Rook.ts b/src/pieces/Rook.ts index ddbd834..1f6a806 100644 --- a/src/pieces/Rook.ts +++ b/src/pieces/Rook.ts @@ -11,7 +11,7 @@ export class Rook extends Piece { ]; protected override initType(): void { - this._type = PieceType.ROOK; + this._type = PieceType.ROOK; this._movement = new LongRangeMovement(this, this.board, Rook.DIRECTIONS); } } diff --git a/src/pieces/movements/CloseRangeMovement.ts b/src/pieces/movements/CloseRangeMovement.ts index 6a6db96..550487f 100644 --- a/src/pieces/movements/CloseRangeMovement.ts +++ b/src/pieces/movements/CloseRangeMovement.ts @@ -18,7 +18,7 @@ export abstract class CloseRangeMovement extends PieceMovement { continue; } const newVector: BoardVector2d = new BoardVector2d(scalar1, scalar2).add(piece.position); - let move: Partial = { + const move: Partial = { destination: newVector, moveType: MoveType.Move } diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index 4d2d30a..3ddf731 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -37,25 +37,25 @@ export class LongRangeMovement extends PieceMovement { private getAllLongRangeMoves(): Partial[]>> { const moves: Partial[]>> = {}; for (const direction of this.directions) { - moves[direction] = this.getAllCoordinatesByDirection(direction); + moves[direction] = this.getAllCoordinatesByDirection(direction); } return moves; } private getAllCoordinatesByDirection(direction: Direction): Partial[] { - const x = this.piece.position.x, - y = this.piece.position.y, - tuple = DirectionUtils.toTuple(direction), - step = { x: tuple[0], y: tuple[1] }; + const x = this.piece.position.x, + y = this.piece.position.y, + tuple = DirectionUtils.toTuple(direction), + step = { x: tuple[0], y: tuple[1] }; const maxMoveLength = { - x: step.x > 0 ? this.board.width - x : x, + x: step.x > 0 ? this.board.width - x : x, y: step.y > 0 ? this.board.height - y : y }; const moveLength = Math.min(maxMoveLength.x, maxMoveLength.y); const moveArray: Partial[] = []; let i = 0; - for (;i < moveLength; i++) { + for (; i < moveLength; i++) { let vector: BoardVector2d = new BoardVector2d(x + i * step.x, y + i * step.y); if (this.board.canMoveTo(vector, this.piece, CaptureOptions.NoCapture)) { moveArray.push({ @@ -70,6 +70,6 @@ export class LongRangeMovement extends PieceMovement { }) } } - return moveArray + return moveArray } } \ No newline at end of file diff --git a/tests/core/PieceGenerator.test.ts b/tests/core/PieceGenerator.test.ts index b6f9a34..fc7d265 100644 --- a/tests/core/PieceGenerator.test.ts +++ b/tests/core/PieceGenerator.test.ts @@ -1,6 +1,6 @@ import { Board, Generator } from "@lc/core" import { BoardVector2d, Direction } from "@lc/geometry"; -import { Bishop, King, Knight, Mirror, Pawn, Piece, Queen, Rook } from "@lc/pieces"; +import { Bishop, King, Knight, Mirror, Pawn, Queen, Rook } from "@lc/pieces"; import { PieceType } from "@lc/pieces"; @@ -8,38 +8,38 @@ import { PieceType } from "@lc/pieces"; describe("PieceGenerator", () => { const board: Board = new Board(8, 8); - + test("createStandardPiece", () => { - let data: Generator.StandardPieceData = { + const data: Generator.StandardPieceData = { position: new BoardVector2d(1, 1), playerId: 0, board: board, } const constructors = [King, Queen, Bishop, Rook, Knight]; let enumValues: PieceType[] = [PieceType.KING, PieceType.QUEEN, PieceType.BISHOP, PieceType.ROOK, PieceType.KNIGHT]; - for(let zip of constructors.map((e, i) => {return [e, enumValues[i]] as [any, PieceType]})) { - expect(Generator.createStandardPiece(data, zip[1])).toStrictEqual(new zip[0](data.position,data.playerId,data.board)); + for (const zip of constructors.map((e, i) => { return [e, enumValues[i]] as [typeof King, PieceType] })) { + expect(Generator.createStandardPiece(data, zip[1])).toStrictEqual(new zip[0](data.position, data.playerId, data.board)); } enumValues = [PieceType.MIRROR, PieceType.PAWN]; - for(let single of enumValues) { + for (const single of enumValues) { expect(() => Generator.createStandardPiece(data, single)).toThrowError(Error); } - }) + }) test("createMirror", () => { - let data: Generator.DirectedPieceData = { + const data: Generator.DirectedPieceData = { position: new BoardVector2d(1, 1), playerId: 0, board: board, direction: Direction.BottomLeftDiagonal } - const mirror: Mirror = new Mirror(data.position,data.playerId,data.board); + const mirror: Mirror = new Mirror(data.position, data.playerId, data.board); mirror.direction = data.direction; expect(Generator.createMirror(data)).toStrictEqual(mirror); }) test("createPawn", () => { - let data: Generator.PawnPieceData = { + const data: Generator.PawnPieceData = { position: new BoardVector2d(1, 1), playerId: 0, board: board, @@ -47,11 +47,11 @@ describe("PieceGenerator", () => { enPassantPosition: new BoardVector2d(2, 3), promotionPosition: new BoardVector2d(5, 5) } - const pawn: Pawn = new Pawn(data.position,data.playerId,data.board); + const pawn: Pawn = new Pawn(data.position, data.playerId, data.board); pawn.direction = data.direction; pawn.enPassantPosition = data.enPassantPosition; pawn.promotionPosition = data.promotionPosition expect(Generator.createPawn(data)).toStrictEqual(pawn); - }) + }) } ) \ No newline at end of file diff --git a/tests/core/Tile.test.ts b/tests/core/Tile.test.ts index d550811..4edd29b 100644 --- a/tests/core/Tile.test.ts +++ b/tests/core/Tile.test.ts @@ -4,22 +4,22 @@ import { BoardVector2d } from "geometry/Vector2d.js" import { King, PieceType, Queen } from "@lc/pieces" describe("Tile", () => { - let board: Board = new Board(8, 8); - - let data: Generator.StandardPieceData = { + const board: Board = new Board(8, 8); + + const data: Generator.StandardPieceData = { position: new BoardVector2d(2, 2), playerId: Player.White, board: board - } - let piece1: King = Generator.createStandardPiece(data, PieceType.KING) as King; - + } + const piece1: King = Generator.createStandardPiece(data, PieceType.KING) as King; + data.playerId = Player.Black - let piece2: Queen = Generator.createStandardPiece(data, PieceType.QUEEN) as Queen; - - let tile = new Tile(new BoardVector2d(2,2)); - + const piece2: Queen = Generator.createStandardPiece(data, PieceType.QUEEN) as Queen; + + const tile = new Tile(new BoardVector2d(2, 2)); + test("addPieceMovesToTile", () => { - tile.addPieceMovesToTile(piece1,MovesPredictionsType.Illegal); + tile.addPieceMovesToTile(piece1, MovesPredictionsType.Illegal); expect(tile.checkIfPieceMovesInTile(piece1, MovesPredictionsType.Illegal)).toBe(true); expect(tile.checkIfPieceMovesInTile(piece1, MovesPredictionsType.Legal)).toBe(false); }) @@ -35,13 +35,13 @@ describe("Tile", () => { expect(tile.isPieceMovesEmpty(piece2.playerId, MovesPredictionsType.Legal)).toBe(false); expect(tile.isPieceMovesEmpty(piece2.playerId, MovesPredictionsType.Illegal)).toBe(true); }) - + test("getPieceMovesOfTile", () => { - expect(tile.getPieceMovesOfTile(piece2.playerId, MovesPredictionsType.Illegal| MovesPredictionsType.Legal).size).toBe(1) + expect(tile.getPieceMovesOfTile(piece2.playerId, MovesPredictionsType.Illegal | MovesPredictionsType.Legal).size).toBe(1) }) - + test("clearAllPredictions", () => { - tile.addPieceMovesToTile(piece1,MovesPredictionsType.Illegal); + tile.addPieceMovesToTile(piece1, MovesPredictionsType.Illegal); tile.clearAllPredictions(); expect(tile.getPieceMovesOfTile(piece1.playerId, MovesPredictionsType.Illegal | MovesPredictionsType.Legal).size).toBe(0); }) diff --git a/tests/geometry/DirectionUtils.test.ts b/tests/geometry/DirectionUtils.test.ts index 0ebc21f..8bec727 100644 --- a/tests/geometry/DirectionUtils.test.ts +++ b/tests/geometry/DirectionUtils.test.ts @@ -1,21 +1,21 @@ import { BoardVector2d, Direction, DirectionUtils } from "@lc/geometry"; describe("DirectionUtils", () => { - test("rotate",() => { - expect(DirectionUtils.rotate(Direction.LeftRank,3)).toBe(Direction.UpperRightDiagonal); - expect(DirectionUtils.rotate(Direction.UpperFile,-3)).toBe(Direction.BottomLeftDiagonal); + test("rotate", () => { + expect(DirectionUtils.rotate(Direction.LeftRank, 3)).toBe(Direction.UpperRightDiagonal); + expect(DirectionUtils.rotate(Direction.UpperFile, -3)).toBe(Direction.BottomLeftDiagonal); expect(DirectionUtils.rotate(Direction.UpperFile, 20)).toBe(Direction.BottomFile); }) - test("rotateClockwise",() => { + test("rotateClockwise", () => { expect(DirectionUtils.rotateClockwise(Direction.LeftRank)).toBe(Direction.UpperLeftDiagonal); }) - test("rotateAnticlockwise",() => { + test("rotateAnticlockwise", () => { expect(DirectionUtils.rotateAnticlockwise(Direction.LeftRank)).toBe(Direction.BottomLeftDiagonal); }) - test("rotateDoubleClockwise",() => { + test("rotateDoubleClockwise", () => { expect(DirectionUtils.rotateDoubleClockwise(Direction.LeftRank)).toBe(Direction.UpperFile); }) - test("rotateDoubleAnticlockwise",() => { + test("rotateDoubleAnticlockwise", () => { expect(DirectionUtils.rotateDoubleAnticlockwise(Direction.LeftRank)).toBe(Direction.BottomFile); }) test("formCoordinates", () => { @@ -27,9 +27,9 @@ describe("DirectionUtils", () => { [[-1, 1], Direction.UpperLeftDiagonal], [[1, 1], Direction.UpperRightDiagonal], [[1, -1], Direction.BottomRightDiagonal], - [[-1, -1],Direction.BottomLeftDiagonal] + [[-1, -1], Direction.BottomLeftDiagonal] ] - for (let corresponding of coordinates) { + for (const corresponding of coordinates) { expect(DirectionUtils.fromCoordinates(corresponding[0])).toBe(corresponding[1]); } }) @@ -42,9 +42,9 @@ describe("DirectionUtils", () => { [[-1, 1], Direction.UpperLeftDiagonal], [[1, 1], Direction.UpperRightDiagonal], [[1, -1], Direction.BottomRightDiagonal], - [[-1, -1],Direction.BottomLeftDiagonal] + [[-1, -1], Direction.BottomLeftDiagonal] ] - for (let corresponding of coordinates) { + for (const corresponding of coordinates) { expect(DirectionUtils.toTuple(corresponding[1])).toStrictEqual(corresponding[0]); } }) @@ -60,7 +60,7 @@ describe("DirectionUtils", () => { Direction.BottomLeftDiagonal ] - for (let corresponding of coordinates) { + for (const corresponding of coordinates) { expect(DirectionUtils.toBoardVector2d(corresponding)).toStrictEqual(BoardVector2d.fromTuple(DirectionUtils.toTuple(corresponding))); } }) diff --git a/tests/geometry/vector.test.ts b/tests/geometry/vector.test.ts index d5931ac..35ebc3f 100644 --- a/tests/geometry/vector.test.ts +++ b/tests/geometry/vector.test.ts @@ -121,11 +121,11 @@ describe("BoardVector2d", () => { }); test("Getting moves", () => { - const board: Board = new Board(8,8) - let vector: BoardVector2d = new BoardVector2d(7,7); - expect(vector.getDirectedMoveFromTuple([1,1],board)).toStrictEqual([new BoardVector2d(7,7)]); - vector = new BoardVector2d(2,4); - expect(vector.getDirectedMoveFromTuple([-1,1],board)).toStrictEqual([new BoardVector2d(2,4), new BoardVector2d(1,5),new BoardVector2d(0,6)]); + const board: Board = new Board(8, 8) + let vector: BoardVector2d = new BoardVector2d(7, 7); + expect(vector.getDirectedMoveFromTuple([1, 1], board)).toStrictEqual([new BoardVector2d(7, 7)]); + vector = new BoardVector2d(2, 4); + expect(vector.getDirectedMoveFromTuple([-1, 1], board)).toStrictEqual([new BoardVector2d(2, 4), new BoardVector2d(1, 5), new BoardVector2d(0, 6)]); }) }); @@ -133,8 +133,8 @@ describe("BoardVector2d", () => { describe("Different types vectors", () => { test("Creating BoardVector2d from other type vectors", () => { - expect(new BoardVector2d(2,2).add(new Vector2d(2,2)).toString()).toStrictEqual(new BoardVector2d(4, 4).toString()); - expect(new Vector2d(2,2).add(new BoardVector2d(2,2)).toString()).toStrictEqual(new Vector2d(4, 4).toString()); + expect(new BoardVector2d(2, 2).add(new Vector2d(2, 2)).toString()).toStrictEqual(new BoardVector2d(4, 4).toString()); + expect(new Vector2d(2, 2).add(new BoardVector2d(2, 2)).toString()).toStrictEqual(new Vector2d(4, 4).toString()); }); - + }); \ No newline at end of file diff --git a/tests/pieces/Knight.test.ts b/tests/pieces/Knight.test.ts index c49b225..a78cc0c 100644 --- a/tests/pieces/Knight.test.ts +++ b/tests/pieces/Knight.test.ts @@ -28,7 +28,7 @@ describe("Knight", () => { test("wasMoved", () => { expect(knigth1.wasMoved()).toBeFalsy(); - let move: Move = { + const move: Move = { destination: new BoardVector2d(2, 2) } as Move; knigth1.move(move); @@ -39,11 +39,11 @@ describe("Knight", () => { test("isSameColor", () => { expect(knigth1.isSameColor(Player.Black)).toBeFalsy(); expect(knigth1.isSameColor(Player.White)).toBeTruthy(); - + const knigth2 = Generator.createStandardPiece(data, PieceType.KNIGHT); data.playerId = Player.Black; const knigth3 = Generator.createStandardPiece(data, PieceType.KNIGHT); - + expect(knigth1.isSameColor(knigth2)).toBeTruthy(); expect(knigth1.isSameColor(knigth3)).toBeFalsy(); }) @@ -54,7 +54,7 @@ describe("Knight", () => { moveType: MoveType.Move | MoveType.Capture } as Move; knigth1.move(move); - + expect(knigth1.position).toStrictEqual(new BoardVector2d(5, 5)); expect(knigth1.moveCount).toStrictEqual(2); @@ -68,47 +68,46 @@ describe("Knight", () => { }) describe("Knight movement", () => { - describe("updateMoves",() => { + describe("updateMoves", () => { const data: Generator.StandardPieceData = { position: new BoardVector2d(4, 4), playerId: Player.White, board: board } - + const knigthMovementTest = Generator.createStandardPiece(data, PieceType.KNIGHT); - - test("No other pieces",() => { + + test("No other pieces", () => { const moves: Set> = new Set( [ - {destination: new BoardVector2d(3, 2), moveType: MoveType.Move}, - {destination: new BoardVector2d(2, 3), moveType: MoveType.Move}, - {destination: new BoardVector2d(3, 6), moveType: MoveType.Move}, - {destination: new BoardVector2d(2, 5), moveType: MoveType.Move}, - {destination: new BoardVector2d(5, 2), moveType: MoveType.Move}, - {destination: new BoardVector2d(6, 3), moveType: MoveType.Move}, - {destination: new BoardVector2d(5, 6), moveType: MoveType.Move}, - {destination: new BoardVector2d(6, 5), moveType: MoveType.Move}, + { destination: new BoardVector2d(3, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 5), moveType: MoveType.Move }, ] ) knigthMovementTest.movement.updateMoves(); - let k = knigthMovementTest.movement.legalMoves - for(let move of moves) { + for (const move of moves) { expect(knigthMovementTest.movement.legalMoves).toContainEqual(move); } - for(let move of moves) { + for (const move of moves) { move.moveType = MoveType.RangedCapture expect(knigthMovementTest.movement.illegalMoves).toContainEqual(move); } }) - test("Enemy and friendly piece",() => { + test("Enemy and friendly piece", () => { const friendly = Generator.createStandardPiece({ - position: new BoardVector2d(3,2), + position: new BoardVector2d(3, 2), playerId: Player.White, board: board }, PieceType.KNIGHT); const enemy = Generator.createStandardPiece({ - position: new BoardVector2d(2,3), + position: new BoardVector2d(2, 3), playerId: Player.Black, board: board }, PieceType.KNIGHT); @@ -117,16 +116,16 @@ describe("Knight", () => { knigthMovementTest.movement.updateMoves(); - expect(knigthMovementTest.movement.illegalMoves).toContainEqual( {destination: new BoardVector2d(3, 2), moveType: MoveType.Move},); - expect(knigthMovementTest.movement.legalMoves).toContainEqual( {destination: new BoardVector2d(2, 3), moveType: MoveType.Move | MoveType.Capture},); - expect(knigthMovementTest.movement.legalMoves).toContainEqual( {destination: new BoardVector2d(2, 3), moveType: MoveType.RangedCapture},); - + expect(knigthMovementTest.movement.illegalMoves).toContainEqual({ destination: new BoardVector2d(3, 2), moveType: MoveType.Move },); + expect(knigthMovementTest.movement.legalMoves).toContainEqual({ destination: new BoardVector2d(2, 3), moveType: MoveType.Move | MoveType.Capture },); + expect(knigthMovementTest.movement.legalMoves).toContainEqual({ destination: new BoardVector2d(2, 3), moveType: MoveType.RangedCapture },); + }) } - + ) - }) + }) }) diff --git a/tests/pieces/Mirror.test.ts b/tests/pieces/Mirror.test.ts index 5f91fec..d41e098 100644 --- a/tests/pieces/Mirror.test.ts +++ b/tests/pieces/Mirror.test.ts @@ -17,7 +17,7 @@ describe("Mirror", () => { } ) expect(mirror.direction).toBe(Direction.BottomLeftDiagonal); - expect(() => {mirror.direction = Direction.BottomFile}).toThrow(); + expect(() => { mirror.direction = Direction.BottomFile }).toThrow(); }) test("move", () => { @@ -62,16 +62,16 @@ describe("Mirror", () => { mirror.movement.updateMoves(); const moves: Set> = new Set( [ - {destination: new BoardVector2d(2, 3), moveType: MoveType.Move}, - {destination: new BoardVector2d(3, 3), moveType: MoveType.Move}, - {destination: new BoardVector2d(4, 3), moveType: MoveType.Move}, - {destination: new BoardVector2d(4, 4), moveType: MoveType.Move}, - {destination: new BoardVector2d(4, 5), moveType: MoveType.Move}, - {destination: new BoardVector2d(3, 5), moveType: MoveType.Move}, - {destination: new BoardVector2d(2, 5), moveType: MoveType.Move}, - {destination: new BoardVector2d(2, 4), moveType: MoveType.Move}, - {rotation: Rotation.Clockwise}, - {rotation: Rotation.Anticlockwise} + { destination: new BoardVector2d(2, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 4), moveType: MoveType.Move }, + { rotation: Rotation.Clockwise }, + { rotation: Rotation.Anticlockwise } ] ) for (const move of moves) { @@ -105,8 +105,8 @@ describe("Mirror", () => { ) board.addPieces([friend, enemy]); mirror.movement.updateMoves(); - let m1 = {destination: new BoardVector2d(2, 3), moveType: MoveType.Move} - let m2 = {destination: new BoardVector2d(3, 3), moveType: MoveType.Move | MoveType.Capture} + const m1 = { destination: new BoardVector2d(2, 3), moveType: MoveType.Move } + const m2 = { destination: new BoardVector2d(3, 3), moveType: MoveType.Move | MoveType.Capture } expect(mirror.movement.illegalMoves).toContainEqual(m1); expect(mirror.movement.illegalMoves).toContainEqual(m2); }) diff --git a/tests/pieces/Pawn.test.ts b/tests/pieces/Pawn.test.ts new file mode 100644 index 0000000..c4d94b1 --- /dev/null +++ b/tests/pieces/Pawn.test.ts @@ -0,0 +1,70 @@ +import { Board, Generator, Player } from "@lc/core" +import { Direction } from "geometry/Direction.js"; +import { BoardVector2d } from "geometry/Vector2d.js" + +describe("Pawn", () => { + const board = new Board(8, 8); + test("direction", () => { + const pawn = Generator.createPawn( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board, + enPassantPosition: new BoardVector2d(1, 4), + promotionPosition: new BoardVector2d(1, 7), + direction: Direction.UpperFile + } + ) + pawn.direction = Direction.BottomFile; + expect(pawn.direction).toBe(Direction.BottomFile); + expect(() => pawn.direction = Direction.UpperLeftDiagonal).toThrow(); + }) + + test("isOnEnPassantPosition", () => { + const pawn = Generator.createPawn( + { + position: new BoardVector2d(1, 4), + playerId: Player.White, + board: board, + enPassantPosition: new BoardVector2d(1, 4), + promotionPosition: new BoardVector2d(1, 7), + direction: Direction.UpperFile + } + ) + expect(pawn.isOnEnPassantPosition()).toBeTruthy(); + + pawn.enPassantPosition = new BoardVector2d(1, 5); + expect(pawn.isOnEnPassantPosition()).toBeFalsy(); + + pawn.enPassantPosition = undefined as unknown as BoardVector2d; + expect(() => pawn.enPassantPosition).toThrow() + }) + + test("isOnPromotionPosition", () => { + const pawn = Generator.createPawn( + { + position: new BoardVector2d(1, 7), + playerId: Player.White, + board: board, + enPassantPosition: new BoardVector2d(1, 4), + promotionPosition: new BoardVector2d(1, 7), + direction: Direction.UpperFile + } + ) + expect(pawn.isOnPromotionPosition()).toBeTruthy(); + + pawn.position = new BoardVector2d(2, 7); + expect(pawn.isOnPromotionPosition()).toBeTruthy(); + + pawn.position = new BoardVector2d(2, 6); + expect(pawn.isOnPromotionPosition()).toBeFalsy(); + + pawn.promotionPosition = undefined as unknown as BoardVector2d; + expect(() => pawn.promotionPosition).toThrow(); + }) + describe("movement", () => { + describe("updateMoves", () => { + + }) + }) +}) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 2047076..bb8e928 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,13 +9,25 @@ "removeComments": false, "resolveJsonModule": true, "esModuleInterop": true, - "types": [ "vitest/globals" ], + "types": [ + "vitest/globals" + ], "paths": { - "@lc/core": [ "core/index.ts" ], - "@lc/utils": [ "utils/index.ts" ], - "@lc/geometry": [ "geometry/index.ts" ], - "@lc/pieces": [ "pieces/index.ts" ], - "@lc/piece-movements": [ "pieces/movements/index.ts" ] + "@lc/core": [ + "core/index.ts" + ], + "@lc/utils": [ + "utils/index.ts" + ], + "@lc/geometry": [ + "geometry/index.ts" + ], + "@lc/pieces": [ + "pieces/index.ts" + ], + "@lc/piece-movements": [ + "pieces/movements/index.ts" + ] } }, "include": [ diff --git a/tsconfig.prod.json b/tsconfig.prod.json index e1bfc3e..985d032 100644 --- a/tsconfig.prod.json +++ b/tsconfig.prod.json @@ -1,4 +1,6 @@ { "extends": "./tsconfig.json", - "include": [ "src/**/*" ] + "include": [ + "src/**/*" + ] } \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts index 429488f..0808063 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from "vitest/config"; import tsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig({ - plugins: [ tsconfigPaths() ], + plugins: [tsconfigPaths()], test: { root: './tests', globals: true From 37502db84ecb9a8391f3cb1d2f62cb93ab0a983a Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 1 Oct 2023 01:18:59 +0200 Subject: [PATCH 30/35] Finished tests for `Pawn`. --- .vscode/settings.json | 3 +- src/pieces/Pawn.ts | 51 ++++++----------- src/pieces/Piece.ts | 12 +++- tests/pieces/Pawn.test.ts | 115 +++++++++++++++++++++++++++++++++++++- 4 files changed, 143 insertions(+), 38 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 70347ea..6d954ad 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "vitest.commandLine": "npx vitest" + "vitest.commandLine": "npx vitest", + "editor.tabSize": 2, } diff --git a/src/pieces/Pawn.ts b/src/pieces/Pawn.ts index 1d735ce..c31c693 100644 --- a/src/pieces/Pawn.ts +++ b/src/pieces/Pawn.ts @@ -49,7 +49,7 @@ export class Pawn extends DirectedPiece { if (this._enPassantPosition === undefined) { throw new Error("enPassantPosition is not initialised."); } - return this._enPassantPosition!.equals(this.position); + return this._enPassantPosition!.y === this.position.y; } public isOnPromotionPosition(): boolean { @@ -92,12 +92,7 @@ export class PawnMovement extends PieceMovement { destination: piece.position.add(direction) as BoardVector2d, moveType: MoveType.Move } - if (board.canMoveTo(piece.position.add(direction), piece, CaptureOptions.NoCapture)) { - this.legalMoves.push(move); - } - else { - this.illegalMoves.push(move); - } + this.appendToMovePredictionType(board.canMoveTo(piece.position.add(direction), piece, CaptureOptions.NoCapture), move) } // Advance 2 squares @@ -106,16 +101,11 @@ export class PawnMovement extends PieceMovement { destination: piece.position.add(direction.mul(2)) as BoardVector2d, moveType: MoveType.Move } - if ( + this.appendToMovePredictionType( !piece.wasMoved() && board.canMoveTo(piece.position.add(direction.mul(2)), piece, CaptureOptions.NoCapture) && this.legalMoves.length > 0 - ) { - this.legalMoves.push(move); - } - else { - this.illegalMoves.push(move); - } + ,move) } // Capture @@ -123,34 +113,27 @@ export class PawnMovement extends PieceMovement { const position: BoardVector2d = piece.position.add(increment); const move: Partial = { destination: position, - moveType: MoveType.Move & MoveType.Capture + moveType: MoveType.Move | MoveType.Capture } if (!board.isOutOfBounds(position)) { - if (!board.canMoveTo(position, piece, CaptureOptions.RequiredCapture)) { // Additional data - this.legalMoves.push(move); - } - else { - this.illegalMoves.push(move); - } + this.appendToMovePredictionType(board.canMoveTo(position, piece, CaptureOptions.RequiredCapture), move); } + } // En Passant - if (piece.isOnEnPassantPosition()) { - for (const position of captureDeltas) { - const tmpPosition: BoardVector2d = piece.position.add(position); - const move: Partial = { - destination: position, - moveType: MoveType.Move | MoveType.Capture - } - if (this.isEnPassantLegal(tmpPosition)) { - this.legalMoves.push(move); - } - else { - this.illegalMoves.push(move); - } + + for (const increment of captureDeltas) { + const position: BoardVector2d = piece.position.add(increment); + const move: Partial = { + destination: position, + moveType: MoveType.Move | MoveType.Capture | MoveType.EnPassant + } + if (!board.isOutOfBounds(position)) { + this.appendToMovePredictionType(this.isEnPassantLegal(position), move); } } + // Promotion flag const commonMoves: Partial[] = [...this.legalMoves, ...this.illegalMoves]; diff --git a/src/pieces/Piece.ts b/src/pieces/Piece.ts index 4d76fee..5b56542 100644 --- a/src/pieces/Piece.ts +++ b/src/pieces/Piece.ts @@ -41,14 +41,14 @@ export abstract class Piece { protected abstract initType(): void; public get type(): PieceType { - if (!this._type) { + if (this._type === undefined) { throw new Error("Piece type is not initialised."); } return this._type; } public get movement(): PieceMovement { - if (!this._movement) { + if (this._movement === undefined) { throw new Error("Piece movement is not initialised."); } return this._movement; @@ -109,6 +109,14 @@ export abstract class PieceMovement { this.legalMoves.length = 0; this.illegalMoves.length = 0; } + protected appendToMovePredictionType(isLegal: boolean, move: Partial): void { + if (isLegal) { + this.legalMoves.push(move); + } + else { + this.illegalMoves.push(move); + } + } public abstract updateMoves(): void; } diff --git a/tests/pieces/Pawn.test.ts b/tests/pieces/Pawn.test.ts index c4d94b1..508e0e4 100644 --- a/tests/pieces/Pawn.test.ts +++ b/tests/pieces/Pawn.test.ts @@ -1,6 +1,7 @@ -import { Board, Generator, Player } from "@lc/core" +import { Board, Generator, Move, MoveType, Player } from "@lc/core" import { Direction } from "geometry/Direction.js"; import { BoardVector2d } from "geometry/Vector2d.js" +import { PieceType } from "pieces/Piece.js"; describe("Pawn", () => { const board = new Board(8, 8); @@ -64,6 +65,118 @@ describe("Pawn", () => { }) describe("movement", () => { describe("updateMoves", () => { + test("No other pieces", () => { + const pawn = Generator.createPawn( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board, + enPassantPosition: new BoardVector2d(1, 4), + promotionPosition: new BoardVector2d(1, 7), + direction: Direction.UpperFile + } + ) + + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(1, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 3), moveType: MoveType.Move }, + ]) + const movesIllegal: Set> = new Set( + [ + { destination: new BoardVector2d(2, 2), moveType: MoveType.Move | MoveType.Capture }, + { destination: new BoardVector2d(0, 2), moveType: MoveType.Move | MoveType.Capture }, + // { destination: new BoardVector2d(2, 2), moveType: MoveType.Move | MoveType.Capture | MoveType.EnPassant }, + // { destination: new BoardVector2d(0, 2), moveType: MoveType.Move | MoveType.Capture | MoveType.EnPassant }, + ] + ) + pawn.movement.updateMoves(); + for (const singleMove of movesLegal) { + expect(pawn.movement.legalMoves).toContainEqual(singleMove); + } + for (const singleMove of movesIllegal) { + expect(pawn.movement.illegalMoves).toContainEqual(singleMove); + } + }) + test("Enemy pawn",() => { + const enemyPawn = Generator.createPawn( + { + position: new BoardVector2d(2, 6), + playerId: Player.Black, + board: board, + enPassantPosition: new BoardVector2d(2, 3), + promotionPosition: new BoardVector2d(2, 0), + direction: Direction.BottomFile + } + ); + const enemyPawnOpposite = Generator.createPawn( + { + position: new BoardVector2d(1, 6), + playerId: Player.Black, + board: board, + enPassantPosition: new BoardVector2d(1, 3), + promotionPosition: new BoardVector2d(1, 0), + direction: Direction.BottomFile + } + ); + const pawn = Generator.createPawn( + { + position: new BoardVector2d(1, 2), + playerId: Player.White, + board: board, + enPassantPosition: new BoardVector2d(1, 4), + promotionPosition: new BoardVector2d(1, 7), + direction: Direction.UpperFile + } + ); + + let move = { destination: new BoardVector2d(2, 6), moveType: MoveType.Move | MoveType.Capture }; + + board.addPiece(enemyPawn); + pawn.position = new BoardVector2d(1, 5); + pawn.movement.updateMoves(); + + expect(pawn.movement.legalMoves).toContainEqual(move) + + move = { destination: new BoardVector2d(1, 6), moveType: MoveType.Move }; + + board.addPiece(enemyPawnOpposite); + pawn.position = new BoardVector2d(1, 5); + pawn.movement.updateMoves(); + + expect(pawn.movement.illegalMoves).toContainEqual(move) + + }) + test("Friendly piece",() => { + const knight = Generator.createStandardPiece( + { + position: new BoardVector2d(2, 3), + playerId: Player.White, + board: board, + }, + PieceType.KNIGHT + ); + const pawn = Generator.createPawn( + { + position: new BoardVector2d(1, 2), + playerId: Player.White, + board: board, + enPassantPosition: new BoardVector2d(1, 4), + promotionPosition: new BoardVector2d(1, 7), + direction: Direction.UpperFile + } + ); + + const move = { destination: new BoardVector2d(2, 3), moveType: MoveType.Move | MoveType.Capture }; + + board.addPiece(knight); + pawn.movement.updateMoves(); + + expect(pawn.movement.illegalMoves).toContainEqual(move) + + + }) + + }) }) From 62f5b09f539c28e6843c16ac27431d69e9b680c7 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 1 Oct 2023 14:38:27 +0200 Subject: [PATCH 31/35] Added tests for `King`. --- src/pieces/King.ts | 70 +++++++++++----------------- tests/pieces/King.test.ts | 97 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 44 deletions(-) create mode 100644 tests/pieces/King.test.ts diff --git a/src/pieces/King.ts b/src/pieces/King.ts index 362158c..4fe16e2 100644 --- a/src/pieces/King.ts +++ b/src/pieces/King.ts @@ -6,36 +6,20 @@ import { CloseRangeMovement } from "@lc/piece-movements"; export class King extends Piece { - private _kingRook?: Piece; - private _queenRook?: Piece; + public kingRook?: Piece; + public queenRook?: Piece; protected override initType(): void { this._type = PieceType.KING; this._movement = new KingMovement(this, this.board); } - public set kingRook(rook: Piece | undefined) { - this._kingRook = this.kingRook; - } - - public set queenRook(rook: Piece | undefined) { - this._queenRook = this.kingRook; - } - - public get kingRook(): Piece { - return this._kingRook!; - } - - public get queenRook(): Piece { - return this._queenRook!; - } - } export class KingMovement extends CloseRangeMovement { public isCastlingLegal(castling: MoveType): boolean { - let potentialRook: Piece; + let potentialRook: Piece | undefined; const piece: King = this.piece as King; if (castling === MoveType.KingSideCastling) { potentialRook = piece.kingRook; @@ -60,9 +44,6 @@ export class KingMovement extends CloseRangeMovement { let currentPosition: BoardVector2d = this.piece.position; for (let i = 0; i < 2; i++) { - // if (this.board.isCheckAt(currentPosition, this.piece.playerId)) { - // return false; - // } currentPosition = currentPosition.add(fromKingUnitVector); } @@ -80,28 +61,29 @@ export class KingMovement extends CloseRangeMovement { public updateMoves(): void { super.updateMoves(); - let move: Partial = { - destination: this.piece.position.add(new BoardVector2d(2, 0)) as BoardVector2d, - moveType: MoveType.Move | MoveType.KingSideCastling - } - if (this.isCastlingLegal(MoveType.KingSideCastling)) { - this.legalMoves.push(move); - } - else { - this.illegalMoves.push(move); - } - - move = { - destination: this.piece.position.add(new BoardVector2d(-2, 0)) as BoardVector2d, - moveType: MoveType.Move & MoveType.QueenSideCastling - } - - if (this.isCastlingLegal(MoveType.QueenSideCastling)) { - this.legalMoves.push(move); - } - else { - this.illegalMoves.push(move); - } + // let move: Partial = { + // destination: this.piece.position.add(new BoardVector2d(2, 0)) as BoardVector2d, + // moveType: MoveType.Move | MoveType.KingSideCastling + // } + + // if (this.isCastlingLegal(MoveType.KingSideCastling)) { + // this.legalMoves.push(move); + // } + // else { + // this.illegalMoves.push(move); + // } + + // move = { + // destination: this.piece.position.add(new BoardVector2d(-2, 0)) as BoardVector2d, + // moveType: MoveType.Move & MoveType.QueenSideCastling + // } + + // if (this.isCastlingLegal(MoveType.QueenSideCastling)) { + // this.legalMoves.push(move); + // } + // else { + // this.illegalMoves.push(move); + // } } } diff --git a/tests/pieces/King.test.ts b/tests/pieces/King.test.ts new file mode 100644 index 0000000..47250ad --- /dev/null +++ b/tests/pieces/King.test.ts @@ -0,0 +1,97 @@ +import { Board, Generator, Move, MoveType, Player } from "@lc/core" +import { BoardVector2d } from "geometry/Vector2d.js" +import { PieceType } from "pieces/Piece.js"; + +describe("King", () => { + const board = new Board(8, 8); + + describe("movement", () => { + describe("updateMoves", () => { + test("No other pieces", () => { + const king = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.KING + ) + + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(1, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 2), moveType: MoveType.Move }, + ]) + + king.movement.updateMoves(); + for (const singleMove of movesLegal) { + expect(king.movement.legalMoves).toContainEqual(singleMove); + } + expect(king.movement.illegalMoves.length).toBe(0); + }) + test("Enemy piece",() => { + const king = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.KING + ) + const enemyKnight = Generator.createStandardPiece( + { + position: new BoardVector2d(2, 2), + playerId: Player.Black, + board: board + }, + PieceType.KNIGHT + ); + + + const move = { destination: new BoardVector2d(2, 2), moveType: MoveType.Move | MoveType.Capture }; + + board.addPiece(enemyKnight); + + king.movement.updateMoves(); + + expect(king.movement.legalMoves).toContainEqual(move); + + }) + + test("Friendly piece",() => { + const king = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.KING + ) + const friendlyKnight = Generator.createStandardPiece( + { + position: new BoardVector2d(2, 2), + playerId: Player.White, + board: board + }, + PieceType.KNIGHT + ); + + + const move = { destination: new BoardVector2d(2, 2), moveType: MoveType.Move }; + + board.addPiece(friendlyKnight); + + king.movement.updateMoves(); + + expect(king.movement.illegalMoves).toContainEqual(move); + + + }) + }) + }) +}) \ No newline at end of file From 5a1daeb5d490f6186b554eefd29d5d21a4435385 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 1 Oct 2023 20:24:16 +0200 Subject: [PATCH 32/35] Added tests for `Rook`. --- src/pieces/movements/LongRangeMovement.ts | 65 +++++++++----- tests/pieces/Rook.test.ts | 104 ++++++++++++++++++++++ 2 files changed, 148 insertions(+), 21 deletions(-) create mode 100644 tests/pieces/Rook.test.ts diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index 3ddf731..d7c6748 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -18,18 +18,21 @@ export class LongRangeMovement extends PieceMovement { this.allLongRangeMoves = this.getAllLongRangeMoves(); for (const direction of this.directions) { - const legal: boolean = true; + let legal: boolean = true; for (const move of this.allLongRangeMoves[direction]!) { - if (Syntax.inAlternative(move.moveType!, MoveType.Capture)) { + if (this.board.isPieceAt(move.destination!) && !this.board.canMoveTo(move.destination!, this.piece, CaptureOptions.RequiredCapture)) { legal = false; } - if (legal) { this.legalMoves.push(move); } else { this.illegalMoves.push(move); } + + if (Syntax.inAlternative(move.moveType!, MoveType.Capture)) { + legal = false; + } } } } @@ -47,28 +50,48 @@ export class LongRangeMovement extends PieceMovement { y = this.piece.position.y, tuple = DirectionUtils.toTuple(direction), step = { x: tuple[0], y: tuple[1] }; - const maxMoveLength = { - x: step.x > 0 ? this.board.width - x : x, - y: step.y > 0 ? this.board.height - y : y - }; + const maxMoveLength: {x: number, y: number} = {} as {x: number, y: number}; + if (step.x > 0) { + maxMoveLength.x = this.board.width - x; + } + else if (step.x < 0){ + maxMoveLength.x = x; + } + else { + maxMoveLength.x = Infinity; + } + + if (step.y > 0) { + maxMoveLength.y = this.board.height - y; + } + else if (step.y < 0){ + maxMoveLength.y = y; + } + else { + maxMoveLength.y = Infinity; + } + const moveLength = Math.min(maxMoveLength.x, maxMoveLength.y); const moveArray: Partial[] = []; - let i = 0; - for (; i < moveLength; i++) { - let vector: BoardVector2d = new BoardVector2d(x + i * step.x, y + i * step.y); - if (this.board.canMoveTo(vector, this.piece, CaptureOptions.NoCapture)) { - moveArray.push({ - destination: vector, - moveType: MoveType.Move - }) - } - else if (this.board.canMoveTo(vector, this.piece, CaptureOptions.RequiredCapture)) { - moveArray.push({ - destination: vector, - moveType: MoveType.Move | MoveType.Capture - }) + let i = 1; + for (; i < moveLength + 1; i++) { + const vector: BoardVector2d = new BoardVector2d(x + i * step.x, y + i * step.y); + if (!this.board.isOutOfBounds(vector)) { + if (this.board.canMoveTo(vector, this.piece, CaptureOptions.RequiredCapture)) { + moveArray.push({ + destination: vector, + moveType: MoveType.Move | MoveType.Capture + }) + } + else { + moveArray.push({ + destination: vector, + moveType: MoveType.Move + }) + } } + } return moveArray } diff --git a/tests/pieces/Rook.test.ts b/tests/pieces/Rook.test.ts new file mode 100644 index 0000000..f3e1400 --- /dev/null +++ b/tests/pieces/Rook.test.ts @@ -0,0 +1,104 @@ +import { Board, Generator, Move, MoveType, Player } from "@lc/core" +import { BoardVector2d } from "geometry/Vector2d.js" +import { PieceType } from "pieces/Piece.js"; + +describe("Rook", () => { + const board = new Board(8, 8); + + describe("movement", () => { + describe("updateMoves", () => { + test("No other pieces", () => { + const rook = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.ROOK + ) + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(1, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(7, 1), moveType: MoveType.Move }, + ]) + + rook.movement.updateMoves(); + for (const singleMove of movesLegal) { + expect(rook.movement.legalMoves).toContainEqual(singleMove); + } + expect(rook.movement.illegalMoves.length).toBe(0); + }) + test("Enemy/friendly piece", () => { + const rook = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.ROOK + ) + const enemyRook = Generator.createStandardPiece( + { + position: new BoardVector2d(6, 1), + playerId: Player.Black, + board: board + }, + PieceType.ROOK + ) + // You're my friend now + const friendlyRook = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 6), + playerId: Player.White, + board: board + }, + PieceType.ROOK + ) + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(1, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 5), moveType: MoveType.Move }, + // { destination: new BoardVector2d(1, 6), moveType: MoveType.Move }, + // { destination: new BoardVector2d(1, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 1), moveType: MoveType.Move | MoveType.Capture }, + ]) + + const movesIllegal = new Set([ + { destination: new BoardVector2d(7, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 7), moveType: MoveType.Move }, + ]); + + board.addPiece(enemyRook); + board.addPiece(friendlyRook); + rook.movement.updateMoves(); + + for (const singleMove of movesLegal) { + expect(rook.movement.legalMoves).toContainEqual(singleMove); + } + for (const singleMove of movesIllegal) { + expect(rook.movement.illegalMoves).toContainEqual(singleMove); + } + + }) + }) + }) +}) \ No newline at end of file From 401fd6b51a7e9dfa10393237069af946d92c8d4e Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 1 Oct 2023 20:54:17 +0200 Subject: [PATCH 33/35] Added tests for `Bishop`. --- src/pieces/movements/LongRangeMovement.ts | 2 +- tests/pieces/Bishop.test.ts | 94 +++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 tests/pieces/Bishop.test.ts diff --git a/src/pieces/movements/LongRangeMovement.ts b/src/pieces/movements/LongRangeMovement.ts index d7c6748..f41939d 100644 --- a/src/pieces/movements/LongRangeMovement.ts +++ b/src/pieces/movements/LongRangeMovement.ts @@ -50,7 +50,7 @@ export class LongRangeMovement extends PieceMovement { y = this.piece.position.y, tuple = DirectionUtils.toTuple(direction), step = { x: tuple[0], y: tuple[1] }; - const maxMoveLength: {x: number, y: number} = {} as {x: number, y: number}; + const maxMoveLength = {} as {x: number, y: number}; if (step.x > 0) { maxMoveLength.x = this.board.width - x; } diff --git a/tests/pieces/Bishop.test.ts b/tests/pieces/Bishop.test.ts new file mode 100644 index 0000000..daaf5a6 --- /dev/null +++ b/tests/pieces/Bishop.test.ts @@ -0,0 +1,94 @@ +import { Board, Generator, Move, MoveType, Player } from "@lc/core" +import { BoardVector2d } from "geometry/Vector2d.js" +import { PieceType } from "pieces/Piece.js"; + +describe("Rook", () => { + const board = new Board(8, 8); + + describe("movement", () => { + describe("updateMoves", () => { + test("No other pieces", () => { + const bishop = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.BISHOP + ) + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(0, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(7, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 0), moveType: MoveType.Move }, + ]) + + bishop.movement.updateMoves(); + for (const singleMove of movesLegal) { + expect(bishop.movement.legalMoves).toContainEqual(singleMove); + } + expect(bishop.movement.illegalMoves.length).toBe(0); + }) + test("Enemy/friendly piece", () => { + const bishop = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.BISHOP + ) + const enemyBishop = Generator.createStandardPiece( + { + position: new BoardVector2d(6, 6), + playerId: Player.Black, + board: board + }, + PieceType.BISHOP + ) + // You're my friend now + const friendlyBishop = Generator.createStandardPiece( + { + position: new BoardVector2d(2, 0), + playerId: Player.White, + board: board + }, + PieceType.BISHOP + ) + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(0, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 6), moveType: MoveType.Move | MoveType.Capture }, + // { destination: new BoardVector2d(7, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 2), moveType: MoveType.Move }, + // { destination: new BoardVector2d(2, 0), moveType: MoveType.Move }, + ]) + + const movesIllegal = new Set([ + { destination: new BoardVector2d(7, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 0), moveType: MoveType.Move }, + ]); + + board.addPiece(enemyBishop); + board.addPiece(friendlyBishop); + bishop.movement.updateMoves(); + + for (const singleMove of movesLegal) { + expect(bishop.movement.legalMoves).toContainEqual(singleMove); + } + for (const singleMove of movesIllegal) { + expect(bishop.movement.illegalMoves).toContainEqual(singleMove); + } + + }) + }) + }) +}) \ No newline at end of file From ee9d7981b4efa894f1958b6960e2f5ec078a6a94 Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Sun, 1 Oct 2023 21:00:49 +0200 Subject: [PATCH 34/35] Added tests for `Queen`. --- tests/pieces/Bishop.test.ts | 2 +- tests/pieces/Queen.test.ts | 122 ++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 tests/pieces/Queen.test.ts diff --git a/tests/pieces/Bishop.test.ts b/tests/pieces/Bishop.test.ts index daaf5a6..04d6c99 100644 --- a/tests/pieces/Bishop.test.ts +++ b/tests/pieces/Bishop.test.ts @@ -2,7 +2,7 @@ import { Board, Generator, Move, MoveType, Player } from "@lc/core" import { BoardVector2d } from "geometry/Vector2d.js" import { PieceType } from "pieces/Piece.js"; -describe("Rook", () => { +describe("Bishop", () => { const board = new Board(8, 8); describe("movement", () => { diff --git a/tests/pieces/Queen.test.ts b/tests/pieces/Queen.test.ts new file mode 100644 index 0000000..7392371 --- /dev/null +++ b/tests/pieces/Queen.test.ts @@ -0,0 +1,122 @@ +import { Board, Generator, Move, MoveType, Player } from "@lc/core" +import { BoardVector2d } from "geometry/Vector2d.js" +import { PieceType } from "pieces/Piece.js"; + +describe("Queen", () => { + const board = new Board(8, 8); + + describe("movement", () => { + describe("updateMoves", () => { + test("No other pieces", () => { + const queen = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.QUEEN + ) + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(0, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(7, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(7, 1), moveType: MoveType.Move }, + ]) + + queen.movement.updateMoves(); + for (const singleMove of movesLegal) { + expect(queen.movement.legalMoves).toContainEqual(singleMove); + } + expect(queen.movement.illegalMoves.length).toBe(0); + }) + test("Enemy/friendly piece", () => { + const queen = Generator.createStandardPiece( + { + position: new BoardVector2d(1, 1), + playerId: Player.White, + board: board + }, + PieceType.QUEEN + ) + const enemyBishop = Generator.createStandardPiece( + { + position: new BoardVector2d(6, 6), + playerId: Player.Black, + board: board + }, + PieceType.QUEEN + ) + // You're my friend now + const friendlyBishop = Generator.createStandardPiece( + { + position: new BoardVector2d(2, 0), + playerId: Player.White, + board: board + }, + PieceType.QUEEN + ) + const movesLegal: Set> = new Set([ + { destination: new BoardVector2d(0, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 0), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 2), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 3), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 4), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 5), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 6), moveType: MoveType.Move }, + { destination: new BoardVector2d(1, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(3, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(4, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(5, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(7, 1), moveType: MoveType.Move }, + { destination: new BoardVector2d(6, 6), moveType: MoveType.Move | MoveType.Capture }, + // { destination: new BoardVector2d(7, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(0, 2), moveType: MoveType.Move }, + // { destination: new BoardVector2d(2, 0), moveType: MoveType.Move }, + ]) + + const movesIllegal = new Set([ + { destination: new BoardVector2d(7, 7), moveType: MoveType.Move }, + { destination: new BoardVector2d(2, 0), moveType: MoveType.Move }, + ]); + + board.addPiece(enemyBishop); + board.addPiece(friendlyBishop); + queen.movement.updateMoves(); + + for (const singleMove of movesLegal) { + expect(queen.movement.legalMoves).toContainEqual(singleMove); + } + for (const singleMove of movesIllegal) { + expect(queen.movement.illegalMoves).toContainEqual(singleMove); + } + + }) + }) + }) +}) \ No newline at end of file From 5b11680f73723cd3b94e97ddb31236b6bdc2547e Mon Sep 17 00:00:00 2001 From: kpiotr6 Date: Mon, 2 Oct 2023 21:37:19 +0200 Subject: [PATCH 35/35] Created basic tests for `Board`. --- .vscode/settings.json | 1 + src/core/Board.ts | 48 ++++++--------- src/geometry/Vector2d.ts | 1 - tests/core/Board.test.ts | 122 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 tests/core/Board.test.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 6d954ad..5a1dacb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ { "vitest.commandLine": "npx vitest", "editor.tabSize": 2, + "javascript.preferences.importModuleSpecifier": "non-relative", } diff --git a/src/core/Board.ts b/src/core/Board.ts index 4ae1826..452489f 100644 --- a/src/core/Board.ts +++ b/src/core/Board.ts @@ -24,7 +24,6 @@ export class Board { public readonly height: number; private readonly tiles: Map; private readonly piecesOfType: Map, Set]>; - private readonly kingsProtectors: [Set, Set]; private readonly movesHistory: [Move[], Move[]]; private readonly lasguns!: [Lasgun, Lasgun]; private _lastMove: Move | null; @@ -37,7 +36,6 @@ export class Board { this.height = height; this.tiles = new Map(); this.piecesOfType = new Map, Set]>(); - this.kingsProtectors = [new Set, new Set]; this.movesHistory = [[], []]; this._lastMove = null; @@ -51,6 +49,10 @@ export class Board { // this.checkManager } + public get lastMove(): Move | null { + return this._lastMove; + } + public getPiecesOfPlayer(playerId: number): Set { let playerPieces: Set = new Set; for (const type in PieceType) { @@ -60,31 +62,24 @@ export class Board { return playerPieces; } - public getKingProtectors(playerId: number): Set { - return this.kingsProtectors[playerId]; - } - public isOutOfBounds(destination: BoardVector2d): boolean { - return destination.x < 0 || destination.x >= this.width || destination.y < 0 || destination.y >= this.height; + public getPiece(position: BoardVector2d): Piece | null { + return this.tiles.get(position.toString()) ?? null; } - public changePosition(newPosition: BoardVector2d, piece: Piece) { - this.removePiece(piece); - this.tiles.set(newPosition.toString(), piece); - piece.position = newPosition; + public getPiecesOfType(playerId: number, pieceType: PieceType): Set { + return this.piecesOfType.get(pieceType)![playerId]; } - public getPiece(position: BoardVector2d): Piece | null { - return this.tiles.get(position.toString()) ?? null; + public isOutOfBounds(destination: BoardVector2d): boolean { + return destination.x < 0 || destination.x >= this.width || destination.y < 0 || destination.y >= this.height; } public isPieceAt(positon: BoardVector2d): boolean { return this.getPiece(positon) !== null; } - public addPieces(pieces: Piece[]): void { - for (const piece of pieces) { - this.addPiece(piece); - } + public isCheckAt(/* position: BoardVector2d, playerId: number */): boolean { + return false; } public addPiece(piece: Piece): void { @@ -95,12 +90,15 @@ export class Board { this.piecesOfType.get(piece.type)![piece.playerId].add(piece); } + public addPieces(pieces: Piece[]): void { + for (const piece of pieces) { + this.addPiece(piece); + } + } + public removePiece(piece: Piece): void { this.tiles.delete(piece.position.toString()); this.piecesOfType.get(piece.type)![piece.playerId].delete(piece); - for (const protectors of this.kingsProtectors) { - protectors.delete(piece); - } } public shiftPiece(origin: BoardVector2d, destination: BoardVector2d) { @@ -152,9 +150,7 @@ export class Board { return false; } - public getPiecesOfType(playerId: number, pieceType: PieceType): Set { - return this.piecesOfType.get(pieceType)![playerId]; - } + private isMoveCommandLegal(move: MoveCommand, playerId: Player): boolean { const pieceToMove: Piece | null = this.getPiece(move.origin); @@ -277,12 +273,6 @@ export class Board { } - public get lastMove(): Move | null { - return this._lastMove; - } - public isCheckAt(/* position: BoardVector2d, playerId: number */): boolean { - return false; - } } \ No newline at end of file diff --git a/src/geometry/Vector2d.ts b/src/geometry/Vector2d.ts index f2f3a3e..de6b5f7 100644 --- a/src/geometry/Vector2d.ts +++ b/src/geometry/Vector2d.ts @@ -32,7 +32,6 @@ export class Vector2d { * its subclasses. */ public readonly y: number; - public l = Vector2d /** * Basic constructor that allows to create new `Vector2d` object. diff --git a/tests/core/Board.test.ts b/tests/core/Board.test.ts new file mode 100644 index 0000000..1fc55bb --- /dev/null +++ b/tests/core/Board.test.ts @@ -0,0 +1,122 @@ +import { Generator, Player } from "@lc/core"; +import { Board } from "@lc/core" +import { BoardVector2d } from "@lc/geometry"; +import { Piece, PieceType } from "@lc/pieces"; + + +describe("Board", () => { + const size = 8; + const board = new Board(size, size); + const types = [ + PieceType.BISHOP, + PieceType.KING, + PieceType.KNIGHT, + PieceType.QUEEN, + PieceType.ROOK + ] + const both = [new Set, new Set]; + const ofType = new Map>(); + const all: Piece[] = []; + for (const type of types) { + ofType.set(type, new Set); + } + for (let i = 0; i < size; i++) { + const piece = Generator.createStandardPiece( + { + playerId: i % 2, + board: board, + position: new BoardVector2d(i, i) + }, + types[i % 5] + ) + both[piece.playerId].add(piece); + ofType.get(piece.type)!.add(piece); + board.addPiece(piece); + all.push(piece); + } + test("getPiecesOfPlayer", () => { + expect(board.getPiecesOfPlayer(Player.Black).size).toBe(4); + expect(board.getPiecesOfPlayer(Player.White).size).toBe(4); + }) + test("getPiece", () => { + expect(board.getPiece(new BoardVector2d(0, 0))).toStrictEqual(all[0]); + expect(board.getPiece(new BoardVector2d(1, 2))).toBe(null); + }) + test("getPiecesOfType", () => { + expect(board.getPiecesOfType(Player.White,PieceType.BISHOP).size).toBe(1); + expect(board.getPiecesOfType(Player.White,PieceType.PAWN).size).toBe(0); + }) + test("isOutOfBounds", () => { + expect(board.isOutOfBounds(new BoardVector2d(7, 10))).toBeTruthy(); + expect(board.isOutOfBounds(new BoardVector2d(0, 0))).toBeFalsy(); + expect(board.isOutOfBounds(new BoardVector2d(5, 5))).toBeFalsy(); + }) + test("isPieceAt", () => { + expect(board.isPieceAt(new BoardVector2d(1, 1))).toBeTruthy(); + expect(board.isPieceAt(new BoardVector2d(1, 0))).toBeFalsy(); + }) + test("addPiece",() => { + const queen = Generator.createStandardPiece( + { + playerId: Player.White, + position: new BoardVector2d(1, 1), + board: board + }, + PieceType.QUEEN + ) + expect(() => (board.addPiece(queen))).toThrow(); + queen.position = new BoardVector2d(5, 2); + board.addPiece(queen); + expect(board.isPieceAt(queen.position)).toBeTruthy() + }) + test("addPieces",() => { + const queen = Generator.createStandardPiece( + { + playerId: Player.White, + position: new BoardVector2d(6, 3), + board: board + }, + PieceType.QUEEN + ) + const knight = Generator.createStandardPiece( + { + playerId: Player.Black, + position: new BoardVector2d(2, 3), + board: board + }, + PieceType.KNIGHT + ) + board.addPieces([queen, knight]); + expect(board.isPieceAt(queen.position)).toBeTruthy(); + expect(board.isPieceAt(knight.position)).toBeTruthy() + }) + test("removePiece",() => { + const knight = Generator.createStandardPiece( + { + playerId: Player.Black, + position: new BoardVector2d(5, 7), + board: board + }, + PieceType.KNIGHT + ) + board.addPiece(knight); + board.removePiece(knight); + expect(board.isPieceAt(knight.position)).toBeFalsy(); + }) + test("shiftPiece",() => { + const knight = Generator.createStandardPiece( + { + playerId: Player.Black, + position: new BoardVector2d(1, 7), + board: board + }, + PieceType.KNIGHT + ) + board.addPiece(knight) + expect(() => (board.shiftPiece(new BoardVector2d(1, 7), new BoardVector2d(6, 6)))).toThrow(); + expect(() => (board.shiftPiece(new BoardVector2d(5, 0), new BoardVector2d(4, 5)))).toThrow(); + board.shiftPiece(new BoardVector2d(1, 7), new BoardVector2d(2, 6)); + expect(board.isPieceAt(new BoardVector2d(1, 7))).toBeFalsy(); + expect(board.isPieceAt(new BoardVector2d(2, 6))).toBeTruthy(); + }) +}) \ No newline at end of file