Compare commits
9 commits
8cad1eeea5
...
6c00f42ed3
Author | SHA1 | Date | |
---|---|---|---|
6c00f42ed3 |
|||
39feba7d1d |
|||
9639525ddd | |||
b25f76dde8 |
|||
aa7cf00ebb |
|||
bd1d8f8339 | |||
|
3e1c15e023 | ||
|
78b8f4696c | ||
|
b7a8627bcf |
7 changed files with 283 additions and 28 deletions
15
.gitea/workflows/stale.yml
Normal file
15
.gitea/workflows/stale.yml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
name: "Close stale issues and PRs"
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "@hourly"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
stale-pr-message: "Will be closed in x days bc yo mom is a bitch. im not telling you when it will be closed fuckface"
|
||||||
|
days-before-pr-stale: 2
|
||||||
|
days-before-pr-close: 3
|
|
@ -4,8 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||||
import de.szut.casino.user.UserEntity;
|
import de.szut.casino.user.UserEntity;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import jakarta.validation.constraints.Positive;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
|
@ -5,12 +5,14 @@ import jakarta.validation.constraints.DecimalMax;
|
||||||
import jakarta.validation.constraints.DecimalMin;
|
import jakarta.validation.constraints.DecimalMin;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
public class DiceDto extends BetDto {
|
public class DiceDto extends BetDto {
|
||||||
private boolean rollOver;
|
private boolean rollOver;
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,11 @@ import java.util.Random;
|
||||||
@Service
|
@Service
|
||||||
public class DiceService {
|
public class DiceService {
|
||||||
private static final int MAX_DICE_VALUE = 100;
|
private static final int MAX_DICE_VALUE = 100;
|
||||||
private final Random random = new Random();
|
private final Random random;
|
||||||
private final BalanceService balanceService;
|
private final BalanceService balanceService;
|
||||||
|
|
||||||
public DiceService(BalanceService balanceService) {
|
public DiceService(Random random, BalanceService balanceService) {
|
||||||
|
this.random = random;
|
||||||
this.balanceService = balanceService;
|
this.balanceService = balanceService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
251
backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java
Normal file
251
backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
package de.szut.casino.dice;
|
||||||
|
|
||||||
|
import de.szut.casino.shared.service.BalanceService;
|
||||||
|
import de.szut.casino.user.UserEntity;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class DiceServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BalanceService balanceService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Random random;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private DiceService diceService;
|
||||||
|
|
||||||
|
private UserEntity user;
|
||||||
|
private DiceDto diceDto;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
user = new UserEntity();
|
||||||
|
user.setId(1L);
|
||||||
|
user.setBalance(BigDecimal.valueOf(1000));
|
||||||
|
|
||||||
|
diceDto = new DiceDto();
|
||||||
|
diceDto.setBetAmount(BigDecimal.valueOf(10));
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(50));
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollOver_win() {
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(50));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(55);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(56), result.getRolledValue());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollOver_lose() {
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(50));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(49);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertFalse(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(50), result.getRolledValue());
|
||||||
|
assertEquals(BigDecimal.ZERO, result.getPayout());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollUnder_win() {
|
||||||
|
diceDto.setRollOver(false);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(50));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(48);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(49), result.getRolledValue());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollUnder_lose() {
|
||||||
|
diceDto.setRollOver(false);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(50));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(50);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertFalse(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(51), result.getRolledValue());
|
||||||
|
assertEquals(BigDecimal.ZERO, result.getPayout());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollOver_targetValueOne_rolledOne_lose() {
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(1));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(0);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertFalse(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(1), result.getRolledValue());
|
||||||
|
assertEquals(BigDecimal.ZERO, result.getPayout());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollOver_targetValueOne_rolledTwo_win() {
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(1));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(1);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(2), result.getRolledValue());
|
||||||
|
// Win chance for target 1 (roll over) is 99. Multiplier = (100-1)/99 = 1
|
||||||
|
assertEquals(diceDto.getBetAmount().stripTrailingZeros(), result.getPayout().stripTrailingZeros());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollUnder_targetValueOne_alwaysLose_winChanceZero() {
|
||||||
|
diceDto.setRollOver(false);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(1));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(0);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertFalse(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(1), result.getRolledValue());
|
||||||
|
assertEquals(BigDecimal.ZERO, result.getPayout());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollOver_targetValueNinetyNine_rolledHundred_win() {
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(99));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(99);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(100), result.getRolledValue());
|
||||||
|
// Win chance for target 99 (roll over) is 1. Multiplier = (100-1)/1 = 99
|
||||||
|
assertEquals(diceDto.getBetAmount().multiply(BigDecimal.valueOf(99)).stripTrailingZeros(), result.getPayout().stripTrailingZeros());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollUnder_targetValueNinetyNine_rolledNinetyEight_win() {
|
||||||
|
diceDto.setRollOver(false);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(99));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(97);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(98), result.getRolledValue());
|
||||||
|
// Win chance for target 99 (roll under) is 98. Multiplier = (100-1)/98 = 99/98
|
||||||
|
assertEquals(diceDto.getBetAmount().multiply(BigDecimal.valueOf(99).divide(BigDecimal.valueOf(98), 4, RoundingMode.HALF_UP)), result.getPayout());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollOver_targetValueOneHundred_alwaysLose_winChanceZero() {
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(100));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(99);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertFalse(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(100), result.getRolledValue());
|
||||||
|
assertEquals(BigDecimal.ZERO, result.getPayout());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_rollUnder_targetValueOneHundred_rolledNinetyNine_win() {
|
||||||
|
diceDto.setRollOver(false);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(100));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(98);
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(99), result.getRolledValue());
|
||||||
|
// Win chance for target 100 (roll under) is 99. Multiplier = (100-1)/99 = 1
|
||||||
|
assertEquals(diceDto.getBetAmount().stripTrailingZeros(), result.getPayout().stripTrailingZeros());
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_payoutCalculationCorrect() {
|
||||||
|
diceDto.setRollOver(true);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(75));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(75);
|
||||||
|
|
||||||
|
// Multiplier for win chance 25: (100-1)/25 = 99/25 = 3.96
|
||||||
|
// Payout: 10 * 3.96 = 39.6
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(39.6).stripTrailingZeros(), result.getPayout().stripTrailingZeros());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_payoutCalculationCorrect_rollUnder() {
|
||||||
|
diceDto.setRollOver(false);
|
||||||
|
diceDto.setTargetValue(BigDecimal.valueOf(25));
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(0);
|
||||||
|
|
||||||
|
// Multiplier for win chance 24: (100-1)/24 = 99/24 = 4.125
|
||||||
|
// Payout: 10 * 4.125 = 41.25
|
||||||
|
|
||||||
|
DiceResult result = diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
assertTrue(result.isWin());
|
||||||
|
assertEquals(BigDecimal.valueOf(41.25).stripTrailingZeros(), result.getPayout().stripTrailingZeros());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void play_betAmountSubtracted() {
|
||||||
|
when(random.nextInt(anyInt())).thenReturn(50);
|
||||||
|
|
||||||
|
diceService.play(user, diceDto);
|
||||||
|
|
||||||
|
verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount());
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,7 @@
|
||||||
"@angular/cli": "^19.2.5",
|
"@angular/cli": "^19.2.5",
|
||||||
"@angular/compiler-cli": "^19.0.0",
|
"@angular/compiler-cli": "^19.0.0",
|
||||||
"@types/jasmine": "~5.1.0",
|
"@types/jasmine": "~5.1.0",
|
||||||
"angular-eslint": "19.6.0",
|
"angular-eslint": "19.7.0",
|
||||||
"eslint": "^9.25.1",
|
"eslint": "^9.25.1",
|
||||||
"jasmine-core": "~5.7.0",
|
"jasmine-core": "~5.7.0",
|
||||||
"karma": "~6.4.0",
|
"karma": "~6.4.0",
|
||||||
|
@ -62,19 +62,19 @@
|
||||||
|
|
||||||
"@angular-devkit/schematics": ["@angular-devkit/schematics@19.2.6", "", { "dependencies": { "@angular-devkit/core": "19.2.6", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "5.4.1", "rxjs": "7.8.1" } }, "sha512-YTAxNnT++5eflx19OUHmOWu597/TbTel+QARiZCv1xQw99+X8DCKKOUXtqBRd53CAHlREDI33Rn/JLY3NYgMLQ=="],
|
"@angular-devkit/schematics": ["@angular-devkit/schematics@19.2.6", "", { "dependencies": { "@angular-devkit/core": "19.2.6", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "5.4.1", "rxjs": "7.8.1" } }, "sha512-YTAxNnT++5eflx19OUHmOWu597/TbTel+QARiZCv1xQw99+X8DCKKOUXtqBRd53CAHlREDI33Rn/JLY3NYgMLQ=="],
|
||||||
|
|
||||||
"@angular-eslint/builder": ["@angular-eslint/builder@19.6.0", "", { "dependencies": { "@angular-devkit/architect": ">= 0.1900.0 < 0.2000.0", "@angular-devkit/core": ">= 19.0.0 < 20.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-hUdYS1mSB09b5ABi2tuWeMTVprYHW+x6KmeAFJfXC6aMOa4NYQBdetIjOLwr7qUDlq1S/+2+HiX/FO76FPHClw=="],
|
"@angular-eslint/builder": ["@angular-eslint/builder@19.7.0", "", { "dependencies": { "@angular-devkit/architect": ">= 0.1900.0 < 0.2000.0", "@angular-devkit/core": ">= 19.0.0 < 20.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-tnanOOwUKzeS0FwhjJd/dNeb8gVzcF0+cI4/ZgohOjZxm8fZqtzXcKfGS1C7KsR/CPHBdY9cbF1OVPJEarrnsQ=="],
|
||||||
|
|
||||||
"@angular-eslint/bundled-angular-compiler": ["@angular-eslint/bundled-angular-compiler@19.6.0", "", {}, "sha512-ro+seaTAg5GvtJ72uWEEnP9J5mT0vtgdqH6YMrmMt4pZbSZxvkLfLjZGkXo/HjVDVcCjPnmZeMwKN+uoEc27Jg=="],
|
"@angular-eslint/bundled-angular-compiler": ["@angular-eslint/bundled-angular-compiler@19.7.0", "", {}, "sha512-95Z30MhQ93s1G1mEnsVuG45te82I+6dp8Y0MamRgyh4OZvOajmEXpvCwT+hkr/9WAroLZ7p5nlMbzAA+OXZ+YQ=="],
|
||||||
|
|
||||||
"@angular-eslint/eslint-plugin": ["@angular-eslint/eslint-plugin@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0", "@angular-eslint/utils": "19.6.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-IOMfFi/rPNrPwxZwIGTqWw0C5pC2Facwg3llmJoQFq8w2sUE0nNBL5uSQv5dT8s6ucum4g+RFNYHNe20SEOvRw=="],
|
"@angular-eslint/eslint-plugin": ["@angular-eslint/eslint-plugin@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0", "@angular-eslint/utils": "19.7.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-M8OqDgiFSSxMinW/Gkdrvy2O2Oeo8bGk1DQc0s3aEKB44PYAjXC49jMSihvdozqtu1qjPBcTN5kvUwzwN5oWxA=="],
|
||||||
|
|
||||||
"@angular-eslint/eslint-plugin-template": ["@angular-eslint/eslint-plugin-template@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0", "@angular-eslint/utils": "19.6.0", "aria-query": "5.3.2", "axobject-query": "4.1.0" }, "peerDependencies": { "@typescript-eslint/types": "^7.11.0 || ^8.0.0", "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-SDGbNSCUuPmqVesy5SvRE2MV7AKvvA/bVJwL9Fz5KYCHYxJz1rrJ8FknjWAfmg0qO2TMs1ZI9hov8JL+Bc4BBw=="],
|
"@angular-eslint/eslint-plugin-template": ["@angular-eslint/eslint-plugin-template@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0", "@angular-eslint/utils": "19.7.0", "aria-query": "5.3.2", "axobject-query": "4.1.0" }, "peerDependencies": { "@angular-eslint/template-parser": "19.7.0", "@typescript-eslint/types": "^7.11.0 || ^8.0.0", "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-gR+RH7ZDFctupUsCcxWWloD0I7m9pE8HiDX9TrwrSQbNgzvp/P7+Mgv709rR1Jju9GSVavPh7EG3VgiCyR2m5w=="],
|
||||||
|
|
||||||
"@angular-eslint/schematics": ["@angular-eslint/schematics@19.6.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/eslint-plugin": "19.6.0", "@angular-eslint/eslint-plugin-template": "19.6.0", "ignore": "7.0.4", "semver": "7.7.2", "strip-json-comments": "3.1.1" } }, "sha512-lJzwHju7bhJ3p+SZnY0JVwGjxF2q68gUdOYhdU62pglfYkS5lm+A5LM/VznRvdpZOH69vvZ9gizQ8W1P525cdw=="],
|
"@angular-eslint/schematics": ["@angular-eslint/schematics@19.7.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/eslint-plugin": "19.7.0", "@angular-eslint/eslint-plugin-template": "19.7.0", "ignore": "7.0.5", "semver": "7.7.2", "strip-json-comments": "3.1.1" } }, "sha512-07j/qXfSLvLsUq8a7WJlGYgcgfVEJ1ODuwJ2R4686dh2lqZ5GRV75fpdOtOBdC38MILLwd5el+8LfdaIG19Yog=="],
|
||||||
|
|
||||||
"@angular-eslint/template-parser": ["@angular-eslint/template-parser@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0", "eslint-scope": "^8.0.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-NGxXUZkI5lXjoKnmL51C8DoJx8AjwF9sonieC2EVxgXycK2MYAamFWYGHMiVemzFsg1nIv+JvhHITgjSjyC3HQ=="],
|
"@angular-eslint/template-parser": ["@angular-eslint/template-parser@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0", "eslint-scope": "^8.0.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-XLPt6gk8VMOrUO9NWRpXN8zgwJuCDV+9y3KbVnd4WyakO0sOz9SVzktuI4AeY9jWS9/tqU6P8Uj0WZsMVz7F8w=="],
|
||||||
|
|
||||||
"@angular-eslint/utils": ["@angular-eslint/utils@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-ygtsmRKHNqrzG2mpUj1XwLNRoG+ikYkizsOuq5xPRM8o6dCw03H5eel4s7hnXT4c09WbpnoaVNi9O3xFLIETJQ=="],
|
"@angular-eslint/utils": ["@angular-eslint/utils@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-F4JcZtc2/Wl0AwRaeUywupPHdaOtldpwfrGYewT1dYDikFafyDk5T6E9JYv/HgLXROPNMDVPFquwikNvAPlfAg=="],
|
||||||
|
|
||||||
"@angular/animations": ["@angular/animations@19.2.5", "", { "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/common": "19.2.5", "@angular/core": "19.2.5" } }, "sha512-m4RtY3z1JuHFCh6OrOHxo25oKEigBDdR/XmdCfXIwfTiObZzNA7VQhysgdrb9IISO99kXbjZUYKDtLzgWT8Klg=="],
|
"@angular/animations": ["@angular/animations@19.2.5", "", { "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/common": "19.2.5", "@angular/core": "19.2.5" } }, "sha512-m4RtY3z1JuHFCh6OrOHxo25oKEigBDdR/XmdCfXIwfTiObZzNA7VQhysgdrb9IISO99kXbjZUYKDtLzgWT8Klg=="],
|
||||||
|
|
||||||
|
@ -692,7 +692,7 @@
|
||||||
|
|
||||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.33.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.33.0", "@typescript-eslint/utils": "8.33.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ=="],
|
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.33.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.33.0", "@typescript-eslint/utils": "8.33.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.32.1", "", {}, "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg=="],
|
"@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.33.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.33.0", "@typescript-eslint/tsconfig-utils": "8.33.0", "@typescript-eslint/types": "8.33.0", "@typescript-eslint/visitor-keys": "8.33.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ=="],
|
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.33.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.33.0", "@typescript-eslint/tsconfig-utils": "8.33.0", "@typescript-eslint/types": "8.33.0", "@typescript-eslint/visitor-keys": "8.33.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ=="],
|
||||||
|
|
||||||
|
@ -756,7 +756,7 @@
|
||||||
|
|
||||||
"ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="],
|
"ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="],
|
||||||
|
|
||||||
"angular-eslint": ["angular-eslint@19.6.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/builder": "19.6.0", "@angular-eslint/eslint-plugin": "19.6.0", "@angular-eslint/eslint-plugin-template": "19.6.0", "@angular-eslint/schematics": "19.6.0", "@angular-eslint/template-parser": "19.6.0", "@typescript-eslint/types": "^8.0.0", "@typescript-eslint/utils": "^8.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*", "typescript-eslint": "^8.0.0" } }, "sha512-9qfP6rR6De5xe9WyviD9Vdpg2F3iHTlo7T1129ms0AQXrG9/U/upIQmNUN+Jz9CiJcHDUsniyd+EL8hjuNYnOg=="],
|
"angular-eslint": ["angular-eslint@19.7.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/builder": "19.7.0", "@angular-eslint/eslint-plugin": "19.7.0", "@angular-eslint/eslint-plugin-template": "19.7.0", "@angular-eslint/schematics": "19.7.0", "@angular-eslint/template-parser": "19.7.0", "@typescript-eslint/types": "^8.0.0", "@typescript-eslint/utils": "^8.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*", "typescript-eslint": "^8.0.0" } }, "sha512-ujlc8CR40RYEWUctpVEg41ZCtmKnWeJH0mzORhzf0NVZb6FLhoNhmDPr1byw4Bcxzl0DAoNgKBhJymt6FNL6Rw=="],
|
||||||
|
|
||||||
"ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
|
"ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
|
||||||
|
|
||||||
|
@ -1884,7 +1884,7 @@
|
||||||
|
|
||||||
"@angular-devkit/schematics/rxjs": ["rxjs@7.8.1", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg=="],
|
"@angular-devkit/schematics/rxjs": ["rxjs@7.8.1", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg=="],
|
||||||
|
|
||||||
"@angular-eslint/schematics/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="],
|
"@angular-eslint/schematics/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||||
|
|
||||||
"@angular-eslint/schematics/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
"@angular-eslint/schematics/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||||
|
|
||||||
|
@ -1972,24 +1972,12 @@
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="],
|
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||||
|
|
||||||
"@typescript-eslint/utils/@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
|
"@typescript-eslint/utils/@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
|
||||||
|
|
||||||
"@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="],
|
|
||||||
|
|
||||||
"accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
"accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
||||||
|
|
||||||
"adjust-sourcemap-loader/loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="],
|
"adjust-sourcemap-loader/loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="],
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
"@angular/cli": "^19.2.5",
|
"@angular/cli": "^19.2.5",
|
||||||
"@angular/compiler-cli": "^19.0.0",
|
"@angular/compiler-cli": "^19.0.0",
|
||||||
"@types/jasmine": "~5.1.0",
|
"@types/jasmine": "~5.1.0",
|
||||||
"angular-eslint": "19.6.0",
|
"angular-eslint": "19.7.0",
|
||||||
"eslint": "^9.25.1",
|
"eslint": "^9.25.1",
|
||||||
"jasmine-core": "~5.7.0",
|
"jasmine-core": "~5.7.0",
|
||||||
"karma": "~6.4.0",
|
"karma": "~6.4.0",
|
||||||
|
|
Reference in a new issue