From 43369b2d5960b12bf3a2aea25727514a3632c48f Mon Sep 17 00:00:00 2001 From: AnnaUgrai <149159395+AnnaUgrai@users.noreply.github.com> Date: Sat, 6 Jul 2024 12:23:53 +0200 Subject: [PATCH 01/19] chore: add dependencies for passford validation --- backend/pom.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/backend/pom.xml b/backend/pom.xml index aeaaa19f..ae46c2f8 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -49,6 +49,26 @@ commons-validator 1.9.0 + + org.passay + passay + 1.6.4 + + + org.hibernate + hibernate-validator + 6.0.10.Final + + + + + + + + com.google.guava + guava + r05 + org.postgresql postgresql From 305ca675db1bf74c0e7ef17a9b7782604a38e584 Mon Sep 17 00:00:00 2001 From: AnnaUgrai <149159395+AnnaUgrai@users.noreply.github.com> Date: Sat, 6 Jul 2024 12:24:28 +0200 Subject: [PATCH 02/19] chore: create password strength validation --- .../backend/controller/UserController.java | 18 ++++---- .../backend/dtos/RegisterUserDto.java | 2 + .../services/PasswordConstraintValidator.java | 41 +++++++++++++++++++ .../backend/services/UserServiceImpl.java | 4 ++ .../backend/services/ValidPassword.java | 24 +++++++++++ 5 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index 5ad4e226..79cb2c3a 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -2,8 +2,10 @@ import com.greenfoxacademy.backend.dtos.RegisterUserDto; import com.greenfoxacademy.backend.services.UserService; +import com.greenfoxacademy.backend.services.ValidPassword; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -14,20 +16,20 @@ */ @RestController @RequiredArgsConstructor -@CrossOrigin(origins = "http://localhost:8080") +@CrossOrigin (origins = "http://localhost:8080") public class UserController { private final UserService userService; - - @CrossOrigin(origins = "http://localhost:5173") - @PostMapping("/register") - public ResponseEntity registerUser(@RequestBody RegisterUserDto registerUserDto) { + + @CrossOrigin (origins = "http://localhost:5173") + @PostMapping ("/register") + public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { if (!userService.emailValidation(registerUserDto.getEmail())) { return ResponseEntity.badRequest().body("Email is not valid!"); } else if (userService.existsByEmail(registerUserDto.getEmail())) { return ResponseEntity.badRequest().body("Email is already exist!"); - } else { - userService.register(registerUserDto); - return ResponseEntity.ok().build(); } + userService.register(registerUserDto); + return ResponseEntity.ok().build(); } } + diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java index 44635faa..8c4c2aa2 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java @@ -1,5 +1,6 @@ package com.greenfoxacademy.backend.dtos; +import com.greenfoxacademy.backend.services.ValidPassword; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -14,5 +15,6 @@ public class RegisterUserDto { private String firstName; private String lastName; private String email; + @ValidPassword private String password; } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java new file mode 100644 index 00000000..90f8ed37 --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java @@ -0,0 +1,41 @@ +package com.greenfoxacademy.backend.services; + +import org.passay.*; +import com.google.common.base.Joiner; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.Arrays; + +public class PasswordConstraintValidator implements ConstraintValidator { + + @Override + public void initialize(ValidPassword constraintAnnotation) { + // Initialization code, if required + } + + @Override + public boolean isValid(String password, ConstraintValidatorContext context) { + PasswordValidator validator = new PasswordValidator(Arrays.asList( + new LengthRule(8, 30), +// new UppercaseCharacterRule(1), +// new DigitCharacterRule(1), +// new SpecialCharacterRule(1), +// new NumericalSequenceRule(3, false), +// new AlphabeticalSequenceRule(3, false), +// new QwertySequenceRule(3, false), + new WhitespaceRule() // Disallow whitespace + )); + + RuleResult result = validator.validate(new PasswordData(password)); + if (result.isValid()) { + return true; + } + + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate( + Joiner.on(",").join(validator.getMessages(result))) + .addConstraintViolation(); + return false; + } +} diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java index bcf1afcd..d5fc4882 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java @@ -41,6 +41,10 @@ public Boolean emailValidation(String email) { return EmailValidator.getInstance().isValid(email); } +// public Boolean passwordValidation(String password) { +// return PasswordConstraintValidator.isValid(password); +// } + @Override public boolean existsByEmail(String email) { return userRepository.existsByEmail(email); diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java new file mode 100644 index 00000000..69bb1f96 --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java @@ -0,0 +1,24 @@ +package com.greenfoxacademy.backend.services; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Documented +@Constraint (validatedBy = PasswordConstraintValidator.class) +@Target ({ TYPE, FIELD, ANNOTATION_TYPE }) +@Retention (RUNTIME) +public @interface ValidPassword { + + String message() default "Invalid Password"; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} From 0021dc72475220e761997a61ae759735f729c2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Sat, 6 Jul 2024 13:44:35 +0200 Subject: [PATCH 03/19] chore: definitely not messing up things for watchdog --- backend/pom.xml | 30 +------- .../backend/controller/UserController.java | 52 +++++++++----- .../backend/dtos/RegisterUserDto.java | 19 +++-- .../services/PasswordConstraintValidator.java | 69 ++++++++++--------- .../backend/services/UserServiceImpl.java | 51 +++++++------- .../backend/services/ValidPassword.java | 26 +++---- 6 files changed, 123 insertions(+), 124 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index ae46c2f8..182dc562 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -45,29 +45,8 @@ true - commons-validator - commons-validator - 1.9.0 - - - org.passay - passay - 1.6.4 - - - org.hibernate - hibernate-validator - 6.0.10.Final - - - - - - - - com.google.guava - guava - r05 + org.springframework.boot + spring-boot-starter-validation org.postgresql @@ -103,11 +82,6 @@ org.springframework.boot spring-boot-starter-security - - org.springframework.security - spring-security-test - test - diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index 79cb2c3a..849a8f23 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -2,34 +2,50 @@ import com.greenfoxacademy.backend.dtos.RegisterUserDto; import com.greenfoxacademy.backend.services.UserService; -import com.greenfoxacademy.backend.services.ValidPassword; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + /** * REST controller where endpoints are handled. */ @RestController @RequiredArgsConstructor -@CrossOrigin (origins = "http://localhost:8080") +@CrossOrigin(origins = "http://localhost:8080") public class UserController { - private final UserService userService; - - @CrossOrigin (origins = "http://localhost:5173") - @PostMapping ("/register") - public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { - if (!userService.emailValidation(registerUserDto.getEmail())) { - return ResponseEntity.badRequest().body("Email is not valid!"); - } else if (userService.existsByEmail(registerUserDto.getEmail())) { - return ResponseEntity.badRequest().body("Email is already exist!"); + private final UserService userService; + + @CrossOrigin(origins = "http://localhost:5173") + @PostMapping("/register") + public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { +// if (!userService.emailValidation(registerUserDto.getEmail())) { +// return ResponseEntity.badRequest().body("Email is not valid!"); +// } else if (userService.existsByEmail(registerUserDto.getEmail())) { +// return ResponseEntity.badRequest().body("Email is already exist!"); +// } + userService.register(registerUserDto); + return ResponseEntity.ok().build(); } - userService.register(registerUserDto); - return ResponseEntity.ok().build(); - } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(MethodArgumentNotValidException.class) + public Map handleValidationExceptions(MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + return errors; + } + } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java index 8c4c2aa2..d0f389e4 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java @@ -1,20 +1,25 @@ package com.greenfoxacademy.backend.dtos; import com.greenfoxacademy.backend.services.ValidPassword; +import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; /** * Data Transfer Object for User Entity. */ -@Data @AllArgsConstructor @NoArgsConstructor +@Getter +@Setter public class RegisterUserDto { - private String firstName; - private String lastName; - private String email; - @ValidPassword - private String password; + @NotBlank + private String firstName; + @NotBlank + private String lastName; + private String email; + @ValidPassword + private String password; } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java index 90f8ed37..b49f7655 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java @@ -1,41 +1,42 @@ package com.greenfoxacademy.backend.services; -import org.passay.*; -import com.google.common.base.Joiner; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import java.util.Arrays; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.ArrayList; + public class PasswordConstraintValidator implements ConstraintValidator { - - @Override - public void initialize(ValidPassword constraintAnnotation) { - // Initialization code, if required - } - - @Override - public boolean isValid(String password, ConstraintValidatorContext context) { - PasswordValidator validator = new PasswordValidator(Arrays.asList( - new LengthRule(8, 30), -// new UppercaseCharacterRule(1), -// new DigitCharacterRule(1), -// new SpecialCharacterRule(1), -// new NumericalSequenceRule(3, false), -// new AlphabeticalSequenceRule(3, false), -// new QwertySequenceRule(3, false), - new WhitespaceRule() // Disallow whitespace - )); - - RuleResult result = validator.validate(new PasswordData(password)); - if (result.isValid()) { - return true; + + @Override + public boolean isValid(String password, ConstraintValidatorContext constraintValidatorContext) { + boolean isValid = true; + ArrayList errorMessages = new ArrayList<>(); + if (password.length() < 8) { + errorMessages.add("must be at least 8 characters long"); + isValid = false; + } + if (!password.matches(".*\\S.*")) { + errorMessages.add("must not contain whitespace"); + isValid = false; + } + if (!password.matches(".*\\d.*")) { + errorMessages.add("must contain at least one digit"); + isValid = false; + } + if (!password.matches(".*[A-Z].*")) { + errorMessages.add("must contain at least one uppercase letter"); + isValid = false; + } + if (!password.matches(".*[a-z].*")) { + errorMessages.add("must contain at least one lowercase letter"); + isValid = false; + } + if (!isValid) { + constraintValidatorContext.disableDefaultConstraintViolation(); + constraintValidatorContext.buildConstraintViolationWithTemplate("Invalid password: " + String.join(", ", errorMessages)).addConstraintViolation(); + } + return isValid; } - - context.disableDefaultConstraintViolation(); - context.buildConstraintViolationWithTemplate( - Joiner.on(",").join(validator.getMessages(result))) - .addConstraintViolation(); - return false; - } } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java index d5fc4882..f97483ce 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java @@ -4,7 +4,7 @@ import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import lombok.RequiredArgsConstructor; -import org.apache.commons.validator.routines.EmailValidator; +//import org.apache.commons.validator.routines.EmailValidator; import org.modelmapper.ModelMapper; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -15,38 +15,39 @@ @Service @RequiredArgsConstructor public class UserServiceImpl implements UserService { - private final PasswordEncoder passwordEncoder; + private final PasswordEncoder passwordEncoder; - private final UserRepository userRepository; - private final ModelMapper modelMapper; + private final UserRepository userRepository; + private final ModelMapper modelMapper; - @Override - public void register(RegisterUserDto userDto) { - User user = this.mapToEntity(userDto); - user.setPassword(passwordEncoder.encode(userDto.getPassword())); - userRepository.save(user); - } + @Override + public void register(RegisterUserDto userDto) { + User user = this.mapToEntity(userDto); + user.setPassword(passwordEncoder.encode(userDto.getPassword())); + userRepository.save(user); + } - private RegisterUserDto mapToDto(User user) { - RegisterUserDto registerUserDto = modelMapper.map(user, RegisterUserDto.class); - return registerUserDto; - } + private RegisterUserDto mapToDto(User user) { + RegisterUserDto registerUserDto = modelMapper.map(user, RegisterUserDto.class); + return registerUserDto; + } - private User mapToEntity(RegisterUserDto userDto) { - User user = modelMapper.map(userDto, User.class); - return user; - } + private User mapToEntity(RegisterUserDto userDto) { + User user = modelMapper.map(userDto, User.class); + return user; + } - public Boolean emailValidation(String email) { - return EmailValidator.getInstance().isValid(email); - } + public Boolean emailValidation(String email) { + return true; +// return EmailValidator.getInstance().isValid(email); + } // public Boolean passwordValidation(String password) { // return PasswordConstraintValidator.isValid(password); // } - @Override - public boolean existsByEmail(String email) { - return userRepository.existsByEmail(email); - } + @Override + public boolean existsByEmail(String email) { + return userRepository.existsByEmail(email); + } } \ No newline at end of file diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java index 69bb1f96..cf25978a 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java @@ -1,7 +1,9 @@ package com.greenfoxacademy.backend.services; -import javax.validation.Constraint; -import javax.validation.Payload; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -10,15 +12,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Documented -@Constraint (validatedBy = PasswordConstraintValidator.class) -@Target ({ TYPE, FIELD, ANNOTATION_TYPE }) -@Retention (RUNTIME) +@Constraint(validatedBy = PasswordConstraintValidator.class) +@Target({TYPE, FIELD, ANNOTATION_TYPE}) +@Retention(RUNTIME) public @interface ValidPassword { - - String message() default "Invalid Password"; - - Class[] groups() default {}; - - Class[] payload() default {}; - + + String message() default "Invalid Password"; + + Class[] groups() default {}; + + Class[] payload() default {}; + } From ff201f739e7aadeea7c81fa20c4bc72c108341d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Sat, 6 Jul 2024 13:49:32 +0200 Subject: [PATCH 04/19] fix: reenable email validation --- backend/pom.xml | 201 +++++++++--------- .../backend/controller/UserController.java | 10 +- .../backend/services/UserServiceImpl.java | 9 +- 3 files changed, 111 insertions(+), 109 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index 182dc562..169991c3 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -1,104 +1,111 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.3.1 - - - com.greenfoxacademy - backend - 0.0.1-SNAPSHOT - backend - backend - - - - - - - - - - - + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.1 + + + com.greenfoxacademy + backend + 0.0.1-SNAPSHOT + backend + backend - - - 21 - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - org.springframework.boot - spring-boot-starter-validation - - - org.postgresql - postgresql - runtime - - - org.projectlombok - lombok - true - - - org.modelmapper - modelmapper - 3.2.0 - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.security - spring-security-test - test - - - com.h2database - h2 - runtime - - - org.springframework.boot - spring-boot-starter-security - - + + + + + + + + + + + + + + 21 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-starter-validation + + + org.postgresql + postgresql + runtime + + + org.projectlombok + lombok + true + + + org.modelmapper + modelmapper + 3.2.0 + - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - + + commons-validator + commons-validator + 1.9.0 + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-security + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index 849a8f23..52db59fb 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -26,11 +26,11 @@ public class UserController { @CrossOrigin(origins = "http://localhost:5173") @PostMapping("/register") public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { -// if (!userService.emailValidation(registerUserDto.getEmail())) { -// return ResponseEntity.badRequest().body("Email is not valid!"); -// } else if (userService.existsByEmail(registerUserDto.getEmail())) { -// return ResponseEntity.badRequest().body("Email is already exist!"); -// } + if (!userService.emailValidation(registerUserDto.getEmail())) { + return ResponseEntity.badRequest().body("Email is not valid!"); + } else if (userService.existsByEmail(registerUserDto.getEmail())) { + return ResponseEntity.badRequest().body("Email is already exist!"); + } userService.register(registerUserDto); return ResponseEntity.ok().build(); } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java index f97483ce..714ea8ab 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java @@ -4,7 +4,7 @@ import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import lombok.RequiredArgsConstructor; -//import org.apache.commons.validator.routines.EmailValidator; +import org.apache.commons.validator.routines.EmailValidator; import org.modelmapper.ModelMapper; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -38,14 +38,9 @@ private User mapToEntity(RegisterUserDto userDto) { } public Boolean emailValidation(String email) { - return true; -// return EmailValidator.getInstance().isValid(email); + return EmailValidator.getInstance().isValid(email); } -// public Boolean passwordValidation(String password) { -// return PasswordConstraintValidator.isValid(password); -// } - @Override public boolean existsByEmail(String email) { return userRepository.existsByEmail(email); From a7548a761dfd3cdceb8a4df5fe12c14cb0363f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Sat, 6 Jul 2024 16:51:00 +0200 Subject: [PATCH 05/19] test(register-API): scenarios for email and password --- .../controller/HealthCheckController.java | 8 +- .../backend/controller/UserController.java | 13 +- .../backend/dtos/RegisterResponseDto.java | 8 + .../backend/dtos/RegisterUserDto.java | 2 + .../greenfoxacademy/backend/models/User.java | 21 +-- .../services/PasswordConstraintValidator.java | 7 +- .../backend/services/UserService.java | 7 +- .../backend/services/UserServiceImpl.java | 27 +-- .../controller/UserControllerTest.java | 170 ++++++++++++++++++ 9 files changed, 215 insertions(+), 48 deletions(-) create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java create mode 100644 backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java index 10c7d183..01ec38d8 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java @@ -11,9 +11,9 @@ */ @Controller public class HealthCheckController { - @GetMapping("/health-check") - public ResponseEntity healthCheck() { - return new ResponseEntity<>("OK", HttpStatus.OK); - } + @GetMapping("/health-check") + public ResponseEntity healthCheck() { + return new ResponseEntity<>("OK", HttpStatus.OK); + } } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index 52db59fb..bfd50b8d 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.*; +import java.net.URI; import java.util.HashMap; import java.util.Map; @@ -19,20 +20,18 @@ */ @RestController @RequiredArgsConstructor -@CrossOrigin(origins = "http://localhost:8080") public class UserController { private final UserService userService; @CrossOrigin(origins = "http://localhost:5173") @PostMapping("/register") public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { - if (!userService.emailValidation(registerUserDto.getEmail())) { - return ResponseEntity.badRequest().body("Email is not valid!"); - } else if (userService.existsByEmail(registerUserDto.getEmail())) { - return ResponseEntity.badRequest().body("Email is already exist!"); + try { + URI uri = URI.create("/users/" + userService.register(registerUserDto).id()); + return ResponseEntity.created(uri).build(); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); } - userService.register(registerUserDto); - return ResponseEntity.ok().build(); } @ResponseStatus(HttpStatus.BAD_REQUEST) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java new file mode 100644 index 00000000..117db004 --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java @@ -0,0 +1,8 @@ +package com.greenfoxacademy.backend.dtos; + +public record RegisterResponseDto( + Integer id +) { + public RegisterResponseDto { + } +} diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java index d0f389e4..3c46dfe0 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java @@ -1,6 +1,7 @@ package com.greenfoxacademy.backend.dtos; import com.greenfoxacademy.backend.services.ValidPassword; +import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Getter; @@ -19,6 +20,7 @@ public class RegisterUserDto { private String firstName; @NotBlank private String lastName; + @Email private String email; @ValidPassword private String password; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index 9538672a..02cce0ae 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -1,9 +1,6 @@ package com.greenfoxacademy.backend.models; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -21,13 +18,13 @@ @Table(name = "_user") public class User { - @Id - @GeneratedValue - private Integer id; - private String firstName; - private String lastName; - private String email; - private String password; - + @Id + @GeneratedValue + private Integer id; + private String firstName; + private String lastName; + @Column(unique = true) + private String email; + private String password; } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java index b49f7655..959817df 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java @@ -11,13 +11,18 @@ public class PasswordConstraintValidator implements ConstraintValidator errorMessages = new ArrayList<>(); if (password.length() < 8) { errorMessages.add("must be at least 8 characters long"); isValid = false; } - if (!password.matches(".*\\S.*")) { + if (password.matches(".*\\s.*")) { errorMessages.add("must not contain whitespace"); isValid = false; } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java index 255dbfee..4ebfa763 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java @@ -1,5 +1,6 @@ package com.greenfoxacademy.backend.services; +import com.greenfoxacademy.backend.dtos.RegisterResponseDto; import com.greenfoxacademy.backend.dtos.RegisterUserDto; import com.greenfoxacademy.backend.models.User; import org.springframework.stereotype.Service; @@ -9,9 +10,5 @@ */ @Service public interface UserService { - void register(RegisterUserDto userDto); - - Boolean emailValidation(String email); - - boolean existsByEmail(String email); + RegisterResponseDto register(RegisterUserDto userDto) throws Exception; } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java index 714ea8ab..feed9ad5 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java @@ -1,10 +1,10 @@ package com.greenfoxacademy.backend.services; +import com.greenfoxacademy.backend.dtos.RegisterResponseDto; import com.greenfoxacademy.backend.dtos.RegisterUserDto; import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import lombok.RequiredArgsConstructor; -import org.apache.commons.validator.routines.EmailValidator; import org.modelmapper.ModelMapper; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -16,33 +16,22 @@ @RequiredArgsConstructor public class UserServiceImpl implements UserService { private final PasswordEncoder passwordEncoder; - private final UserRepository userRepository; private final ModelMapper modelMapper; @Override - public void register(RegisterUserDto userDto) { - User user = this.mapToEntity(userDto); + public RegisterResponseDto register(RegisterUserDto userDto) throws Exception { + User user = mapToEntity(userDto); user.setPassword(passwordEncoder.encode(userDto.getPassword())); - userRepository.save(user); + User savedUser = userRepository.save(user); + return mapToRegisterResponseDto(savedUser); } - private RegisterUserDto mapToDto(User user) { - RegisterUserDto registerUserDto = modelMapper.map(user, RegisterUserDto.class); - return registerUserDto; + private RegisterResponseDto mapToRegisterResponseDto(User user) { + return new RegisterResponseDto(user.getId()); } private User mapToEntity(RegisterUserDto userDto) { - User user = modelMapper.map(userDto, User.class); - return user; - } - - public Boolean emailValidation(String email) { - return EmailValidator.getInstance().isValid(email); - } - - @Override - public boolean existsByEmail(String email) { - return userRepository.existsByEmail(email); + return modelMapper.map(userDto, User.class); } } \ No newline at end of file diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java new file mode 100644 index 00000000..9ebdf79c --- /dev/null +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -0,0 +1,170 @@ +package com.greenfoxacademy.backend.controller; + +import com.greenfoxacademy.backend.repositories.UserRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + + +@SpringBootTest +@AutoConfigureMockMvc +class UserControllerTest { + + @MockBean + private UserRepository userRepository; + + @Autowired + private MockMvc mockMvc; + + + @DisplayName("Should return password is not present when password is not present") + @Test + void shouldReturnPasswordIsNotPresentWhenPasswordIsNotPResent() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Password should be added"))); + } + + @DisplayName("Should return password is short when password is short") + @Test + void shouldReturnPasswordIsNotLongEnoughWhenPasswordIsShort() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1Aa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must be at least 8 characters long"))); + } + + + @DisplayName("Should return password has no digit when password has no digit") + @Test + void shouldReturnPasswordContainsNoDigitsIfItContainsNoDigits() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "aAaaaaaaaaaaaaaaaaaaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one digit"))); + } + + + @DisplayName("Should return password has no uppercase when password has no uppercase") + @Test + void shouldReturnPasswordContainsNoUpperCaseIfPasswordContainsNoUppercase() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1aaaaaaaaaaaaaaaaaaaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one uppercase letter"))); + } + + + @DisplayName("Should return password has no lowercase when password has no lowercase") + @Test + void shouldReturnPasswordContainsNoLowerCaseIfPasswordContainsNoLowercase() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1AAAAAAAAAAAAAAAAAAAAAA" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one lowercase letter"))); + } + + @DisplayName("Should return password contains white space when password contains white space") + @Test + void shouldReturnPasswordContainsWhiteSpaceIfContainsWhiteSpace() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1 A c a 2 b B a 2" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must not contain whitespace"))); + } + + @DisplayName("Should return password is invalid with all errors if it has all errors") + @Test + void shouldReturnPasswordIsInvalidWithAllErrorsIfItHasAllErrors() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": " " + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must be at least 8 characters long, must not contain whitespace, must contain at least one digit, must contain at least one uppercase letter, must contain at least one lowercase letter"))); + } + + @DisplayName("Should return email is not valid when email in not valid") + @Test + void shouldReturnEmailIsInvalidWhenEmailIsInvalid() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john.doe.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.email", is("must be a well-formed email address"))); + } + + + @DisplayName("Should return email is duplicated when email is duplicated") + @Test + void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { + + Mockito.when(userRepository.save(Mockito.any())).thenThrow(new RuntimeException("Email is already taken")); + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "asd@asd.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andDo(print()).andExpectAll(status().isBadRequest(), content().string("Email is already taken")); + } + +} \ No newline at end of file From 28a9b57f9a3e75cb21da59ec5bc05900c924bd90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Sat, 6 Jul 2024 17:46:49 +0200 Subject: [PATCH 06/19] test(register): add sucessfull registration scenario --- .../backend/services/UserServiceImpl.java | 3 +-- .../backend/controller/UserControllerTest.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java index feed9ad5..e8d5bca9 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java @@ -23,8 +23,7 @@ public class UserServiceImpl implements UserService { public RegisterResponseDto register(RegisterUserDto userDto) throws Exception { User user = mapToEntity(userDto); user.setPassword(passwordEncoder.encode(userDto.getPassword())); - User savedUser = userRepository.save(user); - return mapToRegisterResponseDto(savedUser); + return mapToRegisterResponseDto(userRepository.save(user)); } private RegisterResponseDto mapToRegisterResponseDto(User user) { diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 9ebdf79c..13c29a02 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -1,5 +1,6 @@ package com.greenfoxacademy.backend.controller; +import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -167,4 +168,20 @@ void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andDo(print()).andExpectAll(status().isBadRequest(), content().string("Email is already taken")); } + @DisplayName("Should return email is duplicated when email is duplicated") + @Test + void shouldReturnUserSuccessfullyCreatedIfEverythingIsCorrect() throws Exception { + + Mockito.when(userRepository.save(Mockito.any())).thenReturn(User.builder().id(1).build()); + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "asd@asd.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andDo(print()).andExpectAll(status().isCreated(), header().string("Location", "/users/1")); + } + } \ No newline at end of file From 90334decdf7bdfb925b392b1a7553d2ee65a8b45 Mon Sep 17 00:00:00 2001 From: AnnaUgrai <149159395+AnnaUgrai@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:47:10 +0200 Subject: [PATCH 07/19] fix: excluded common validatin to make validation work --- backend/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index 169991c3..9ed8e47b 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -64,11 +64,11 @@ 3.2.0 - - commons-validator - commons-validator - 1.9.0 - + + + + + org.springframework.boot From de321dbfa6c2edc5624b485c1e5e53b3edeee9b9 Mon Sep 17 00:00:00 2001 From: AnnaUgrai <149159395+AnnaUgrai@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:55:48 +0200 Subject: [PATCH 08/19] style: fixed intentation --- backend/node_modules/.bin/runjs | 16 + backend/node_modules/.bin/runjs.cmd | 17 + backend/node_modules/.bin/runjs.ps1 | 28 + backend/node_modules/.package-lock.json | 48 + .../balanced-match/.github/FUNDING.yml | 2 + .../node_modules/balanced-match/LICENSE.md | 21 + backend/node_modules/balanced-match/README.md | 97 ++ backend/node_modules/balanced-match/index.js | 62 + .../node_modules/balanced-match/package.json | 48 + .../brace-expansion/.github/FUNDING.yml | 2 + backend/node_modules/brace-expansion/LICENSE | 21 + .../node_modules/brace-expansion/README.md | 135 +++ backend/node_modules/brace-expansion/index.js | 203 ++++ .../node_modules/brace-expansion/package.json | 46 + backend/node_modules/minimatch/LICENSE | 15 + backend/node_modules/minimatch/README.md | 454 ++++++++ .../dist/commonjs/assert-valid-pattern.d.ts | 2 + .../commonjs/assert-valid-pattern.d.ts.map | 1 + .../dist/commonjs/assert-valid-pattern.js | 14 + .../dist/commonjs/assert-valid-pattern.js.map | 1 + .../minimatch/dist/commonjs/ast.d.ts | 20 + .../minimatch/dist/commonjs/ast.d.ts.map | 1 + .../minimatch/dist/commonjs/ast.js | 592 ++++++++++ .../minimatch/dist/commonjs/ast.js.map | 1 + .../dist/commonjs/brace-expressions.d.ts | 8 + .../dist/commonjs/brace-expressions.d.ts.map | 1 + .../dist/commonjs/brace-expressions.js | 152 +++ .../dist/commonjs/brace-expressions.js.map | 1 + .../minimatch/dist/commonjs/escape.d.ts | 12 + .../minimatch/dist/commonjs/escape.d.ts.map | 1 + .../minimatch/dist/commonjs/escape.js | 22 + .../minimatch/dist/commonjs/escape.js.map | 1 + .../minimatch/dist/commonjs/index.d.ts | 94 ++ .../minimatch/dist/commonjs/index.d.ts.map | 1 + .../minimatch/dist/commonjs/index.js | 1017 +++++++++++++++++ .../minimatch/dist/commonjs/index.js.map | 1 + .../minimatch/dist/commonjs/package.json | 3 + .../minimatch/dist/commonjs/unescape.d.ts | 17 + .../minimatch/dist/commonjs/unescape.d.ts.map | 1 + .../minimatch/dist/commonjs/unescape.js | 24 + .../minimatch/dist/commonjs/unescape.js.map | 1 + .../dist/esm/assert-valid-pattern.d.ts | 2 + .../dist/esm/assert-valid-pattern.d.ts.map | 1 + .../dist/esm/assert-valid-pattern.js | 10 + .../dist/esm/assert-valid-pattern.js.map | 1 + .../node_modules/minimatch/dist/esm/ast.d.ts | 20 + .../minimatch/dist/esm/ast.d.ts.map | 1 + .../node_modules/minimatch/dist/esm/ast.js | 588 ++++++++++ .../minimatch/dist/esm/ast.js.map | 1 + .../minimatch/dist/esm/brace-expressions.d.ts | 8 + .../dist/esm/brace-expressions.d.ts.map | 1 + .../minimatch/dist/esm/brace-expressions.js | 148 +++ .../dist/esm/brace-expressions.js.map | 1 + .../minimatch/dist/esm/escape.d.ts | 12 + .../minimatch/dist/esm/escape.d.ts.map | 1 + .../node_modules/minimatch/dist/esm/escape.js | 18 + .../minimatch/dist/esm/escape.js.map | 1 + .../minimatch/dist/esm/index.d.ts | 94 ++ .../minimatch/dist/esm/index.d.ts.map | 1 + .../node_modules/minimatch/dist/esm/index.js | 1001 ++++++++++++++++ .../minimatch/dist/esm/index.js.map | 1 + .../minimatch/dist/esm/package.json | 3 + .../minimatch/dist/esm/unescape.d.ts | 17 + .../minimatch/dist/esm/unescape.d.ts.map | 1 + .../minimatch/dist/esm/unescape.js | 20 + .../minimatch/dist/esm/unescape.js.map | 1 + backend/node_modules/minimatch/package.json | 82 ++ backend/node_modules/run/LICENSE | 18 + backend/node_modules/run/cli.js | 2 + backend/node_modules/run/package.json | 26 + backend/node_modules/run/readme.md | 47 + backend/node_modules/run/run.js | 179 +++ backend/node_modules/run/test/runme.js | 28 + backend/node_modules/run/test/screenshot.png | Bin 0 -> 92481 bytes backend/package-lock.json | 53 + backend/package.json | 5 + .../backend/BackendApplication.java | 4 +- .../controller/HealthCheckController.java | 10 +- .../backend/controller/UserController.java | 48 +- .../backend/dtos/RegisterResponseDto.java | 4 +- .../backend/dtos/RegisterUserDto.java | 16 +- .../greenfoxacademy/backend/models/User.java | 22 +- .../services/PasswordConstraintValidator.java | 70 +- .../backend/services/UserService.java | 2 +- .../backend/services/UserServiceImpl.java | 36 +- .../backend/services/ValidPassword.java | 20 +- .../controller/UserControllerTest.java | 326 +++--- 87 files changed, 5876 insertions(+), 279 deletions(-) create mode 100644 backend/node_modules/.bin/runjs create mode 100644 backend/node_modules/.bin/runjs.cmd create mode 100644 backend/node_modules/.bin/runjs.ps1 create mode 100644 backend/node_modules/.package-lock.json create mode 100644 backend/node_modules/balanced-match/.github/FUNDING.yml create mode 100644 backend/node_modules/balanced-match/LICENSE.md create mode 100644 backend/node_modules/balanced-match/README.md create mode 100644 backend/node_modules/balanced-match/index.js create mode 100644 backend/node_modules/balanced-match/package.json create mode 100644 backend/node_modules/brace-expansion/.github/FUNDING.yml create mode 100644 backend/node_modules/brace-expansion/LICENSE create mode 100644 backend/node_modules/brace-expansion/README.md create mode 100644 backend/node_modules/brace-expansion/index.js create mode 100644 backend/node_modules/brace-expansion/package.json create mode 100644 backend/node_modules/minimatch/LICENSE create mode 100644 backend/node_modules/minimatch/README.md create mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts create mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js create mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.d.ts create mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.js create mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.js.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts create mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.js create mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.d.ts create mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.js create mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.js.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/index.d.ts create mode 100644 backend/node_modules/minimatch/dist/commonjs/index.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/index.js create mode 100644 backend/node_modules/minimatch/dist/commonjs/index.js.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/package.json create mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.d.ts create mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.js create mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.js.map create mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts create mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js create mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map create mode 100644 backend/node_modules/minimatch/dist/esm/ast.d.ts create mode 100644 backend/node_modules/minimatch/dist/esm/ast.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/esm/ast.js create mode 100644 backend/node_modules/minimatch/dist/esm/ast.js.map create mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts create mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.js create mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.js.map create mode 100644 backend/node_modules/minimatch/dist/esm/escape.d.ts create mode 100644 backend/node_modules/minimatch/dist/esm/escape.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/esm/escape.js create mode 100644 backend/node_modules/minimatch/dist/esm/escape.js.map create mode 100644 backend/node_modules/minimatch/dist/esm/index.d.ts create mode 100644 backend/node_modules/minimatch/dist/esm/index.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/esm/index.js create mode 100644 backend/node_modules/minimatch/dist/esm/index.js.map create mode 100644 backend/node_modules/minimatch/dist/esm/package.json create mode 100644 backend/node_modules/minimatch/dist/esm/unescape.d.ts create mode 100644 backend/node_modules/minimatch/dist/esm/unescape.d.ts.map create mode 100644 backend/node_modules/minimatch/dist/esm/unescape.js create mode 100644 backend/node_modules/minimatch/dist/esm/unescape.js.map create mode 100644 backend/node_modules/minimatch/package.json create mode 100644 backend/node_modules/run/LICENSE create mode 100644 backend/node_modules/run/cli.js create mode 100644 backend/node_modules/run/package.json create mode 100644 backend/node_modules/run/readme.md create mode 100644 backend/node_modules/run/run.js create mode 100644 backend/node_modules/run/test/runme.js create mode 100644 backend/node_modules/run/test/screenshot.png create mode 100644 backend/package-lock.json create mode 100644 backend/package.json diff --git a/backend/node_modules/.bin/runjs b/backend/node_modules/.bin/runjs new file mode 100644 index 00000000..746d6049 --- /dev/null +++ b/backend/node_modules/.bin/runjs @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../run/cli.js" "$@" +else + exec node "$basedir/../run/cli.js" "$@" +fi diff --git a/backend/node_modules/.bin/runjs.cmd b/backend/node_modules/.bin/runjs.cmd new file mode 100644 index 00000000..df496fc5 --- /dev/null +++ b/backend/node_modules/.bin/runjs.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\run\cli.js" %* diff --git a/backend/node_modules/.bin/runjs.ps1 b/backend/node_modules/.bin/runjs.ps1 new file mode 100644 index 00000000..84b777da --- /dev/null +++ b/backend/node_modules/.bin/runjs.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../run/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../run/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../run/cli.js" $args + } else { + & "node$exe" "$basedir/../run/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/backend/node_modules/.package-lock.json b/backend/node_modules/.package-lock.json new file mode 100644 index 00000000..6927574e --- /dev/null +++ b/backend/node_modules/.package-lock.json @@ -0,0 +1,48 @@ +{ + "name": "backend", + "lockfileVersion": 3, + "requires": true, + "packages": { + "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==" + }, + "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==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/run/-/run-1.5.0.tgz", + "integrity": "sha512-CBPzeX6JQZUdhZpSFyNt2vUk44ivKMWZYCNBYoZYEE46mL9nf6WyMP3320WnzIrJuo89+njiUvlo83jUEXjXLg==", + "dependencies": { + "minimatch": "*" + }, + "bin": { + "runjs": "cli.js" + }, + "engines": { + "node": ">=v0.9.0" + } + } + } +} diff --git a/backend/node_modules/balanced-match/.github/FUNDING.yml b/backend/node_modules/balanced-match/.github/FUNDING.yml new file mode 100644 index 00000000..cea8b16e --- /dev/null +++ b/backend/node_modules/balanced-match/.github/FUNDING.yml @@ -0,0 +1,2 @@ +tidelift: "npm/balanced-match" +patreon: juliangruber diff --git a/backend/node_modules/balanced-match/LICENSE.md b/backend/node_modules/balanced-match/LICENSE.md new file mode 100644 index 00000000..2cdc8e41 --- /dev/null +++ b/backend/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/backend/node_modules/balanced-match/README.md b/backend/node_modules/balanced-match/README.md new file mode 100644 index 00000000..d2a48b6b --- /dev/null +++ b/backend/node_modules/balanced-match/README.md @@ -0,0 +1,97 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/backend/node_modules/balanced-match/index.js b/backend/node_modules/balanced-match/index.js new file mode 100644 index 00000000..c67a6460 --- /dev/null +++ b/backend/node_modules/balanced-match/index.js @@ -0,0 +1,62 @@ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + if(a===b) { + return [ai, bi]; + } + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/backend/node_modules/balanced-match/package.json b/backend/node_modules/balanced-match/package.json new file mode 100644 index 00000000..ce6073e0 --- /dev/null +++ b/backend/node_modules/balanced-match/package.json @@ -0,0 +1,48 @@ +{ + "name": "balanced-match", + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "version": "1.0.2", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "homepage": "https://github.com/juliangruber/balanced-match", + "main": "index.js", + "scripts": { + "test": "tape test/test.js", + "bench": "matcha test/bench.js" + }, + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + } +} diff --git a/backend/node_modules/brace-expansion/.github/FUNDING.yml b/backend/node_modules/brace-expansion/.github/FUNDING.yml new file mode 100644 index 00000000..79d1eafc --- /dev/null +++ b/backend/node_modules/brace-expansion/.github/FUNDING.yml @@ -0,0 +1,2 @@ +tidelift: "npm/brace-expansion" +patreon: juliangruber diff --git a/backend/node_modules/brace-expansion/LICENSE b/backend/node_modules/brace-expansion/LICENSE new file mode 100644 index 00000000..de322667 --- /dev/null +++ b/backend/node_modules/brace-expansion/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 Julian Gruber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/backend/node_modules/brace-expansion/README.md b/backend/node_modules/brace-expansion/README.md new file mode 100644 index 00000000..e55c583d --- /dev/null +++ b/backend/node_modules/brace-expansion/README.md @@ -0,0 +1,135 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) +[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## Sponsors + +This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! + +Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/backend/node_modules/brace-expansion/index.js b/backend/node_modules/brace-expansion/index.js new file mode 100644 index 00000000..4af9ddee --- /dev/null +++ b/backend/node_modules/brace-expansion/index.js @@ -0,0 +1,203 @@ +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m) return [str]; + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + if (/\$$/.test(m.pre)) { + for (var k = 0; k < post.length; k++) { + var expansion = pre+ '{' + m.body + '}' + post[k]; + expansions.push(expansion); + } + } else { + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = []; + + for (var j = 0; j < n.length; j++) { + N.push.apply(N, expand(n[j], false)); + } + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + } + + return expansions; +} + diff --git a/backend/node_modules/brace-expansion/package.json b/backend/node_modules/brace-expansion/package.json new file mode 100644 index 00000000..7097d41e --- /dev/null +++ b/backend/node_modules/brace-expansion/package.json @@ -0,0 +1,46 @@ +{ + "name": "brace-expansion", + "description": "Brace expansion as known from sh/bash", + "version": "2.0.1", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "homepage": "https://github.com/juliangruber/brace-expansion", + "main": "index.js", + "scripts": { + "test": "tape test/*.js", + "gentest": "bash test/generate.sh", + "bench": "matcha test/perf/bench.js" + }, + "dependencies": { + "balanced-match": "^1.0.0" + }, + "devDependencies": { + "@c4312/matcha": "^1.3.1", + "tape": "^4.6.0" + }, + "keywords": [], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + } +} diff --git a/backend/node_modules/minimatch/LICENSE b/backend/node_modules/minimatch/LICENSE new file mode 100644 index 00000000..1493534e --- /dev/null +++ b/backend/node_modules/minimatch/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/backend/node_modules/minimatch/README.md b/backend/node_modules/minimatch/README.md new file mode 100644 index 00000000..3c97a02f --- /dev/null +++ b/backend/node_modules/minimatch/README.md @@ -0,0 +1,454 @@ +# minimatch + +A minimal matching utility. + +This is the matching library used internally by npm. + +It works by converting glob expressions into JavaScript `RegExp` +objects. + +## Usage + +```js +// hybrid module, load with require() or import +import { minimatch } from 'minimatch' +// or: +const { minimatch } = require('minimatch') + +minimatch('bar.foo', '*.foo') // true! +minimatch('bar.foo', '*.bar') // false! +minimatch('bar.foo', '*.+(bar|foo)', { debug: true }) // true, and noisy! +``` + +## Features + +Supports these glob features: + +- Brace Expansion +- Extended glob matching +- "Globstar" `**` matching +- [Posix character + classes](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html), + like `[[:alpha:]]`, supporting the full range of Unicode + characters. For example, `[[:alpha:]]` will match against + `'é'`, though `[a-zA-Z]` will not. Collating symbol and set + matching is not supported, so `[[=e=]]` will _not_ match `'é'` + and `[[.ch.]]` will not match `'ch'` in locales where `ch` is + considered a single character. + +See: + +- `man sh` +- `man bash` [Pattern + Matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) +- `man 3 fnmatch` +- `man 5 gitignore` + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes in patterns +will always be interpreted as escape characters, not path separators. + +Note that `\` or `/` _will_ be interpreted as path separators in paths on +Windows, and will match against `/` in glob expressions. + +So just always use `/` in patterns. + +### UNC Paths + +On Windows, UNC paths like `//?/c:/...` or +`//ComputerName/Share/...` are handled specially. + +- Patterns starting with a double-slash followed by some + non-slash characters will preserve their double-slash. As a + result, a pattern like `//*` will match `//x`, but not `/x`. +- Patterns staring with `//?/:` will _not_ treat + the `?` as a wildcard character. Instead, it will be treated + as a normal string. +- Patterns starting with `//?/:/...` will match + file paths starting with `:/...`, and vice versa, + as if the `//?/` was not present. This behavior only is + present when the drive letters are a case-insensitive match to + one another. The remaining portions of the path/pattern are + compared case sensitively, unless `nocase:true` is set. + +Note that specifying a UNC path using `\` characters as path +separators is always allowed in the file path argument, but only +allowed in the pattern argument when `windowsPathsNoEscape: true` +is set in the options. + +## Minimatch Class + +Create a minimatch object by instantiating the `minimatch.Minimatch` class. + +```javascript +var Minimatch = require('minimatch').Minimatch +var mm = new Minimatch(pattern, options) +``` + +### Properties + +- `pattern` The original pattern the minimatch object represents. +- `options` The options supplied to the constructor. +- `set` A 2-dimensional array of regexp or string expressions. + Each row in the + array corresponds to a brace-expanded pattern. Each item in the row + corresponds to a single path-part. For example, the pattern + `{a,b/c}/d` would expand to a set of patterns like: + + [ [ a, d ] + , [ b, c, d ] ] + + If a portion of the pattern doesn't have any "magic" in it + (that is, it's something like `"foo"` rather than `fo*o?`), then it + will be left as a string rather than converted to a regular + expression. + +- `regexp` Created by the `makeRe` method. A single regular expression + expressing the entire pattern. This is useful in cases where you wish + to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. +- `negate` True if the pattern is negated. +- `comment` True if the pattern is a comment. +- `empty` True if the pattern is `""`. + +### Methods + +- `makeRe()` Generate the `regexp` member if necessary, and return it. + Will return `false` if the pattern is invalid. +- `match(fname)` Return true if the filename matches the pattern, or + false otherwise. +- `matchOne(fileArray, patternArray, partial)` Take a `/`-split + filename, and match it against a single row in the `regExpSet`. This + method is mainly for internal use, but is exposed so that it can be + used by a glob-walker that needs to avoid excessive filesystem calls. +- `hasMagic()` Returns true if the parsed pattern contains any + magic characters. Returns false if all comparator parts are + string literals. If the `magicalBraces` option is set on the + constructor, then it will consider brace expansions which are + not otherwise magical to be magic. If not set, then a pattern + like `a{b,c}d` will return `false`, because neither `abd` nor + `acd` contain any special glob characters. + + This does **not** mean that the pattern string can be used as a + literal filename, as it may contain magic glob characters that + are escaped. For example, the pattern `\\*` or `[*]` would not + be considered to have magic, as the matching portion parses to + the literal string `'*'` and would match a path named `'*'`, + not `'\\*'` or `'[*]'`. The `minimatch.unescape()` method may + be used to remove escape characters. + +All other methods are internal, and will be called as necessary. + +### minimatch(path, pattern, options) + +Main export. Tests a path against the pattern using the options. + +```javascript +var isJS = minimatch(file, '*.js', { matchBase: true }) +``` + +### minimatch.filter(pattern, options) + +Returns a function that tests its +supplied argument, suitable for use with `Array.filter`. Example: + +```javascript +var javascripts = fileList.filter(minimatch.filter('*.js', { matchBase: true })) +``` + +### minimatch.escape(pattern, options = {}) + +Escape all magic characters in a glob pattern, so that it will +only ever match literal strings + +If the `windowsPathsNoEscape` option is used, then characters are +escaped by wrapping in `[]`, because a magic character wrapped in +a character class can only be satisfied by that exact character. + +Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot +be escaped or unescaped. + +### minimatch.unescape(pattern, options = {}) + +Un-escape a glob string that may contain some escaped characters. + +If the `windowsPathsNoEscape` option is used, then square-brace +escapes are removed, but not backslash escapes. For example, it +will turn the string `'[*]'` into `*`, but it will not turn +`'\\*'` into `'*'`, because `\` is a path separator in +`windowsPathsNoEscape` mode. + +When `windowsPathsNoEscape` is not set, then both brace escapes +and backslash escapes are removed. + +Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot +be escaped or unescaped. + +### minimatch.match(list, pattern, options) + +Match against the list of +files, in the style of fnmatch or glob. If nothing is matched, and +options.nonull is set, then return a list containing the pattern itself. + +```javascript +var javascripts = minimatch.match(fileList, '*.js', { matchBase: true }) +``` + +### minimatch.makeRe(pattern, options) + +Make a regular expression object from the pattern. + +## Options + +All options are `false` by default. + +### debug + +Dump a ton of stuff to stderr. + +### nobrace + +Do not expand `{a,b}` and `{1..3}` brace sets. + +### noglobstar + +Disable `**` matching against multiple folder names. + +### dot + +Allow patterns to match filenames starting with a period, even if +the pattern does not explicitly have a period in that spot. + +Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` +is set. + +### noext + +Disable "extglob" style patterns like `+(a|b)`. + +### nocase + +Perform a case-insensitive match. + +### nocaseMagicOnly + +When used with `{nocase: true}`, create regular expressions that +are case-insensitive, but leave string match portions untouched. +Has no effect when used without `{nocase: true}` + +Useful when some other form of case-insensitive matching is used, +or if the original string representation is useful in some other +way. + +### nonull + +When a match is not found by `minimatch.match`, return a list containing +the pattern itself if this option is set. When not set, an empty list +is returned if there are no matches. + +### magicalBraces + +This only affects the results of the `Minimatch.hasMagic` method. + +If the pattern contains brace expansions, such as `a{b,c}d`, but +no other magic characters, then the `Minimatch.hasMagic()` method +will return `false` by default. When this option set, it will +return `true` for brace expansion as well as other magic glob +characters. + +### matchBase + +If set, then patterns without slashes will be matched +against the basename of the path if it contains slashes. For example, +`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. + +### nocomment + +Suppress the behavior of treating `#` at the start of a pattern as a +comment. + +### nonegate + +Suppress the behavior of treating a leading `!` character as negation. + +### flipNegate + +Returns from negate expressions the same as if they were not negated. +(Ie, true on a hit, false on a miss.) + +### partial + +Compare a partial path to a pattern. As long as the parts of the path that +are present are not contradicted by the pattern, it will be treated as a +match. This is useful in applications where you're walking through a +folder structure, and don't yet have the full path, but want to ensure that +you do not walk down paths that can never be a match. + +For example, + +```js +minimatch('/a/b', '/a/*/c/d', { partial: true }) // true, might be /a/b/c/d +minimatch('/a/b', '/**/d', { partial: true }) // true, might be /a/b/.../d +minimatch('/x/y/z', '/a/**/z', { partial: true }) // false, because x !== a +``` + +### windowsPathsNoEscape + +Use `\\` as a path separator _only_, and _never_ as an escape +character. If set, all `\\` characters are replaced with `/` in +the pattern. Note that this makes it **impossible** to match +against paths containing literal glob pattern characters, but +allows matching with patterns constructed using `path.join()` and +`path.resolve()` on Windows platforms, mimicking the (buggy!) +behavior of earlier versions on Windows. Please use with +caution, and be mindful of [the caveat about Windows +paths](#windows). + +For legacy reasons, this is also set if +`options.allowWindowsEscape` is set to the exact value `false`. + +### windowsNoMagicRoot + +When a pattern starts with a UNC path or drive letter, and in +`nocase:true` mode, do not convert the root portions of the +pattern into a case-insensitive regular expression, and instead +leave them as strings. + +This is the default when the platform is `win32` and +`nocase:true` is set. + +### preserveMultipleSlashes + +By default, multiple `/` characters (other than the leading `//` +in a UNC path, see "UNC Paths" above) are treated as a single +`/`. + +That is, a pattern like `a///b` will match the file path `a/b`. + +Set `preserveMultipleSlashes: true` to suppress this behavior. + +### optimizationLevel + +A number indicating the level of optimization that should be done +to the pattern prior to parsing and using it for matches. + +Globstar parts `**` are always converted to `*` when `noglobstar` +is set, and multiple adjacent `**` parts are converted into a +single `**` (ie, `a/**/**/b` will be treated as `a/**/b`, as this +is equivalent in all cases). + +- `0` - Make no further changes. In this mode, `.` and `..` are + maintained in the pattern, meaning that they must also appear + in the same position in the test path string. Eg, a pattern + like `a/*/../c` will match the string `a/b/../c` but not the + string `a/c`. +- `1` - (default) Remove cases where a double-dot `..` follows a + pattern portion that is not `**`, `.`, `..`, or empty `''`. For + example, the pattern `./a/b/../*` is converted to `./a/*`, and + so it will match the path string `./a/c`, but not the path + string `./a/b/../c`. Dots and empty path portions in the + pattern are preserved. +- `2` (or higher) - Much more aggressive optimizations, suitable + for use with file-walking cases: + + - Remove cases where a double-dot `..` follows a pattern + portion that is not `**`, `.`, or empty `''`. Remove empty + and `.` portions of the pattern, where safe to do so (ie, + anywhere other than the last position, the first position, or + the second position in a pattern starting with `/`, as this + may indicate a UNC path on Windows). + - Convert patterns containing `
/**/../

/` into the + equivalent `

/{..,**}/

/`, where `

` is a + a pattern portion other than `.`, `..`, `**`, or empty + `''`. + - Dedupe patterns where a `**` portion is present in one and + omitted in another, and it is not the final path portion, and + they are otherwise equivalent. So `{a/**/b,a/b}` becomes + `a/**/b`, because `**` matches against an empty path portion. + - Dedupe patterns where a `*` portion is present in one, and a + non-dot pattern other than `**`, `.`, `..`, or `''` is in the + same position in the other. So `a/{*,x}/b` becomes `a/*/b`, + because `*` can match against `x`. + + While these optimizations improve the performance of + file-walking use cases such as [glob](http://npm.im/glob) (ie, + the reason this module exists), there are cases where it will + fail to match a literal string that would have been matched in + optimization level 1 or 0. + + Specifically, while the `Minimatch.match()` method will + optimize the file path string in the same ways, resulting in + the same matches, it will fail when tested with the regular + expression provided by `Minimatch.makeRe()`, unless the path + string is first processed with + `minimatch.levelTwoFileOptimize()` or similar. + +### platform + +When set to `win32`, this will trigger all windows-specific +behaviors (special handling for UNC paths, and treating `\` as +separators in file paths for comparison.) + +Defaults to the value of `process.platform`. + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a +worthwhile goal, some discrepancies exist between minimatch and +other implementations. Some are intentional, and some are +unavoidable. + +If the pattern starts with a `!` character, then it is negated. Set the +`nonegate` flag to suppress this behavior, and treat leading `!` +characters normally. This is perhaps relevant if you wish to start the +pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` +characters at the start of a pattern will negate the pattern multiple +times. + +If a pattern starts with `#`, then it is treated as a comment, and +will not match anything. Use `\#` to match a literal `#` at the +start of a line, or set the `nocomment` flag to suppress this behavior. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.1, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then minimatch.match returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +Negated extglob patterns are handled as closely as possible to +Bash semantics, but there are some cases with negative extglobs +which are exceedingly difficult to express in a JavaScript +regular expression. In particular the negated pattern +`!(*|)*` will in bash match anything that does +not start with ``. However, +`!(*)*` _will_ match paths starting with +``, because the empty string can match against +the negated portion. In this library, `!(*|)*` +will _not_ match any pattern starting with ``, due to a +difference in precisely which patterns are considered "greedy" in +Regular Expressions vs bash path expansion. This may be fixable, +but not without incurring some complexity and performance costs, +and the trade-off seems to not be worth pursuing. + +Note that `fnmatch(3)` in libc is an extremely naive string comparison +matcher, which does not do anything special for slashes. This library is +designed to be used in glob searching and file walkers, and so it does do +special things with `/`. Thus, `foo*` will not match `foo/bar` in this +library, even though it would in `fnmatch(3)`. diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts new file mode 100644 index 00000000..8e318b23 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts @@ -0,0 +1,2 @@ +export declare const assertValidPattern: (pattern: any) => void; +//# sourceMappingURL=assert-valid-pattern.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map new file mode 100644 index 00000000..c61c0310 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAUlD,CAAA"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js new file mode 100644 index 00000000..5fc86bbd --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.assertValidPattern = void 0; +const MAX_PATTERN_LENGTH = 1024 * 64; +const assertValidPattern = (pattern) => { + if (typeof pattern !== 'string') { + throw new TypeError('invalid pattern'); + } + if (pattern.length > MAX_PATTERN_LENGTH) { + throw new TypeError('pattern is too long'); + } +}; +exports.assertValidPattern = assertValidPattern; +//# sourceMappingURL=assert-valid-pattern.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map new file mode 100644 index 00000000..d43215c6 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":";;;AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AAC7B,MAAM,kBAAkB,GAA2B,CACxD,OAAY,EACe,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;KACvC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE;QACvC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;KAC3C;AACH,CAAC,CAAA;AAVY,QAAA,kBAAkB,sBAU9B","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: any) => void = (\n pattern: any\n): asserts pattern is string => {\n if (typeof pattern !== 'string') {\n throw new TypeError('invalid pattern')\n }\n\n if (pattern.length > MAX_PATTERN_LENGTH) {\n throw new TypeError('pattern is too long')\n }\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.d.ts b/backend/node_modules/minimatch/dist/commonjs/ast.d.ts new file mode 100644 index 00000000..b8c1e544 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/ast.d.ts @@ -0,0 +1,20 @@ +import { MinimatchOptions, MMRegExp } from './index.js'; +export type ExtglobType = '!' | '?' | '+' | '*' | '@'; +export declare class AST { + #private; + type: ExtglobType | null; + constructor(type: ExtglobType | null, parent?: AST, options?: MinimatchOptions); + get hasMagic(): boolean | undefined; + toString(): string; + push(...parts: (string | AST)[]): void; + toJSON(): any[]; + isStart(): boolean; + isEnd(): boolean; + copyIn(part: AST | string): void; + clone(parent: AST): AST; + static fromGlob(pattern: string, options?: MinimatchOptions): AST; + toMMPattern(): MMRegExp | string; + get options(): MinimatchOptions; + toRegExpSource(allowDot?: boolean): [re: string, body: string, hasMagic: boolean, uflag: boolean]; +} +//# sourceMappingURL=ast.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map new file mode 100644 index 00000000..9e7bfb9a --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwCvD,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAkCrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;gBAiBtB,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IA+ClB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAY/B,MAAM;IAgBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsIjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CAiMjE"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.js b/backend/node_modules/minimatch/dist/commonjs/ast.js new file mode 100644 index 00000000..7b210962 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/ast.js @@ -0,0 +1,592 @@ +"use strict"; +// parse a single path portion +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AST = void 0; +const brace_expressions_js_1 = require("./brace-expressions.js"); +const unescape_js_1 = require("./unescape.js"); +const types = new Set(['!', '?', '+', '*', '@']); +const isExtglobType = (c) => types.has(c); +// Patterns that get prepended to bind to the start of either the +// entire string, or just a single path portion, to prevent dots +// and/or traversal patterns, when needed. +// Exts don't need the ^ or / bit, because the root binds that already. +const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))'; +const startNoDot = '(?!\\.)'; +// characters that indicate a start of pattern needs the "no dots" bit, +// because a dot *might* be matched. ( is not in the list, because in +// the case of a child extglob, it will handle the prevention itself. +const addPatternStart = new Set(['[', '.']); +// cases where traversal is A-OK, no dot prevention needed +const justDots = new Set(['..', '.']); +const reSpecials = new Set('().*{}+?[]^$\\!'); +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// any single thing other than / +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// use + when we need to ensure that *something* matches, because the * is +// the only thing in the path portion. +const starNoEmpty = qmark + '+?'; +// remove the \ chars that we added if we end up doing a nonmagic compare +// const deslash = (s: string) => s.replace(/\\(.)/g, '$1') +class AST { + type; + #root; + #hasMagic; + #uflag = false; + #parts = []; + #parent; + #parentIndex; + #negs; + #filledNegs = false; + #options; + #toString; + // set to true if it's an extglob with no children + // (which really means one child of '') + #emptyExt = false; + constructor(type, parent, options = {}) { + this.type = type; + // extglobs are inherently magical + if (type) + this.#hasMagic = true; + this.#parent = parent; + this.#root = this.#parent ? this.#parent.#root : this; + this.#options = this.#root === this ? options : this.#root.#options; + this.#negs = this.#root === this ? [] : this.#root.#negs; + if (type === '!' && !this.#root.#filledNegs) + this.#negs.push(this); + this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0; + } + get hasMagic() { + /* c8 ignore start */ + if (this.#hasMagic !== undefined) + return this.#hasMagic; + /* c8 ignore stop */ + for (const p of this.#parts) { + if (typeof p === 'string') + continue; + if (p.type || p.hasMagic) + return (this.#hasMagic = true); + } + // note: will be undefined until we generate the regexp src and find out + return this.#hasMagic; + } + // reconstructs the pattern + toString() { + if (this.#toString !== undefined) + return this.#toString; + if (!this.type) { + return (this.#toString = this.#parts.map(p => String(p)).join('')); + } + else { + return (this.#toString = + this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')'); + } + } + #fillNegs() { + /* c8 ignore start */ + if (this !== this.#root) + throw new Error('should only call on root'); + if (this.#filledNegs) + return this; + /* c8 ignore stop */ + // call toString() once to fill this out + this.toString(); + this.#filledNegs = true; + let n; + while ((n = this.#negs.pop())) { + if (n.type !== '!') + continue; + // walk up the tree, appending everthing that comes AFTER parentIndex + let p = n; + let pp = p.#parent; + while (pp) { + for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) { + for (const part of n.#parts) { + /* c8 ignore start */ + if (typeof part === 'string') { + throw new Error('string part in extglob AST??'); + } + /* c8 ignore stop */ + part.copyIn(pp.#parts[i]); + } + } + p = pp; + pp = p.#parent; + } + } + return this; + } + push(...parts) { + for (const p of parts) { + if (p === '') + continue; + /* c8 ignore start */ + if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) { + throw new Error('invalid part: ' + p); + } + /* c8 ignore stop */ + this.#parts.push(p); + } + } + toJSON() { + const ret = this.type === null + ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON())) + : [this.type, ...this.#parts.map(p => p.toJSON())]; + if (this.isStart() && !this.type) + ret.unshift([]); + if (this.isEnd() && + (this === this.#root || + (this.#root.#filledNegs && this.#parent?.type === '!'))) { + ret.push({}); + } + return ret; + } + isStart() { + if (this.#root === this) + return true; + // if (this.type) return !!this.#parent?.isStart() + if (!this.#parent?.isStart()) + return false; + if (this.#parentIndex === 0) + return true; + // if everything AHEAD of this is a negation, then it's still the "start" + const p = this.#parent; + for (let i = 0; i < this.#parentIndex; i++) { + const pp = p.#parts[i]; + if (!(pp instanceof AST && pp.type === '!')) { + return false; + } + } + return true; + } + isEnd() { + if (this.#root === this) + return true; + if (this.#parent?.type === '!') + return true; + if (!this.#parent?.isEnd()) + return false; + if (!this.type) + return this.#parent?.isEnd(); + // if not root, it'll always have a parent + /* c8 ignore start */ + const pl = this.#parent ? this.#parent.#parts.length : 0; + /* c8 ignore stop */ + return this.#parentIndex === pl - 1; + } + copyIn(part) { + if (typeof part === 'string') + this.push(part); + else + this.push(part.clone(this)); + } + clone(parent) { + const c = new AST(this.type, parent); + for (const p of this.#parts) { + c.copyIn(p); + } + return c; + } + static #parseAST(str, ast, pos, opt) { + let escaping = false; + let inBrace = false; + let braceStart = -1; + let braceNeg = false; + if (ast.type === null) { + // outside of a extglob, append until we find a start + let i = pos; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (inBrace) { + if (i === braceStart + 1) { + if (c === '^' || c === '!') { + braceNeg = true; + } + } + else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { + inBrace = false; + } + acc += c; + continue; + } + else if (c === '[') { + inBrace = true; + braceStart = i; + braceNeg = false; + acc += c; + continue; + } + if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') { + ast.push(acc); + acc = ''; + const ext = new AST(c, ast); + i = AST.#parseAST(str, ext, i, opt); + ast.push(ext); + continue; + } + acc += c; + } + ast.push(acc); + return i; + } + // some kind of extglob, pos is at the ( + // find the next | or ) + let i = pos + 1; + let part = new AST(null, ast); + const parts = []; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (inBrace) { + if (i === braceStart + 1) { + if (c === '^' || c === '!') { + braceNeg = true; + } + } + else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { + inBrace = false; + } + acc += c; + continue; + } + else if (c === '[') { + inBrace = true; + braceStart = i; + braceNeg = false; + acc += c; + continue; + } + if (isExtglobType(c) && str.charAt(i) === '(') { + part.push(acc); + acc = ''; + const ext = new AST(c, part); + part.push(ext); + i = AST.#parseAST(str, ext, i, opt); + continue; + } + if (c === '|') { + part.push(acc); + acc = ''; + parts.push(part); + part = new AST(null, ast); + continue; + } + if (c === ')') { + if (acc === '' && ast.#parts.length === 0) { + ast.#emptyExt = true; + } + part.push(acc); + acc = ''; + ast.push(...parts, part); + return i; + } + acc += c; + } + // unfinished extglob + // if we got here, it was a malformed extglob! not an extglob, but + // maybe something else in there. + ast.type = null; + ast.#hasMagic = undefined; + ast.#parts = [str.substring(pos - 1)]; + return i; + } + static fromGlob(pattern, options = {}) { + const ast = new AST(null, undefined, options); + AST.#parseAST(pattern, ast, 0, options); + return ast; + } + // returns the regular expression if there's magic, or the unescaped + // string if not. + toMMPattern() { + // should only be called on root + /* c8 ignore start */ + if (this !== this.#root) + return this.#root.toMMPattern(); + /* c8 ignore stop */ + const glob = this.toString(); + const [re, body, hasMagic, uflag] = this.toRegExpSource(); + // if we're in nocase mode, and not nocaseMagicOnly, then we do + // still need a regular expression if we have to case-insensitively + // match capital/lowercase characters. + const anyMagic = hasMagic || + this.#hasMagic || + (this.#options.nocase && + !this.#options.nocaseMagicOnly && + glob.toUpperCase() !== glob.toLowerCase()); + if (!anyMagic) { + return body; + } + const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : ''); + return Object.assign(new RegExp(`^${re}$`, flags), { + _src: re, + _glob: glob, + }); + } + get options() { + return this.#options; + } + // returns the string match, the regexp source, whether there's magic + // in the regexp (so a regular expression is required) and whether or + // not the uflag is needed for the regular expression (for posix classes) + // TODO: instead of injecting the start/end at this point, just return + // the BODY of the regexp, along with the start/end portions suitable + // for binding the start/end in either a joined full-path makeRe context + // (where we bind to (^|/), or a standalone matchPart context (where + // we bind to ^, and not /). Otherwise slashes get duped! + // + // In part-matching mode, the start is: + // - if not isStart: nothing + // - if traversal possible, but not allowed: ^(?!\.\.?$) + // - if dots allowed or not possible: ^ + // - if dots possible and not allowed: ^(?!\.) + // end is: + // - if not isEnd(): nothing + // - else: $ + // + // In full-path matching mode, we put the slash at the START of the + // pattern, so start is: + // - if first pattern: same as part-matching mode + // - if not isStart(): nothing + // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/)) + // - if dots allowed or not possible: / + // - if dots possible and not allowed: /(?!\.) + // end is: + // - if last pattern, same as part-matching mode + // - else nothing + // + // Always put the (?:$|/) on negated tails, though, because that has to be + // there to bind the end of the negated pattern portion, and it's easier to + // just stick it in now rather than try to inject it later in the middle of + // the pattern. + // + // We can just always return the same end, and leave it up to the caller + // to know whether it's going to be used joined or in parts. + // And, if the start is adjusted slightly, can do the same there: + // - if not isStart: nothing + // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$) + // - if dots allowed or not possible: (?:/|^) + // - if dots possible and not allowed: (?:/|^)(?!\.) + // + // But it's better to have a simpler binding without a conditional, for + // performance, so probably better to return both start options. + // + // Then the caller just ignores the end if it's not the first pattern, + // and the start always gets applied. + // + // But that's always going to be $ if it's the ending pattern, or nothing, + // so the caller can just attach $ at the end of the pattern when building. + // + // So the todo is: + // - better detect what kind of start is needed + // - return both flavors of starting pattern + // - attach $ at the end of the pattern when creating the actual RegExp + // + // Ah, but wait, no, that all only applies to the root when the first pattern + // is not an extglob. If the first pattern IS an extglob, then we need all + // that dot prevention biz to live in the extglob portions, because eg + // +(*|.x*) can match .xy but not .yx. + // + // So, return the two flavors if it's #root and the first child is not an + // AST, otherwise leave it to the child AST to handle it, and there, + // use the (?:^|/) style of start binding. + // + // Even simplified further: + // - Since the start for a join is eg /(?!\.) and the start for a part + // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root + // or start or whatever) and prepend ^ or / at the Regexp construction. + toRegExpSource(allowDot) { + const dot = allowDot ?? !!this.#options.dot; + if (this.#root === this) + this.#fillNegs(); + if (!this.type) { + const noEmpty = this.isStart() && this.isEnd(); + const src = this.#parts + .map(p => { + const [re, _, hasMagic, uflag] = typeof p === 'string' + ? AST.#parseGlob(p, this.#hasMagic, noEmpty) + : p.toRegExpSource(allowDot); + this.#hasMagic = this.#hasMagic || hasMagic; + this.#uflag = this.#uflag || uflag; + return re; + }) + .join(''); + let start = ''; + if (this.isStart()) { + if (typeof this.#parts[0] === 'string') { + // this is the string that will match the start of the pattern, + // so we need to protect against dots and such. + // '.' and '..' cannot match unless the pattern is that exactly, + // even if it starts with . or dot:true is set. + const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]); + if (!dotTravAllowed) { + const aps = addPatternStart; + // check if we have a possibility of matching . or .., + // and prevent that. + const needNoTrav = + // dots are allowed, and the pattern starts with [ or . + (dot && aps.has(src.charAt(0))) || + // the pattern starts with \., and then [ or . + (src.startsWith('\\.') && aps.has(src.charAt(2))) || + // the pattern starts with \.\., and then [ or . + (src.startsWith('\\.\\.') && aps.has(src.charAt(4))); + // no need to prevent dots if it can't match a dot, or if a + // sub-pattern will be preventing it anyway. + const needNoDot = !dot && !allowDot && aps.has(src.charAt(0)); + start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''; + } + } + } + // append the "end of path portion" pattern to negation tails + let end = ''; + if (this.isEnd() && + this.#root.#filledNegs && + this.#parent?.type === '!') { + end = '(?:$|\\/)'; + } + const final = start + src + end; + return [ + final, + (0, unescape_js_1.unescape)(src), + (this.#hasMagic = !!this.#hasMagic), + this.#uflag, + ]; + } + // We need to calculate the body *twice* if it's a repeat pattern + // at the start, once in nodot mode, then again in dot mode, so a + // pattern like *(?) can match 'x.y' + const repeated = this.type === '*' || this.type === '+'; + // some kind of extglob + const start = this.type === '!' ? '(?:(?!(?:' : '(?:'; + let body = this.#partsToRegExp(dot); + if (this.isStart() && this.isEnd() && !body && this.type !== '!') { + // invalid extglob, has to at least be *something* present, if it's + // the entire path portion. + const s = this.toString(); + this.#parts = [s]; + this.type = null; + this.#hasMagic = undefined; + return [s, (0, unescape_js_1.unescape)(this.toString()), false, false]; + } + // XXX abstract out this map method + let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot + ? '' + : this.#partsToRegExp(true); + if (bodyDotAllowed === body) { + bodyDotAllowed = ''; + } + if (bodyDotAllowed) { + body = `(?:${body})(?:${bodyDotAllowed})*?`; + } + // an empty !() is exactly equivalent to a starNoEmpty + let final = ''; + if (this.type === '!' && this.#emptyExt) { + final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty; + } + else { + const close = this.type === '!' + ? // !() must match something,but !(x) can match '' + '))' + + (this.isStart() && !dot && !allowDot ? startNoDot : '') + + star + + ')' + : this.type === '@' + ? ')' + : this.type === '?' + ? ')?' + : this.type === '+' && bodyDotAllowed + ? ')' + : this.type === '*' && bodyDotAllowed + ? `)?` + : `)${this.type}`; + final = start + body + close; + } + return [ + final, + (0, unescape_js_1.unescape)(body), + (this.#hasMagic = !!this.#hasMagic), + this.#uflag, + ]; + } + #partsToRegExp(dot) { + return this.#parts + .map(p => { + // extglob ASTs should only contain parent ASTs + /* c8 ignore start */ + if (typeof p === 'string') { + throw new Error('string type in extglob ast??'); + } + /* c8 ignore stop */ + // can ignore hasMagic, because extglobs are already always magic + const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot); + this.#uflag = this.#uflag || uflag; + return re; + }) + .filter(p => !(this.isStart() && this.isEnd()) || !!p) + .join('|'); + } + static #parseGlob(glob, hasMagic, noEmpty = false) { + let escaping = false; + let re = ''; + let uflag = false; + for (let i = 0; i < glob.length; i++) { + const c = glob.charAt(i); + if (escaping) { + escaping = false; + re += (reSpecials.has(c) ? '\\' : '') + c; + continue; + } + if (c === '\\') { + if (i === glob.length - 1) { + re += '\\\\'; + } + else { + escaping = true; + } + continue; + } + if (c === '[') { + const [src, needUflag, consumed, magic] = (0, brace_expressions_js_1.parseClass)(glob, i); + if (consumed) { + re += src; + uflag = uflag || needUflag; + i += consumed - 1; + hasMagic = hasMagic || magic; + continue; + } + } + if (c === '*') { + if (noEmpty && glob === '*') + re += starNoEmpty; + else + re += star; + hasMagic = true; + continue; + } + if (c === '?') { + re += qmark; + hasMagic = true; + continue; + } + re += regExpEscape(c); + } + return [re, (0, unescape_js_1.unescape)(glob), !!hasMagic, uflag]; + } +} +exports.AST = AST; +//# sourceMappingURL=ast.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.js.map b/backend/node_modules/minimatch/dist/commonjs/ast.js.map new file mode 100644 index 00000000..8383e433 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/ast.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"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","sourcesContent":["// parse a single path portion\n\nimport { parseClass } from './brace-expressions.js'\nimport { MinimatchOptions, MMRegExp } from './index.js'\nimport { unescape } from './unescape.js'\n\n// classes [] are handled by the parseClass method\n// for positive extglobs, we sub-parse the contents, and combine,\n// with the appropriate regexp close.\n// for negative extglobs, we sub-parse the contents, but then\n// have to include the rest of the pattern, then the parent, etc.,\n// as the thing that cannot be because RegExp negative lookaheads\n// are different from globs.\n//\n// So for example:\n// a@(i|w!(x|y)z|j)b => ^a(i|w((!?(x|y)zb).*)z|j)b$\n// 1 2 3 4 5 6 1 2 3 46 5 6\n//\n// Assembling the extglob requires not just the negated patterns themselves,\n// but also anything following the negative patterns up to the boundary\n// of the current pattern, plus anything following in the parent pattern.\n//\n//\n// So, first, we parse the string into an AST of extglobs, without turning\n// anything into regexps yet.\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y']}, 'z'], ['j']]}, 'b']\n//\n// Then, for all the negative extglobs, we append whatever comes after in\n// each parent as their tail\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y'], 'z', 'b'}, 'z'], ['j']]}, 'b']\n//\n// Lastly, we turn each of these pieces into a regexp, and join\n//\n// v----- .* because there's more following,\n// v v otherwise, .+ because it must be\n// v v *something* there.\n// ['^a', {@ ['i', 'w(?:(!?(?:x|y).*zb$).*)z', 'j' ]}, 'b$']\n// copy what follows into here--^^^^^\n// ['^a', '(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)', 'b$']\n// ['^a(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)b$']\n\nexport type ExtglobType = '!' | '?' | '+' | '*' | '@'\nconst types = new Set(['!', '?', '+', '*', '@'])\nconst isExtglobType = (c: string): c is ExtglobType =>\n types.has(c as ExtglobType)\n\n// Patterns that get prepended to bind to the start of either the\n// entire string, or just a single path portion, to prevent dots\n// and/or traversal patterns, when needed.\n// Exts don't need the ^ or / bit, because the root binds that already.\nconst startNoTraversal = '(?!(?:^|/)\\\\.\\\\.?(?:$|/))'\nconst startNoDot = '(?!\\\\.)'\n\n// characters that indicate a start of pattern needs the \"no dots\" bit,\n// because a dot *might* be matched. ( is not in the list, because in\n// the case of a child extglob, it will handle the prevention itself.\nconst addPatternStart = new Set(['[', '.'])\n// cases where traversal is A-OK, no dot prevention needed\nconst justDots = new Set(['..', '.'])\nconst reSpecials = new Set('().*{}+?[]^$\\\\!')\nconst regExpEscape = (s: string) =>\n s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// any single thing other than /\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n// use + when we need to ensure that *something* matches, because the * is\n// the only thing in the path portion.\nconst starNoEmpty = qmark + '+?'\n\n// remove the \\ chars that we added if we end up doing a nonmagic compare\n// const deslash = (s: string) => s.replace(/\\\\(.)/g, '$1')\n\nexport class AST {\n type: ExtglobType | null\n readonly #root: AST\n\n #hasMagic?: boolean\n #uflag: boolean = false\n #parts: (string | AST)[] = []\n readonly #parent?: AST\n readonly #parentIndex: number\n #negs: AST[]\n #filledNegs: boolean = false\n #options: MinimatchOptions\n #toString?: string\n // set to true if it's an extglob with no children\n // (which really means one child of '')\n #emptyExt: boolean = false\n\n constructor(\n type: ExtglobType | null,\n parent?: AST,\n options: MinimatchOptions = {}\n ) {\n this.type = type\n // extglobs are inherently magical\n if (type) this.#hasMagic = true\n this.#parent = parent\n this.#root = this.#parent ? this.#parent.#root : this\n this.#options = this.#root === this ? options : this.#root.#options\n this.#negs = this.#root === this ? [] : this.#root.#negs\n if (type === '!' && !this.#root.#filledNegs) this.#negs.push(this)\n this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0\n }\n\n get hasMagic(): boolean | undefined {\n /* c8 ignore start */\n if (this.#hasMagic !== undefined) return this.#hasMagic\n /* c8 ignore stop */\n for (const p of this.#parts) {\n if (typeof p === 'string') continue\n if (p.type || p.hasMagic) return (this.#hasMagic = true)\n }\n // note: will be undefined until we generate the regexp src and find out\n return this.#hasMagic\n }\n\n // reconstructs the pattern\n toString(): string {\n if (this.#toString !== undefined) return this.#toString\n if (!this.type) {\n return (this.#toString = this.#parts.map(p => String(p)).join(''))\n } else {\n return (this.#toString =\n this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')')\n }\n }\n\n #fillNegs() {\n /* c8 ignore start */\n if (this !== this.#root) throw new Error('should only call on root')\n if (this.#filledNegs) return this\n /* c8 ignore stop */\n\n // call toString() once to fill this out\n this.toString()\n this.#filledNegs = true\n let n: AST | undefined\n while ((n = this.#negs.pop())) {\n if (n.type !== '!') continue\n // walk up the tree, appending everthing that comes AFTER parentIndex\n let p: AST | undefined = n\n let pp = p.#parent\n while (pp) {\n for (\n let i = p.#parentIndex + 1;\n !pp.type && i < pp.#parts.length;\n i++\n ) {\n for (const part of n.#parts) {\n /* c8 ignore start */\n if (typeof part === 'string') {\n throw new Error('string part in extglob AST??')\n }\n /* c8 ignore stop */\n part.copyIn(pp.#parts[i])\n }\n }\n p = pp\n pp = p.#parent\n }\n }\n return this\n }\n\n push(...parts: (string | AST)[]) {\n for (const p of parts) {\n if (p === '') continue\n /* c8 ignore start */\n if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {\n throw new Error('invalid part: ' + p)\n }\n /* c8 ignore stop */\n this.#parts.push(p)\n }\n }\n\n toJSON() {\n const ret: any[] =\n this.type === null\n ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))\n : [this.type, ...this.#parts.map(p => (p as AST).toJSON())]\n if (this.isStart() && !this.type) ret.unshift([])\n if (\n this.isEnd() &&\n (this === this.#root ||\n (this.#root.#filledNegs && this.#parent?.type === '!'))\n ) {\n ret.push({})\n }\n return ret\n }\n\n isStart(): boolean {\n if (this.#root === this) return true\n // if (this.type) return !!this.#parent?.isStart()\n if (!this.#parent?.isStart()) return false\n if (this.#parentIndex === 0) return true\n // if everything AHEAD of this is a negation, then it's still the \"start\"\n const p = this.#parent\n for (let i = 0; i < this.#parentIndex; i++) {\n const pp = p.#parts[i]\n if (!(pp instanceof AST && pp.type === '!')) {\n return false\n }\n }\n return true\n }\n\n isEnd(): boolean {\n if (this.#root === this) return true\n if (this.#parent?.type === '!') return true\n if (!this.#parent?.isEnd()) return false\n if (!this.type) return this.#parent?.isEnd()\n // if not root, it'll always have a parent\n /* c8 ignore start */\n const pl = this.#parent ? this.#parent.#parts.length : 0\n /* c8 ignore stop */\n return this.#parentIndex === pl - 1\n }\n\n copyIn(part: AST | string) {\n if (typeof part === 'string') this.push(part)\n else this.push(part.clone(this))\n }\n\n clone(parent: AST) {\n const c = new AST(this.type, parent)\n for (const p of this.#parts) {\n c.copyIn(p)\n }\n return c\n }\n\n static #parseAST(\n str: string,\n ast: AST,\n pos: number,\n opt: MinimatchOptions\n ): number {\n let escaping = false\n let inBrace = false\n let braceStart = -1\n let braceNeg = false\n if (ast.type === null) {\n // outside of a extglob, append until we find a start\n let i = pos\n let acc = ''\n while (i < str.length) {\n const c = str.charAt(i++)\n // still accumulate escapes at this point, but we do ignore\n // starts that are escaped\n if (escaping || c === '\\\\') {\n escaping = !escaping\n acc += c\n continue\n }\n\n if (inBrace) {\n if (i === braceStart + 1) {\n if (c === '^' || c === '!') {\n braceNeg = true\n }\n } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n inBrace = false\n }\n acc += c\n continue\n } else if (c === '[') {\n inBrace = true\n braceStart = i\n braceNeg = false\n acc += c\n continue\n }\n\n if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {\n ast.push(acc)\n acc = ''\n const ext = new AST(c, ast)\n i = AST.#parseAST(str, ext, i, opt)\n ast.push(ext)\n continue\n }\n acc += c\n }\n ast.push(acc)\n return i\n }\n\n // some kind of extglob, pos is at the (\n // find the next | or )\n let i = pos + 1\n let part = new AST(null, ast)\n const parts: AST[] = []\n let acc = ''\n while (i < str.length) {\n const c = str.charAt(i++)\n // still accumulate escapes at this point, but we do ignore\n // starts that are escaped\n if (escaping || c === '\\\\') {\n escaping = !escaping\n acc += c\n continue\n }\n\n if (inBrace) {\n if (i === braceStart + 1) {\n if (c === '^' || c === '!') {\n braceNeg = true\n }\n } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n inBrace = false\n }\n acc += c\n continue\n } else if (c === '[') {\n inBrace = true\n braceStart = i\n braceNeg = false\n acc += c\n continue\n }\n\n if (isExtglobType(c) && str.charAt(i) === '(') {\n part.push(acc)\n acc = ''\n const ext = new AST(c, part)\n part.push(ext)\n i = AST.#parseAST(str, ext, i, opt)\n continue\n }\n if (c === '|') {\n part.push(acc)\n acc = ''\n parts.push(part)\n part = new AST(null, ast)\n continue\n }\n if (c === ')') {\n if (acc === '' && ast.#parts.length === 0) {\n ast.#emptyExt = true\n }\n part.push(acc)\n acc = ''\n ast.push(...parts, part)\n return i\n }\n acc += c\n }\n\n // unfinished extglob\n // if we got here, it was a malformed extglob! not an extglob, but\n // maybe something else in there.\n ast.type = null\n ast.#hasMagic = undefined\n ast.#parts = [str.substring(pos - 1)]\n return i\n }\n\n static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n const ast = new AST(null, undefined, options)\n AST.#parseAST(pattern, ast, 0, options)\n return ast\n }\n\n // returns the regular expression if there's magic, or the unescaped\n // string if not.\n toMMPattern(): MMRegExp | string {\n // should only be called on root\n /* c8 ignore start */\n if (this !== this.#root) return this.#root.toMMPattern()\n /* c8 ignore stop */\n const glob = this.toString()\n const [re, body, hasMagic, uflag] = this.toRegExpSource()\n // if we're in nocase mode, and not nocaseMagicOnly, then we do\n // still need a regular expression if we have to case-insensitively\n // match capital/lowercase characters.\n const anyMagic =\n hasMagic ||\n this.#hasMagic ||\n (this.#options.nocase &&\n !this.#options.nocaseMagicOnly &&\n glob.toUpperCase() !== glob.toLowerCase())\n if (!anyMagic) {\n return body\n }\n\n const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '')\n return Object.assign(new RegExp(`^${re}$`, flags), {\n _src: re,\n _glob: glob,\n })\n }\n\n get options() {\n return this.#options\n }\n\n // returns the string match, the regexp source, whether there's magic\n // in the regexp (so a regular expression is required) and whether or\n // not the uflag is needed for the regular expression (for posix classes)\n // TODO: instead of injecting the start/end at this point, just return\n // the BODY of the regexp, along with the start/end portions suitable\n // for binding the start/end in either a joined full-path makeRe context\n // (where we bind to (^|/), or a standalone matchPart context (where\n // we bind to ^, and not /). Otherwise slashes get duped!\n //\n // In part-matching mode, the start is:\n // - if not isStart: nothing\n // - if traversal possible, but not allowed: ^(?!\\.\\.?$)\n // - if dots allowed or not possible: ^\n // - if dots possible and not allowed: ^(?!\\.)\n // end is:\n // - if not isEnd(): nothing\n // - else: $\n //\n // In full-path matching mode, we put the slash at the START of the\n // pattern, so start is:\n // - if first pattern: same as part-matching mode\n // - if not isStart(): nothing\n // - if traversal possible, but not allowed: /(?!\\.\\.?(?:$|/))\n // - if dots allowed or not possible: /\n // - if dots possible and not allowed: /(?!\\.)\n // end is:\n // - if last pattern, same as part-matching mode\n // - else nothing\n //\n // Always put the (?:$|/) on negated tails, though, because that has to be\n // there to bind the end of the negated pattern portion, and it's easier to\n // just stick it in now rather than try to inject it later in the middle of\n // the pattern.\n //\n // We can just always return the same end, and leave it up to the caller\n // to know whether it's going to be used joined or in parts.\n // And, if the start is adjusted slightly, can do the same there:\n // - if not isStart: nothing\n // - if traversal possible, but not allowed: (?:/|^)(?!\\.\\.?$)\n // - if dots allowed or not possible: (?:/|^)\n // - if dots possible and not allowed: (?:/|^)(?!\\.)\n //\n // But it's better to have a simpler binding without a conditional, for\n // performance, so probably better to return both start options.\n //\n // Then the caller just ignores the end if it's not the first pattern,\n // and the start always gets applied.\n //\n // But that's always going to be $ if it's the ending pattern, or nothing,\n // so the caller can just attach $ at the end of the pattern when building.\n //\n // So the todo is:\n // - better detect what kind of start is needed\n // - return both flavors of starting pattern\n // - attach $ at the end of the pattern when creating the actual RegExp\n //\n // Ah, but wait, no, that all only applies to the root when the first pattern\n // is not an extglob. If the first pattern IS an extglob, then we need all\n // that dot prevention biz to live in the extglob portions, because eg\n // +(*|.x*) can match .xy but not .yx.\n //\n // So, return the two flavors if it's #root and the first child is not an\n // AST, otherwise leave it to the child AST to handle it, and there,\n // use the (?:^|/) style of start binding.\n //\n // Even simplified further:\n // - Since the start for a join is eg /(?!\\.) and the start for a part\n // is ^(?!\\.), we can just prepend (?!\\.) to the pattern (either root\n // or start or whatever) and prepend ^ or / at the Regexp construction.\n toRegExpSource(\n allowDot?: boolean\n ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n const dot = allowDot ?? !!this.#options.dot\n if (this.#root === this) this.#fillNegs()\n if (!this.type) {\n const noEmpty = this.isStart() && this.isEnd()\n const src = this.#parts\n .map(p => {\n const [re, _, hasMagic, uflag] =\n typeof p === 'string'\n ? AST.#parseGlob(p, this.#hasMagic, noEmpty)\n : p.toRegExpSource(allowDot)\n this.#hasMagic = this.#hasMagic || hasMagic\n this.#uflag = this.#uflag || uflag\n return re\n })\n .join('')\n\n let start = ''\n if (this.isStart()) {\n if (typeof this.#parts[0] === 'string') {\n // this is the string that will match the start of the pattern,\n // so we need to protect against dots and such.\n\n // '.' and '..' cannot match unless the pattern is that exactly,\n // even if it starts with . or dot:true is set.\n const dotTravAllowed =\n this.#parts.length === 1 && justDots.has(this.#parts[0])\n if (!dotTravAllowed) {\n const aps = addPatternStart\n // check if we have a possibility of matching . or ..,\n // and prevent that.\n const needNoTrav =\n // dots are allowed, and the pattern starts with [ or .\n (dot && aps.has(src.charAt(0))) ||\n // the pattern starts with \\., and then [ or .\n (src.startsWith('\\\\.') && aps.has(src.charAt(2))) ||\n // the pattern starts with \\.\\., and then [ or .\n (src.startsWith('\\\\.\\\\.') && aps.has(src.charAt(4)))\n // no need to prevent dots if it can't match a dot, or if a\n // sub-pattern will be preventing it anyway.\n const needNoDot = !dot && !allowDot && aps.has(src.charAt(0))\n\n start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''\n }\n }\n }\n\n // append the \"end of path portion\" pattern to negation tails\n let end = ''\n if (\n this.isEnd() &&\n this.#root.#filledNegs &&\n this.#parent?.type === '!'\n ) {\n end = '(?:$|\\\\/)'\n }\n const final = start + src + end\n return [\n final,\n unescape(src),\n (this.#hasMagic = !!this.#hasMagic),\n this.#uflag,\n ]\n }\n\n // We need to calculate the body *twice* if it's a repeat pattern\n // at the start, once in nodot mode, then again in dot mode, so a\n // pattern like *(?) can match 'x.y'\n\n const repeated = this.type === '*' || this.type === '+'\n // some kind of extglob\n const start = this.type === '!' ? '(?:(?!(?:' : '(?:'\n let body = this.#partsToRegExp(dot)\n\n if (this.isStart() && this.isEnd() && !body && this.type !== '!') {\n // invalid extglob, has to at least be *something* present, if it's\n // the entire path portion.\n const s = this.toString()\n this.#parts = [s]\n this.type = null\n this.#hasMagic = undefined\n return [s, unescape(this.toString()), false, false]\n }\n\n // XXX abstract out this map method\n let bodyDotAllowed =\n !repeated || allowDot || dot || !startNoDot\n ? ''\n : this.#partsToRegExp(true)\n if (bodyDotAllowed === body) {\n bodyDotAllowed = ''\n }\n if (bodyDotAllowed) {\n body = `(?:${body})(?:${bodyDotAllowed})*?`\n }\n\n // an empty !() is exactly equivalent to a starNoEmpty\n let final = ''\n if (this.type === '!' && this.#emptyExt) {\n final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty\n } else {\n const close =\n this.type === '!'\n ? // !() must match something,but !(x) can match ''\n '))' +\n (this.isStart() && !dot && !allowDot ? startNoDot : '') +\n star +\n ')'\n : this.type === '@'\n ? ')'\n : this.type === '?'\n ? ')?'\n : this.type === '+' && bodyDotAllowed\n ? ')'\n : this.type === '*' && bodyDotAllowed\n ? `)?`\n : `)${this.type}`\n final = start + body + close\n }\n return [\n final,\n unescape(body),\n (this.#hasMagic = !!this.#hasMagic),\n this.#uflag,\n ]\n }\n\n #partsToRegExp(dot: boolean) {\n return this.#parts\n .map(p => {\n // extglob ASTs should only contain parent ASTs\n /* c8 ignore start */\n if (typeof p === 'string') {\n throw new Error('string type in extglob ast??')\n }\n /* c8 ignore stop */\n // can ignore hasMagic, because extglobs are already always magic\n const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot)\n this.#uflag = this.#uflag || uflag\n return re\n })\n .filter(p => !(this.isStart() && this.isEnd()) || !!p)\n .join('|')\n }\n\n static #parseGlob(\n glob: string,\n hasMagic: boolean | undefined,\n noEmpty: boolean = false\n ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n let escaping = false\n let re = ''\n let uflag = false\n for (let i = 0; i < glob.length; i++) {\n const c = glob.charAt(i)\n if (escaping) {\n escaping = false\n re += (reSpecials.has(c) ? '\\\\' : '') + c\n continue\n }\n if (c === '\\\\') {\n if (i === glob.length - 1) {\n re += '\\\\\\\\'\n } else {\n escaping = true\n }\n continue\n }\n if (c === '[') {\n const [src, needUflag, consumed, magic] = parseClass(glob, i)\n if (consumed) {\n re += src\n uflag = uflag || needUflag\n i += consumed - 1\n hasMagic = hasMagic || magic\n continue\n }\n }\n if (c === '*') {\n if (noEmpty && glob === '*') re += starNoEmpty\n else re += star\n hasMagic = true\n continue\n }\n if (c === '?') {\n re += qmark\n hasMagic = true\n continue\n }\n re += regExpEscape(c)\n }\n return [re, unescape(glob), !!hasMagic, uflag]\n }\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts new file mode 100644 index 00000000..b1572deb --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts @@ -0,0 +1,8 @@ +export type ParseClassResult = [ + src: string, + uFlag: boolean, + consumed: number, + hasMagic: boolean +]; +export declare const parseClass: (glob: string, position: number) => ParseClassResult; +//# sourceMappingURL=brace-expressions.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map new file mode 100644 index 00000000..d3949648 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,SACf,MAAM,YACF,MAAM,qBA8HjB,CAAA"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js new file mode 100644 index 00000000..0e13eefc --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js @@ -0,0 +1,152 @@ +"use strict"; +// translate the various posix character classes into unicode properties +// this works across all unicode locales +Object.defineProperty(exports, "__esModule", { value: true }); +exports.parseClass = void 0; +// { : [, /u flag required, negated] +const posixClasses = { + '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true], + '[:alpha:]': ['\\p{L}\\p{Nl}', true], + '[:ascii:]': ['\\x' + '00-\\x' + '7f', false], + '[:blank:]': ['\\p{Zs}\\t', true], + '[:cntrl:]': ['\\p{Cc}', true], + '[:digit:]': ['\\p{Nd}', true], + '[:graph:]': ['\\p{Z}\\p{C}', true, true], + '[:lower:]': ['\\p{Ll}', true], + '[:print:]': ['\\p{C}', true], + '[:punct:]': ['\\p{P}', true], + '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true], + '[:upper:]': ['\\p{Lu}', true], + '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true], + '[:xdigit:]': ['A-Fa-f0-9', false], +}; +// only need to escape a few things inside of brace expressions +// escapes: [ \ ] - +const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&'); +// escape all regexp magic characters +const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// everything has already been escaped, we just have to join +const rangesToString = (ranges) => ranges.join(''); +// takes a glob string at a posix brace expression, and returns +// an equivalent regular expression source, and boolean indicating +// whether the /u flag needs to be applied, and the number of chars +// consumed to parse the character class. +// This also removes out of order ranges, and returns ($.) if the +// entire class just no good. +const parseClass = (glob, position) => { + const pos = position; + /* c8 ignore start */ + if (glob.charAt(pos) !== '[') { + throw new Error('not in a brace expression'); + } + /* c8 ignore stop */ + const ranges = []; + const negs = []; + let i = pos + 1; + let sawStart = false; + let uflag = false; + let escaping = false; + let negate = false; + let endPos = pos; + let rangeStart = ''; + WHILE: while (i < glob.length) { + const c = glob.charAt(i); + if ((c === '!' || c === '^') && i === pos + 1) { + negate = true; + i++; + continue; + } + if (c === ']' && sawStart && !escaping) { + endPos = i + 1; + break; + } + sawStart = true; + if (c === '\\') { + if (!escaping) { + escaping = true; + i++; + continue; + } + // escaped \ char, fall through and treat like normal char + } + if (c === '[' && !escaping) { + // either a posix class, a collation equivalent, or just a [ + for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) { + if (glob.startsWith(cls, i)) { + // invalid, [a-[] is fine, but not [a-[:alpha]] + if (rangeStart) { + return ['$.', false, glob.length - pos, true]; + } + i += cls.length; + if (neg) + negs.push(unip); + else + ranges.push(unip); + uflag = uflag || u; + continue WHILE; + } + } + } + // now it's just a normal character, effectively + escaping = false; + if (rangeStart) { + // throw this range away if it's not valid, but others + // can still match. + if (c > rangeStart) { + ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c)); + } + else if (c === rangeStart) { + ranges.push(braceEscape(c)); + } + rangeStart = ''; + i++; + continue; + } + // now might be the start of a range. + // can be either c-d or c-] or c] or c] at this point + if (glob.startsWith('-]', i + 1)) { + ranges.push(braceEscape(c + '-')); + i += 2; + continue; + } + if (glob.startsWith('-', i + 1)) { + rangeStart = c; + i += 2; + continue; + } + // not the start of a range, just a single character + ranges.push(braceEscape(c)); + i++; + } + if (endPos < i) { + // didn't see the end of the class, not a valid class, + // but might still be valid as a literal match. + return ['', false, 0, false]; + } + // if we got no ranges and no negates, then we have a range that + // cannot possibly match anything, and that poisons the whole glob + if (!ranges.length && !negs.length) { + return ['$.', false, glob.length - pos, true]; + } + // if we got one positive range, and it's a single character, then that's + // not actually a magic pattern, it's just that one literal character. + // we should not treat that as "magic", we should just return the literal + // character. [_] is a perfectly valid way to escape glob magic chars. + if (negs.length === 0 && + ranges.length === 1 && + /^\\?.$/.test(ranges[0]) && + !negate) { + const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]; + return [regexpEscape(r), false, endPos - pos, false]; + } + const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'; + const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'; + const comb = ranges.length && negs.length + ? '(' + sranges + '|' + snegs + ')' + : ranges.length + ? sranges + : snegs; + return [comb, uflag, endPos - pos, true]; +}; +exports.parseClass = parseClass; +//# sourceMappingURL=brace-expressions.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map new file mode 100644 index 00000000..86b04756 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"brace-expressions.js","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,wCAAwC;;;AAExC,8DAA8D;AAC9D,MAAM,YAAY,GAA0D;IAC1E,WAAW,EAAE,CAAC,sBAAsB,EAAE,IAAI,CAAC;IAC3C,WAAW,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,KAAK,GAAG,QAAQ,GAAG,IAAI,EAAE,KAAK,CAAC;IAC7C,WAAW,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC;IACjC,WAAW,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC;IAC9B,WAAW,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC;IAC9B,WAAW,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC;IACzC,WAAW,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC;IAC9B,WAAW,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC;IAC7B,WAAW,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC;IAC7B,WAAW,EAAE,CAAC,uBAAuB,EAAE,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC;IAC9B,UAAU,EAAE,CAAC,6BAA6B,EAAE,IAAI,CAAC;IACjD,YAAY,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC;CACnC,CAAA;AAED,+DAA+D;AAC/D,mBAAmB;AACnB,MAAM,WAAW,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;AACjE,qCAAqC;AACrC,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CACjC,CAAC,CAAC,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAA;AAE/C,4DAA4D;AAC5D,MAAM,cAAc,GAAG,CAAC,MAAgB,EAAU,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AASpE,+DAA+D;AAC/D,kEAAkE;AAClE,mEAAmE;AACnE,yCAAyC;AACzC,iEAAiE;AACjE,6BAA6B;AACtB,MAAM,UAAU,GAAG,CACxB,IAAY,EACZ,QAAgB,EACE,EAAE;IACpB,MAAM,GAAG,GAAG,QAAQ,CAAA;IACpB,qBAAqB;IACrB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;KAC7C;IACD,oBAAoB;IACpB,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,IAAI,GAAa,EAAE,CAAA;IAEzB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;IACf,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,IAAI,KAAK,GAAG,KAAK,CAAA;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,MAAM,GAAG,GAAG,CAAA;IAChB,IAAI,UAAU,GAAG,EAAE,CAAA;IACnB,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACxB,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE;YAC7C,MAAM,GAAG,IAAI,CAAA;YACb,CAAC,EAAE,CAAA;YACH,SAAQ;SACT;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,IAAI,CAAC,QAAQ,EAAE;YACtC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAA;YACd,MAAK;SACN;QAED,QAAQ,GAAG,IAAI,CAAA;QACf,IAAI,CAAC,KAAK,IAAI,EAAE;YACd,IAAI,CAAC,QAAQ,EAAE;gBACb,QAAQ,GAAG,IAAI,CAAA;gBACf,CAAC,EAAE,CAAA;gBACH,SAAQ;aACT;YACD,0DAA0D;SAC3D;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE;YAC1B,4DAA4D;YAC5D,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;gBAChE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE;oBAC3B,+CAA+C;oBAC/C,IAAI,UAAU,EAAE;wBACd,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,CAAA;qBAC9C;oBACD,CAAC,IAAI,GAAG,CAAC,MAAM,CAAA;oBACf,IAAI,GAAG;wBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;;wBACnB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACtB,KAAK,GAAG,KAAK,IAAI,CAAC,CAAA;oBAClB,SAAS,KAAK,CAAA;iBACf;aACF;SACF;QAED,gDAAgD;QAChD,QAAQ,GAAG,KAAK,CAAA;QAChB,IAAI,UAAU,EAAE;YACd,sDAAsD;YACtD,mBAAmB;YACnB,IAAI,CAAC,GAAG,UAAU,EAAE;gBAClB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;aAC5D;iBAAM,IAAI,CAAC,KAAK,UAAU,EAAE;gBAC3B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;aAC5B;YACD,UAAU,GAAG,EAAE,CAAA;YACf,CAAC,EAAE,CAAA;YACH,SAAQ;SACT;QAED,qCAAqC;QACrC,8DAA8D;QAC9D,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE;YAChC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;YACjC,CAAC,IAAI,CAAC,CAAA;YACN,SAAQ;SACT;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE;YAC/B,UAAU,GAAG,CAAC,CAAA;YACd,CAAC,IAAI,CAAC,CAAA;YACN,SAAQ;SACT;QAED,oDAAoD;QACpD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3B,CAAC,EAAE,CAAA;KACJ;IAED,IAAI,MAAM,GAAG,CAAC,EAAE;QACd,sDAAsD;QACtD,+CAA+C;QAC/C,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;KAC7B;IAED,gEAAgE;IAChE,kEAAkE;IAClE,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QAClC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,CAAA;KAC9C;IAED,yEAAyE;IACzE,sEAAsE;IACtE,yEAAyE;IACzE,sEAAsE;IACtE,IACE,IAAI,CAAC,MAAM,KAAK,CAAC;QACjB,MAAM,CAAC,MAAM,KAAK,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC,MAAM,EACP;QACA,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAClE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,CAAA;KACrD;IAED,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,GAAG,CAAA;IACxE,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,GAAG,CAAA;IACpE,MAAM,IAAI,GACR,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;QAC1B,CAAC,CAAC,GAAG,GAAG,OAAO,GAAG,GAAG,GAAG,KAAK,GAAG,GAAG;QACnC,CAAC,CAAC,MAAM,CAAC,MAAM;YACf,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,KAAK,CAAA;IAEX,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,CAAA;AAC1C,CAAC,CAAA;AAhIY,QAAA,UAAU,cAgItB","sourcesContent":["// translate the various posix character classes into unicode properties\n// this works across all unicode locales\n\n// { : [, /u flag required, negated]\nconst posixClasses: { [k: string]: [e: string, u: boolean, n?: boolean] } = {\n '[:alnum:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}', true],\n '[:alpha:]': ['\\\\p{L}\\\\p{Nl}', true],\n '[:ascii:]': ['\\\\x' + '00-\\\\x' + '7f', false],\n '[:blank:]': ['\\\\p{Zs}\\\\t', true],\n '[:cntrl:]': ['\\\\p{Cc}', true],\n '[:digit:]': ['\\\\p{Nd}', true],\n '[:graph:]': ['\\\\p{Z}\\\\p{C}', true, true],\n '[:lower:]': ['\\\\p{Ll}', true],\n '[:print:]': ['\\\\p{C}', true],\n '[:punct:]': ['\\\\p{P}', true],\n '[:space:]': ['\\\\p{Z}\\\\t\\\\r\\\\n\\\\v\\\\f', true],\n '[:upper:]': ['\\\\p{Lu}', true],\n '[:word:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}\\\\p{Pc}', true],\n '[:xdigit:]': ['A-Fa-f0-9', false],\n}\n\n// only need to escape a few things inside of brace expressions\n// escapes: [ \\ ] -\nconst braceEscape = (s: string) => s.replace(/[[\\]\\\\-]/g, '\\\\$&')\n// escape all regexp magic characters\nconst regexpEscape = (s: string) =>\n s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// everything has already been escaped, we just have to join\nconst rangesToString = (ranges: string[]): string => ranges.join('')\n\nexport type ParseClassResult = [\n src: string,\n uFlag: boolean,\n consumed: number,\n hasMagic: boolean\n]\n\n// takes a glob string at a posix brace expression, and returns\n// an equivalent regular expression source, and boolean indicating\n// whether the /u flag needs to be applied, and the number of chars\n// consumed to parse the character class.\n// This also removes out of order ranges, and returns ($.) if the\n// entire class just no good.\nexport const parseClass = (\n glob: string,\n position: number\n): ParseClassResult => {\n const pos = position\n /* c8 ignore start */\n if (glob.charAt(pos) !== '[') {\n throw new Error('not in a brace expression')\n }\n /* c8 ignore stop */\n const ranges: string[] = []\n const negs: string[] = []\n\n let i = pos + 1\n let sawStart = false\n let uflag = false\n let escaping = false\n let negate = false\n let endPos = pos\n let rangeStart = ''\n WHILE: while (i < glob.length) {\n const c = glob.charAt(i)\n if ((c === '!' || c === '^') && i === pos + 1) {\n negate = true\n i++\n continue\n }\n\n if (c === ']' && sawStart && !escaping) {\n endPos = i + 1\n break\n }\n\n sawStart = true\n if (c === '\\\\') {\n if (!escaping) {\n escaping = true\n i++\n continue\n }\n // escaped \\ char, fall through and treat like normal char\n }\n if (c === '[' && !escaping) {\n // either a posix class, a collation equivalent, or just a [\n for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {\n if (glob.startsWith(cls, i)) {\n // invalid, [a-[] is fine, but not [a-[:alpha]]\n if (rangeStart) {\n return ['$.', false, glob.length - pos, true]\n }\n i += cls.length\n if (neg) negs.push(unip)\n else ranges.push(unip)\n uflag = uflag || u\n continue WHILE\n }\n }\n }\n\n // now it's just a normal character, effectively\n escaping = false\n if (rangeStart) {\n // throw this range away if it's not valid, but others\n // can still match.\n if (c > rangeStart) {\n ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c))\n } else if (c === rangeStart) {\n ranges.push(braceEscape(c))\n }\n rangeStart = ''\n i++\n continue\n }\n\n // now might be the start of a range.\n // can be either c-d or c-] or c] or c] at this point\n if (glob.startsWith('-]', i + 1)) {\n ranges.push(braceEscape(c + '-'))\n i += 2\n continue\n }\n if (glob.startsWith('-', i + 1)) {\n rangeStart = c\n i += 2\n continue\n }\n\n // not the start of a range, just a single character\n ranges.push(braceEscape(c))\n i++\n }\n\n if (endPos < i) {\n // didn't see the end of the class, not a valid class,\n // but might still be valid as a literal match.\n return ['', false, 0, false]\n }\n\n // if we got no ranges and no negates, then we have a range that\n // cannot possibly match anything, and that poisons the whole glob\n if (!ranges.length && !negs.length) {\n return ['$.', false, glob.length - pos, true]\n }\n\n // if we got one positive range, and it's a single character, then that's\n // not actually a magic pattern, it's just that one literal character.\n // we should not treat that as \"magic\", we should just return the literal\n // character. [_] is a perfectly valid way to escape glob magic chars.\n if (\n negs.length === 0 &&\n ranges.length === 1 &&\n /^\\\\?.$/.test(ranges[0]) &&\n !negate\n ) {\n const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]\n return [regexpEscape(r), false, endPos - pos, false]\n }\n\n const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'\n const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'\n const comb =\n ranges.length && negs.length\n ? '(' + sranges + '|' + snegs + ')'\n : ranges.length\n ? sranges\n : snegs\n\n return [comb, uflag, endPos - pos, true]\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.d.ts b/backend/node_modules/minimatch/dist/commonjs/escape.d.ts new file mode 100644 index 00000000..dc3e3163 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/escape.d.ts @@ -0,0 +1,12 @@ +import { MinimatchOptions } from './index.js'; +/** + * Escape all magic characters in a glob pattern. + * + * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape} + * option is used, then characters are escaped by wrapping in `[]`, because + * a magic character wrapped in a character class can only be satisfied by + * that exact character. In this mode, `\` is _not_ escaped, because it is + * not interpreted as a magic character, but instead as a path separator. + */ +export declare const escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string; +//# sourceMappingURL=escape.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map new file mode 100644 index 00000000..0779dae7 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,MACd,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAQlD,CAAA"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.js b/backend/node_modules/minimatch/dist/commonjs/escape.js new file mode 100644 index 00000000..02a4f8a8 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/escape.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.escape = void 0; +/** + * Escape all magic characters in a glob pattern. + * + * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape} + * option is used, then characters are escaped by wrapping in `[]`, because + * a magic character wrapped in a character class can only be satisfied by + * that exact character. In this mode, `\` is _not_ escaped, because it is + * not interpreted as a magic character, but instead as a path separator. + */ +const escape = (s, { windowsPathsNoEscape = false, } = {}) => { + // don't need to escape +@! because we escape the parens + // that make those magic, and escaping ! as [!] isn't valid, + // because [!]] is a valid glob class meaning not ']'. + return windowsPathsNoEscape + ? s.replace(/[?*()[\]]/g, '[$&]') + : s.replace(/[?*()[\]\\]/g, '\\$&'); +}; +exports.escape = escape; +//# sourceMappingURL=escape.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.js.map b/backend/node_modules/minimatch/dist/commonjs/escape.js.map new file mode 100644 index 00000000..264b2ea5 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/escape.js.map @@ -0,0 +1 @@ +{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":";;;AACA;;;;;;;;GAQG;AACI,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA;AAZY,QAAA,MAAM,UAYlB","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character. In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n */\nexport const escape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n }: Pick = {}\n) => {\n // don't need to escape +@! because we escape the parens\n // that make those magic, and escaping ! as [!] isn't valid,\n // because [!]] is a valid glob class meaning not ']'.\n return windowsPathsNoEscape\n ? s.replace(/[?*()[\\]]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/index.d.ts b/backend/node_modules/minimatch/dist/commonjs/index.d.ts new file mode 100644 index 00000000..41d16a98 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/index.d.ts @@ -0,0 +1,94 @@ +import { AST } from './ast.js'; +type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd'; +export interface MinimatchOptions { + nobrace?: boolean; + nocomment?: boolean; + nonegate?: boolean; + debug?: boolean; + noglobstar?: boolean; + noext?: boolean; + nonull?: boolean; + windowsPathsNoEscape?: boolean; + allowWindowsEscape?: boolean; + partial?: boolean; + dot?: boolean; + nocase?: boolean; + nocaseMagicOnly?: boolean; + magicalBraces?: boolean; + matchBase?: boolean; + flipNegate?: boolean; + preserveMultipleSlashes?: boolean; + optimizationLevel?: number; + platform?: Platform; + windowsNoMagicRoot?: boolean; +} +export declare const minimatch: { + (p: string, pattern: string, options?: MinimatchOptions): boolean; + sep: Sep; + GLOBSTAR: typeof GLOBSTAR; + filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean; + defaults: (def: MinimatchOptions) => typeof minimatch; + braceExpand: (pattern: string, options?: MinimatchOptions) => string[]; + makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp; + match: (list: string[], pattern: string, options?: MinimatchOptions) => string[]; + AST: typeof AST; + Minimatch: typeof Minimatch; + escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string; + unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string; +}; +type Sep = '\\' | '/'; +export declare const sep: Sep; +export declare const GLOBSTAR: unique symbol; +export declare const filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean; +export declare const defaults: (def: MinimatchOptions) => typeof minimatch; +export declare const braceExpand: (pattern: string, options?: MinimatchOptions) => string[]; +export declare const makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp; +export declare const match: (list: string[], pattern: string, options?: MinimatchOptions) => string[]; +export type MMRegExp = RegExp & { + _src?: string; + _glob?: string; +}; +export type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR; +export type ParseReturn = ParseReturnFiltered | false; +export declare class Minimatch { + options: MinimatchOptions; + set: ParseReturnFiltered[][]; + pattern: string; + windowsPathsNoEscape: boolean; + nonegate: boolean; + negate: boolean; + comment: boolean; + empty: boolean; + preserveMultipleSlashes: boolean; + partial: boolean; + globSet: string[]; + globParts: string[][]; + nocase: boolean; + isWindows: boolean; + platform: Platform; + windowsNoMagicRoot: boolean; + regexp: false | null | MMRegExp; + constructor(pattern: string, options?: MinimatchOptions); + hasMagic(): boolean; + debug(..._: any[]): void; + make(): void; + preprocess(globParts: string[][]): string[][]; + adjascentGlobstarOptimize(globParts: string[][]): string[][]; + levelOneOptimize(globParts: string[][]): string[][]; + levelTwoFileOptimize(parts: string | string[]): string[]; + firstPhasePreProcess(globParts: string[][]): string[][]; + secondPhasePreProcess(globParts: string[][]): string[][]; + partsMatch(a: string[], b: string[], emptyGSMatch?: boolean): false | string[]; + parseNegate(): void; + matchOne(file: string[], pattern: ParseReturn[], partial?: boolean): boolean; + braceExpand(): string[]; + parse(pattern: string): ParseReturn; + makeRe(): false | MMRegExp; + slashSplit(p: string): string[]; + match(f: string, partial?: boolean): boolean; + static defaults(def: MinimatchOptions): typeof Minimatch; +} +export { AST } from './ast.js'; +export { escape } from './escape.js'; +export { unescape } from './unescape.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/index.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/index.d.ts.map new file mode 100644 index 00000000..195491d8 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/index.js b/backend/node_modules/minimatch/dist/commonjs/index.js new file mode 100644 index 00000000..64a0f1f8 --- /dev/null +++ b/backend/node_modules/minimatch/dist/commonjs/index.js @@ -0,0 +1,1017 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unescape = exports.escape = exports.AST = exports.Minimatch = exports.match = exports.makeRe = exports.braceExpand = exports.defaults = exports.filter = exports.GLOBSTAR = exports.sep = exports.minimatch = void 0; +const brace_expansion_1 = __importDefault(require("brace-expansion")); +const assert_valid_pattern_js_1 = require("./assert-valid-pattern.js"); +const ast_js_1 = require("./ast.js"); +const escape_js_1 = require("./escape.js"); +const unescape_js_1 = require("./unescape.js"); +const minimatch = (p, pattern, options = {}) => { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false; + } + return new Minimatch(pattern, options).match(p); +}; +exports.minimatch = minimatch; +// Optimized checking for the most common glob patterns. +const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; +const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext); +const starDotExtTestDot = (ext) => (f) => f.endsWith(ext); +const starDotExtTestNocase = (ext) => { + ext = ext.toLowerCase(); + return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext); +}; +const starDotExtTestNocaseDot = (ext) => { + ext = ext.toLowerCase(); + return (f) => f.toLowerCase().endsWith(ext); +}; +const starDotStarRE = /^\*+\.\*+$/; +const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.'); +const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.'); +const dotStarRE = /^\.\*+$/; +const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.'); +const starRE = /^\*+$/; +const starTest = (f) => f.length !== 0 && !f.startsWith('.'); +const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..'; +const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; +const qmarksTestNocase = ([$0, ext = '']) => { + const noext = qmarksTestNoExt([$0]); + if (!ext) + return noext; + ext = ext.toLowerCase(); + return (f) => noext(f) && f.toLowerCase().endsWith(ext); +}; +const qmarksTestNocaseDot = ([$0, ext = '']) => { + const noext = qmarksTestNoExtDot([$0]); + if (!ext) + return noext; + ext = ext.toLowerCase(); + return (f) => noext(f) && f.toLowerCase().endsWith(ext); +}; +const qmarksTestDot = ([$0, ext = '']) => { + const noext = qmarksTestNoExtDot([$0]); + return !ext ? noext : (f) => noext(f) && f.endsWith(ext); +}; +const qmarksTest = ([$0, ext = '']) => { + const noext = qmarksTestNoExt([$0]); + return !ext ? noext : (f) => noext(f) && f.endsWith(ext); +}; +const qmarksTestNoExt = ([$0]) => { + const len = $0.length; + return (f) => f.length === len && !f.startsWith('.'); +}; +const qmarksTestNoExtDot = ([$0]) => { + const len = $0.length; + return (f) => f.length === len && f !== '.' && f !== '..'; +}; +/* c8 ignore start */ +const defaultPlatform = (typeof process === 'object' && process + ? (typeof process.env === 'object' && + process.env && + process.env.__MINIMATCH_TESTING_PLATFORM__) || + process.platform + : 'posix'); +const path = { + win32: { sep: '\\' }, + posix: { sep: '/' }, +}; +/* c8 ignore stop */ +exports.sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep; +exports.minimatch.sep = exports.sep; +exports.GLOBSTAR = Symbol('globstar **'); +exports.minimatch.GLOBSTAR = exports.GLOBSTAR; +// any single thing other than / +// don't need to escape / when using new RegExp() +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?'; +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?'; +const filter = (pattern, options = {}) => (p) => (0, exports.minimatch)(p, pattern, options); +exports.filter = filter; +exports.minimatch.filter = exports.filter; +const ext = (a, b = {}) => Object.assign({}, a, b); +const defaults = (def) => { + if (!def || typeof def !== 'object' || !Object.keys(def).length) { + return exports.minimatch; + } + const orig = exports.minimatch; + const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options)); + return Object.assign(m, { + Minimatch: class Minimatch extends orig.Minimatch { + constructor(pattern, options = {}) { + super(pattern, ext(def, options)); + } + static defaults(options) { + return orig.defaults(ext(def, options)).Minimatch; + } + }, + AST: class AST extends orig.AST { + /* c8 ignore start */ + constructor(type, parent, options = {}) { + super(type, parent, ext(def, options)); + } + /* c8 ignore stop */ + static fromGlob(pattern, options = {}) { + return orig.AST.fromGlob(pattern, ext(def, options)); + } + }, + unescape: (s, options = {}) => orig.unescape(s, ext(def, options)), + escape: (s, options = {}) => orig.escape(s, ext(def, options)), + filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), + defaults: (options) => orig.defaults(ext(def, options)), + makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), + braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), + match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), + sep: orig.sep, + GLOBSTAR: exports.GLOBSTAR, + }); +}; +exports.defaults = defaults; +exports.minimatch.defaults = exports.defaults; +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +const braceExpand = (pattern, options = {}) => { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + // Thanks to Yeting Li for + // improving this regexp to avoid a ReDOS vulnerability. + if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { + // shortcut. no need to expand. + return [pattern]; + } + return (0, brace_expansion_1.default)(pattern); +}; +exports.braceExpand = braceExpand; +exports.minimatch.braceExpand = exports.braceExpand; +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); +exports.makeRe = makeRe; +exports.minimatch.makeRe = exports.makeRe; +const match = (list, pattern, options = {}) => { + const mm = new Minimatch(pattern, options); + list = list.filter(f => mm.match(f)); + if (mm.options.nonull && !list.length) { + list.push(pattern); + } + return list; +}; +exports.match = match; +exports.minimatch.match = exports.match; +// replace stuff like \* with * +const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +class Minimatch { + options; + set; + pattern; + windowsPathsNoEscape; + nonegate; + negate; + comment; + empty; + preserveMultipleSlashes; + partial; + globSet; + globParts; + nocase; + isWindows; + platform; + windowsNoMagicRoot; + regexp; + constructor(pattern, options = {}) { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + options = options || {}; + this.options = options; + this.pattern = pattern; + this.platform = options.platform || defaultPlatform; + this.isWindows = this.platform === 'win32'; + this.windowsPathsNoEscape = + !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; + if (this.windowsPathsNoEscape) { + this.pattern = this.pattern.replace(/\\/g, '/'); + } + this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; + this.regexp = null; + this.negate = false; + this.nonegate = !!options.nonegate; + this.comment = false; + this.empty = false; + this.partial = !!options.partial; + this.nocase = !!this.options.nocase; + this.windowsNoMagicRoot = + options.windowsNoMagicRoot !== undefined + ? options.windowsNoMagicRoot + : !!(this.isWindows && this.nocase); + this.globSet = []; + this.globParts = []; + this.set = []; + // make the set of regexps etc. + this.make(); + } + hasMagic() { + if (this.options.magicalBraces && this.set.length > 1) { + return true; + } + for (const pattern of this.set) { + for (const part of pattern) { + if (typeof part !== 'string') + return true; + } + } + return false; + } + debug(..._) { } + make() { + const pattern = this.pattern; + const options = this.options; + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true; + return; + } + if (!pattern) { + this.empty = true; + return; + } + // step 1: figure out negation, etc. + this.parseNegate(); + // step 2: expand braces + this.globSet = [...new Set(this.braceExpand())]; + if (options.debug) { + this.debug = (...args) => console.error(...args); + } + this.debug(this.pattern, this.globSet); + // step 3: now we have a set, so turn each one into a series of + // path-portion matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + // + // First, we preprocess to make the glob pattern sets a bit simpler + // and deduped. There are some perf-killing patterns that can cause + // problems with a glob walk, but we can simplify them down a bit. + const rawGlobParts = this.globSet.map(s => this.slashSplit(s)); + this.globParts = this.preprocess(rawGlobParts); + this.debug(this.pattern, this.globParts); + // glob --> regexps + let set = this.globParts.map((s, _, __) => { + if (this.isWindows && this.windowsNoMagicRoot) { + // check if it's a drive or unc path. + const isUNC = s[0] === '' && + s[1] === '' && + (s[2] === '?' || !globMagic.test(s[2])) && + !globMagic.test(s[3]); + const isDrive = /^[a-z]:/i.test(s[0]); + if (isUNC) { + return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]; + } + else if (isDrive) { + return [s[0], ...s.slice(1).map(ss => this.parse(ss))]; + } + } + return s.map(ss => this.parse(ss)); + }); + this.debug(this.pattern, set); + // filter out everything that didn't compile properly. + this.set = set.filter(s => s.indexOf(false) === -1); + // do not treat the ? in UNC paths as magic + if (this.isWindows) { + for (let i = 0; i < this.set.length; i++) { + const p = this.set[i]; + if (p[0] === '' && + p[1] === '' && + this.globParts[i][2] === '?' && + typeof p[3] === 'string' && + /^[a-z]:$/i.test(p[3])) { + p[2] = '?'; + } + } + } + this.debug(this.pattern, this.set); + } + // various transforms to equivalent pattern sets that are + // faster to process in a filesystem walk. The goal is to + // eliminate what we can, and push all ** patterns as far + // to the right as possible, even if it increases the number + // of patterns that we have to process. + preprocess(globParts) { + // if we're not in globstar mode, then turn all ** into * + if (this.options.noglobstar) { + for (let i = 0; i < globParts.length; i++) { + for (let j = 0; j < globParts[i].length; j++) { + if (globParts[i][j] === '**') { + globParts[i][j] = '*'; + } + } + } + } + const { optimizationLevel = 1 } = this.options; + if (optimizationLevel >= 2) { + // aggressive optimization for the purpose of fs walking + globParts = this.firstPhasePreProcess(globParts); + globParts = this.secondPhasePreProcess(globParts); + } + else if (optimizationLevel >= 1) { + // just basic optimizations to remove some .. parts + globParts = this.levelOneOptimize(globParts); + } + else { + // just collapse multiple ** portions into one + globParts = this.adjascentGlobstarOptimize(globParts); + } + return globParts; + } + // just get rid of adjascent ** portions + adjascentGlobstarOptimize(globParts) { + return globParts.map(parts => { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let i = gs; + while (parts[i + 1] === '**') { + i++; + } + if (i !== gs) { + parts.splice(gs, i - gs); + } + } + return parts; + }); + } + // get rid of adjascent ** and resolve .. portions + levelOneOptimize(globParts) { + return globParts.map(parts => { + parts = parts.reduce((set, part) => { + const prev = set[set.length - 1]; + if (part === '**' && prev === '**') { + return set; + } + if (part === '..') { + if (prev && prev !== '..' && prev !== '.' && prev !== '**') { + set.pop(); + return set; + } + } + set.push(part); + return set; + }, []); + return parts.length === 0 ? [''] : parts; + }); + } + levelTwoFileOptimize(parts) { + if (!Array.isArray(parts)) { + parts = this.slashSplit(parts); + } + let didSomething = false; + do { + didSomething = false; + //

// -> 
/
+            if (!this.preserveMultipleSlashes) {
+                for (let i = 1; i < parts.length - 1; i++) {
+                    const p = parts[i];
+                    // don't squeeze out UNC patterns
+                    if (i === 1 && p === '' && parts[0] === '')
+                        continue;
+                    if (p === '.' || p === '') {
+                        didSomething = true;
+                        parts.splice(i, 1);
+                        i--;
+                    }
+                }
+                if (parts[0] === '.' &&
+                    parts.length === 2 &&
+                    (parts[1] === '.' || parts[1] === '')) {
+                    didSomething = true;
+                    parts.pop();
+                }
+            }
+            // 
/

/../ ->

/
+            let dd = 0;
+            while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                const p = parts[dd - 1];
+                if (p && p !== '.' && p !== '..' && p !== '**') {
+                    didSomething = true;
+                    parts.splice(dd - 1, 2);
+                    dd -= 2;
+                }
+            }
+        } while (didSomething);
+        return parts.length === 0 ? [''] : parts;
+    }
+    // First phase: single-pattern processing
+    // 
 is 1 or more portions
+    //  is 1 or more portions
+    // 

is any portion other than ., .., '', or ** + // is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + //

// -> 
/
+    // 
/

/../ ->

/
+    // **/**/ -> **/
+    //
+    // **/*/ -> */**/ <== not valid because ** doesn't follow
+    // this WOULD be allowed if ** did follow symlinks, or * didn't
+    firstPhasePreProcess(globParts) {
+        let didSomething = false;
+        do {
+            didSomething = false;
+            // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + for (let parts of globParts) { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let gss = gs; + while (parts[gss + 1] === '**') { + //

/**/**/ -> 
/**/
+                        gss++;
+                    }
+                    // eg, if gs is 2 and gss is 4, that means we have 3 **
+                    // parts, and can remove 2 of them.
+                    if (gss > gs) {
+                        parts.splice(gs + 1, gss - gs);
+                    }
+                    let next = parts[gs + 1];
+                    const p = parts[gs + 2];
+                    const p2 = parts[gs + 3];
+                    if (next !== '..')
+                        continue;
+                    if (!p ||
+                        p === '.' ||
+                        p === '..' ||
+                        !p2 ||
+                        p2 === '.' ||
+                        p2 === '..') {
+                        continue;
+                    }
+                    didSomething = true;
+                    // edit parts in place, and push the new one
+                    parts.splice(gs, 1);
+                    const other = parts.slice(0);
+                    other[gs] = '**';
+                    globParts.push(other);
+                    gs--;
+                }
+                // 
// -> 
/
+                if (!this.preserveMultipleSlashes) {
+                    for (let i = 1; i < parts.length - 1; i++) {
+                        const p = parts[i];
+                        // don't squeeze out UNC patterns
+                        if (i === 1 && p === '' && parts[0] === '')
+                            continue;
+                        if (p === '.' || p === '') {
+                            didSomething = true;
+                            parts.splice(i, 1);
+                            i--;
+                        }
+                    }
+                    if (parts[0] === '.' &&
+                        parts.length === 2 &&
+                        (parts[1] === '.' || parts[1] === '')) {
+                        didSomething = true;
+                        parts.pop();
+                    }
+                }
+                // 
/

/../ ->

/
+                let dd = 0;
+                while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                    const p = parts[dd - 1];
+                    if (p && p !== '.' && p !== '..' && p !== '**') {
+                        didSomething = true;
+                        const needDot = dd === 1 && parts[dd + 1] === '**';
+                        const splin = needDot ? ['.'] : [];
+                        parts.splice(dd - 1, 2, ...splin);
+                        if (parts.length === 0)
+                            parts.push('');
+                        dd -= 2;
+                    }
+                }
+            }
+        } while (didSomething);
+        return globParts;
+    }
+    // second phase: multi-pattern dedupes
+    // {
/*/,
/

/} ->

/*/
+    // {
/,
/} -> 
/
+    // {
/**/,
/} -> 
/**/
+    //
+    // {
/**/,
/**/

/} ->

/**/
+    // ^-- not valid because ** doens't follow symlinks
+    secondPhasePreProcess(globParts) {
+        for (let i = 0; i < globParts.length - 1; i++) {
+            for (let j = i + 1; j < globParts.length; j++) {
+                const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
+                if (matched) {
+                    globParts[i] = [];
+                    globParts[j] = matched;
+                    break;
+                }
+            }
+        }
+        return globParts.filter(gs => gs.length);
+    }
+    partsMatch(a, b, emptyGSMatch = false) {
+        let ai = 0;
+        let bi = 0;
+        let result = [];
+        let which = '';
+        while (ai < a.length && bi < b.length) {
+            if (a[ai] === b[bi]) {
+                result.push(which === 'b' ? b[bi] : a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
+                result.push(a[ai]);
+                ai++;
+            }
+            else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
+                result.push(b[bi]);
+                bi++;
+            }
+            else if (a[ai] === '*' &&
+                b[bi] &&
+                (this.options.dot || !b[bi].startsWith('.')) &&
+                b[bi] !== '**') {
+                if (which === 'b')
+                    return false;
+                which = 'a';
+                result.push(a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (b[bi] === '*' &&
+                a[ai] &&
+                (this.options.dot || !a[ai].startsWith('.')) &&
+                a[ai] !== '**') {
+                if (which === 'a')
+                    return false;
+                which = 'b';
+                result.push(b[bi]);
+                ai++;
+                bi++;
+            }
+            else {
+                return false;
+            }
+        }
+        // if we fall out of the loop, it means they two are identical
+        // as long as their lengths match
+        return a.length === b.length && result;
+    }
+    parseNegate() {
+        if (this.nonegate)
+            return;
+        const pattern = this.pattern;
+        let negate = false;
+        let negateOffset = 0;
+        for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
+            negate = !negate;
+            negateOffset++;
+        }
+        if (negateOffset)
+            this.pattern = pattern.slice(negateOffset);
+        this.negate = negate;
+    }
+    // set partial to true to test if, for example,
+    // "/a/b" matches the start of "/*/b/*/d"
+    // Partial means, if you run out of file before you run
+    // out of pattern, then that's fine, as long as all
+    // the parts match.
+    matchOne(file, pattern, partial = false) {
+        const options = this.options;
+        // UNC paths like //?/X:/... can match X:/... and vice versa
+        // Drive letters in absolute drive or unc paths are always compared
+        // case-insensitively.
+        if (this.isWindows) {
+            const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
+            const fileUNC = !fileDrive &&
+                file[0] === '' &&
+                file[1] === '' &&
+                file[2] === '?' &&
+                /^[a-z]:$/i.test(file[3]);
+            const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
+            const patternUNC = !patternDrive &&
+                pattern[0] === '' &&
+                pattern[1] === '' &&
+                pattern[2] === '?' &&
+                typeof pattern[3] === 'string' &&
+                /^[a-z]:$/i.test(pattern[3]);
+            const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
+            const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
+            if (typeof fdi === 'number' && typeof pdi === 'number') {
+                const [fd, pd] = [file[fdi], pattern[pdi]];
+                if (fd.toLowerCase() === pd.toLowerCase()) {
+                    pattern[pdi] = fd;
+                    if (pdi > fdi) {
+                        pattern = pattern.slice(pdi);
+                    }
+                    else if (fdi > pdi) {
+                        file = file.slice(fdi);
+                    }
+                }
+            }
+        }
+        // resolve and reduce . and .. portions in the file as well.
+        // dont' need to do the second phase, because it's only one string[]
+        const { optimizationLevel = 1 } = this.options;
+        if (optimizationLevel >= 2) {
+            file = this.levelTwoFileOptimize(file);
+        }
+        this.debug('matchOne', this, { file, pattern });
+        this.debug('matchOne', file.length, pattern.length);
+        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
+            this.debug('matchOne loop');
+            var p = pattern[pi];
+            var f = file[fi];
+            this.debug(pattern, p, f);
+            // should be impossible.
+            // some invalid regexp stuff in the set.
+            /* c8 ignore start */
+            if (p === false) {
+                return false;
+            }
+            /* c8 ignore stop */
+            if (p === exports.GLOBSTAR) {
+                this.debug('GLOBSTAR', [pattern, p, f]);
+                // "**"
+                // a/**/b/**/c would match the following:
+                // a/b/x/y/z/c
+                // a/x/y/z/b/c
+                // a/b/x/b/x/c
+                // a/b/c
+                // To do this, take the rest of the pattern after
+                // the **, and see if it would match the file remainder.
+                // If so, return success.
+                // If not, the ** "swallows" a segment, and try again.
+                // This is recursively awful.
+                //
+                // a/**/b/**/c matching a/b/x/y/z/c
+                // - a matches a
+                // - doublestar
+                //   - matchOne(b/x/y/z/c, b/**/c)
+                //     - b matches b
+                //     - doublestar
+                //       - matchOne(x/y/z/c, c) -> no
+                //       - matchOne(y/z/c, c) -> no
+                //       - matchOne(z/c, c) -> no
+                //       - matchOne(c, c) yes, hit
+                var fr = fi;
+                var pr = pi + 1;
+                if (pr === pl) {
+                    this.debug('** at the end');
+                    // a ** at the end will just swallow the rest.
+                    // We have found a match.
+                    // however, it will not swallow /.x, unless
+                    // options.dot is set.
+                    // . and .. are *never* matched by **, for explosively
+                    // exponential reasons.
+                    for (; fi < fl; fi++) {
+                        if (file[fi] === '.' ||
+                            file[fi] === '..' ||
+                            (!options.dot && file[fi].charAt(0) === '.'))
+                            return false;
+                    }
+                    return true;
+                }
+                // ok, let's see if we can swallow whatever we can.
+                while (fr < fl) {
+                    var swallowee = file[fr];
+                    this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
+                    // XXX remove this slice.  Just pass the start index.
+                    if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
+                        this.debug('globstar found match!', fr, fl, swallowee);
+                        // found a match.
+                        return true;
+                    }
+                    else {
+                        // can't swallow "." or ".." ever.
+                        // can only swallow ".foo" when explicitly asked.
+                        if (swallowee === '.' ||
+                            swallowee === '..' ||
+                            (!options.dot && swallowee.charAt(0) === '.')) {
+                            this.debug('dot detected!', file, fr, pattern, pr);
+                            break;
+                        }
+                        // ** swallows a segment, and continue.
+                        this.debug('globstar swallow a segment, and continue');
+                        fr++;
+                    }
+                }
+                // no match was found.
+                // However, in partial mode, we can't say this is necessarily over.
+                /* c8 ignore start */
+                if (partial) {
+                    // ran out of file
+                    this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
+                    if (fr === fl) {
+                        return true;
+                    }
+                }
+                /* c8 ignore stop */
+                return false;
+            }
+            // something other than **
+            // non-magic patterns just have to match exactly
+            // patterns with magic have been turned into regexps.
+            let hit;
+            if (typeof p === 'string') {
+                hit = f === p;
+                this.debug('string match', p, f, hit);
+            }
+            else {
+                hit = p.test(f);
+                this.debug('pattern match', p, f, hit);
+            }
+            if (!hit)
+                return false;
+        }
+        // Note: ending in / means that we'll get a final ""
+        // at the end of the pattern.  This can only match a
+        // corresponding "" at the end of the file.
+        // If the file ends in /, then it can only match a
+        // a pattern that ends in /, unless the pattern just
+        // doesn't have any more for it. But, a/b/ should *not*
+        // match "a/b/*", even though "" matches against the
+        // [^/]*? pattern, except in partial mode, where it might
+        // simply not be reached yet.
+        // However, a/b/ should still satisfy a/*
+        // now either we fell off the end of the pattern, or we're done.
+        if (fi === fl && pi === pl) {
+            // ran out of pattern and filename at the same time.
+            // an exact hit!
+            return true;
+        }
+        else if (fi === fl) {
+            // ran out of file, but still had pattern left.
+            // this is ok if we're doing the match as part of
+            // a glob fs traversal.
+            return partial;
+        }
+        else if (pi === pl) {
+            // ran out of pattern, still have file left.
+            // this is only acceptable if we're on the very last
+            // empty segment of a file with a trailing slash.
+            // a/* should match a/b/
+            return fi === fl - 1 && file[fi] === '';
+            /* c8 ignore start */
+        }
+        else {
+            // should be unreachable.
+            throw new Error('wtf?');
+        }
+        /* c8 ignore stop */
+    }
+    braceExpand() {
+        return (0, exports.braceExpand)(this.pattern, this.options);
+    }
+    parse(pattern) {
+        (0, assert_valid_pattern_js_1.assertValidPattern)(pattern);
+        const options = this.options;
+        // shortcuts
+        if (pattern === '**')
+            return exports.GLOBSTAR;
+        if (pattern === '')
+            return '';
+        // far and away, the most common glob pattern parts are
+        // *, *.*, and *.  Add a fast check method for those.
+        let m;
+        let fastTest = null;
+        if ((m = pattern.match(starRE))) {
+            fastTest = options.dot ? starTestDot : starTest;
+        }
+        else if ((m = pattern.match(starDotExtRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? starDotExtTestNocaseDot
+                    : starDotExtTestNocase
+                : options.dot
+                    ? starDotExtTestDot
+                    : starDotExtTest)(m[1]);
+        }
+        else if ((m = pattern.match(qmarksRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? qmarksTestNocaseDot
+                    : qmarksTestNocase
+                : options.dot
+                    ? qmarksTestDot
+                    : qmarksTest)(m);
+        }
+        else if ((m = pattern.match(starDotStarRE))) {
+            fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
+        }
+        else if ((m = pattern.match(dotStarRE))) {
+            fastTest = dotStarTest;
+        }
+        const re = ast_js_1.AST.fromGlob(pattern, this.options).toMMPattern();
+        if (fastTest && typeof re === 'object') {
+            // Avoids overriding in frozen environments
+            Reflect.defineProperty(re, 'test', { value: fastTest });
+        }
+        return re;
+    }
+    makeRe() {
+        if (this.regexp || this.regexp === false)
+            return this.regexp;
+        // at this point, this.set is a 2d array of partial
+        // pattern strings, or "**".
+        //
+        // It's better to use .match().  This function shouldn't
+        // be used, really, but it's pretty convenient sometimes,
+        // when you just want to work with a regex.
+        const set = this.set;
+        if (!set.length) {
+            this.regexp = false;
+            return this.regexp;
+        }
+        const options = this.options;
+        const twoStar = options.noglobstar
+            ? star
+            : options.dot
+                ? twoStarDot
+                : twoStarNoDot;
+        const flags = new Set(options.nocase ? ['i'] : []);
+        // regexpify non-globstar patterns
+        // if ** is only item, then we just do one twoStar
+        // if ** is first, and there are more, prepend (\/|twoStar\/)? to next
+        // if ** is last, append (\/twoStar|) to previous
+        // if ** is in the middle, append (\/|\/twoStar\/) to previous
+        // then filter out GLOBSTAR symbols
+        let re = set
+            .map(pattern => {
+            const pp = pattern.map(p => {
+                if (p instanceof RegExp) {
+                    for (const f of p.flags.split(''))
+                        flags.add(f);
+                }
+                return typeof p === 'string'
+                    ? regExpEscape(p)
+                    : p === exports.GLOBSTAR
+                        ? exports.GLOBSTAR
+                        : p._src;
+            });
+            pp.forEach((p, i) => {
+                const next = pp[i + 1];
+                const prev = pp[i - 1];
+                if (p !== exports.GLOBSTAR || prev === exports.GLOBSTAR) {
+                    return;
+                }
+                if (prev === undefined) {
+                    if (next !== undefined && next !== exports.GLOBSTAR) {
+                        pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next;
+                    }
+                    else {
+                        pp[i] = twoStar;
+                    }
+                }
+                else if (next === undefined) {
+                    pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
+                }
+                else if (next !== exports.GLOBSTAR) {
+                    pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
+                    pp[i + 1] = exports.GLOBSTAR;
+                }
+            });
+            return pp.filter(p => p !== exports.GLOBSTAR).join('/');
+        })
+            .join('|');
+        // need to wrap in parens if we had more than one thing with |,
+        // otherwise only the first will be anchored to ^ and the last to $
+        const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
+        // must match entire pattern
+        // ending in a * or ** will make it less strict.
+        re = '^' + open + re + close + '$';
+        // can match anything, as long as it's not this.
+        if (this.negate)
+            re = '^(?!' + re + ').+$';
+        try {
+            this.regexp = new RegExp(re, [...flags].join(''));
+            /* c8 ignore start */
+        }
+        catch (ex) {
+            // should be impossible
+            this.regexp = false;
+        }
+        /* c8 ignore stop */
+        return this.regexp;
+    }
+    slashSplit(p) {
+        // if p starts with // on windows, we preserve that
+        // so that UNC paths aren't broken.  Otherwise, any number of
+        // / characters are coalesced into one, unless
+        // preserveMultipleSlashes is set to true.
+        if (this.preserveMultipleSlashes) {
+            return p.split('/');
+        }
+        else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
+            // add an extra '' for the one we lose
+            return ['', ...p.split(/\/+/)];
+        }
+        else {
+            return p.split(/\/+/);
+        }
+    }
+    match(f, partial = this.partial) {
+        this.debug('match', f, this.pattern);
+        // short-circuit in the case of busted things.
+        // comments, etc.
+        if (this.comment) {
+            return false;
+        }
+        if (this.empty) {
+            return f === '';
+        }
+        if (f === '/' && partial) {
+            return true;
+        }
+        const options = this.options;
+        // windows: need to use /, not \
+        if (this.isWindows) {
+            f = f.split('\\').join('/');
+        }
+        // treat the test path as a set of pathparts.
+        const ff = this.slashSplit(f);
+        this.debug(this.pattern, 'split', ff);
+        // just ONE of the pattern sets in this.set needs to match
+        // in order for it to be valid.  If negating, then just one
+        // match means that we have failed.
+        // Either way, return on the first hit.
+        const set = this.set;
+        this.debug(this.pattern, 'set', set);
+        // Find the basename of the path by looking for the last non-empty segment
+        let filename = ff[ff.length - 1];
+        if (!filename) {
+            for (let i = ff.length - 2; !filename && i >= 0; i--) {
+                filename = ff[i];
+            }
+        }
+        for (let i = 0; i < set.length; i++) {
+            const pattern = set[i];
+            let file = ff;
+            if (options.matchBase && pattern.length === 1) {
+                file = [filename];
+            }
+            const hit = this.matchOne(file, pattern, partial);
+            if (hit) {
+                if (options.flipNegate) {
+                    return true;
+                }
+                return !this.negate;
+            }
+        }
+        // didn't get any hits.  this is success if it's a negative
+        // pattern, failure otherwise.
+        if (options.flipNegate) {
+            return false;
+        }
+        return this.negate;
+    }
+    static defaults(def) {
+        return exports.minimatch.defaults(def).Minimatch;
+    }
+}
+exports.Minimatch = Minimatch;
+/* c8 ignore start */
+var ast_js_2 = require("./ast.js");
+Object.defineProperty(exports, "AST", { enumerable: true, get: function () { return ast_js_2.AST; } });
+var escape_js_2 = require("./escape.js");
+Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return escape_js_2.escape; } });
+var unescape_js_2 = require("./unescape.js");
+Object.defineProperty(exports, "unescape", { enumerable: true, get: function () { return unescape_js_2.unescape; } });
+/* c8 ignore stop */
+exports.minimatch.AST = ast_js_1.AST;
+exports.minimatch.Minimatch = Minimatch;
+exports.minimatch.escape = escape_js_1.escape;
+exports.minimatch.unescape = unescape_js_1.unescape;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/index.js.map b/backend/node_modules/minimatch/dist/commonjs/index.js.map
new file mode 100644
index 00000000..d4f6a870
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/commonjs/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import expand from 'brace-expansion'\nimport { assertValidPattern } from './assert-valid-pattern.js'\nimport { AST, ExtglobType } from './ast.js'\nimport { escape } from './escape.js'\nimport { unescape } from './unescape.js'\n\ntype Platform =\n  | 'aix'\n  | 'android'\n  | 'darwin'\n  | 'freebsd'\n  | 'haiku'\n  | 'linux'\n  | 'openbsd'\n  | 'sunos'\n  | 'win32'\n  | 'cygwin'\n  | 'netbsd'\n\nexport interface MinimatchOptions {\n  nobrace?: boolean\n  nocomment?: boolean\n  nonegate?: boolean\n  debug?: boolean\n  noglobstar?: boolean\n  noext?: boolean\n  nonull?: boolean\n  windowsPathsNoEscape?: boolean\n  allowWindowsEscape?: boolean\n  partial?: boolean\n  dot?: boolean\n  nocase?: boolean\n  nocaseMagicOnly?: boolean\n  magicalBraces?: boolean\n  matchBase?: boolean\n  flipNegate?: boolean\n  preserveMultipleSlashes?: boolean\n  optimizationLevel?: number\n  platform?: Platform\n  windowsNoMagicRoot?: boolean\n}\n\nexport const minimatch = (\n  p: string,\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // shortcut: comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    return false\n  }\n\n  return new Minimatch(pattern, options).match(p)\n}\n\n// Optimized checking for the most common glob patterns.\nconst starDotExtRE = /^\\*+([^+@!?\\*\\[\\(]*)$/\nconst starDotExtTest = (ext: string) => (f: string) =>\n  !f.startsWith('.') && f.endsWith(ext)\nconst starDotExtTestDot = (ext: string) => (f: string) => f.endsWith(ext)\nconst starDotExtTestNocase = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => !f.startsWith('.') && f.toLowerCase().endsWith(ext)\n}\nconst starDotExtTestNocaseDot = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => f.toLowerCase().endsWith(ext)\n}\nconst starDotStarRE = /^\\*+\\.\\*+$/\nconst starDotStarTest = (f: string) => !f.startsWith('.') && f.includes('.')\nconst starDotStarTestDot = (f: string) =>\n  f !== '.' && f !== '..' && f.includes('.')\nconst dotStarRE = /^\\.\\*+$/\nconst dotStarTest = (f: string) => f !== '.' && f !== '..' && f.startsWith('.')\nconst starRE = /^\\*+$/\nconst starTest = (f: string) => f.length !== 0 && !f.startsWith('.')\nconst starTestDot = (f: string) => f.length !== 0 && f !== '.' && f !== '..'\nconst qmarksRE = /^\\?+([^+@!?\\*\\[\\(]*)?$/\nconst qmarksTestNocase = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestNocaseDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTest = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTestNoExt = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && !f.startsWith('.')\n}\nconst qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && f !== '.' && f !== '..'\n}\n\n/* c8 ignore start */\nconst defaultPlatform: Platform = (\n  typeof process === 'object' && process\n    ? (typeof process.env === 'object' &&\n        process.env &&\n        process.env.__MINIMATCH_TESTING_PLATFORM__) ||\n      process.platform\n    : 'posix'\n) as Platform\ntype Sep = '\\\\' | '/'\nconst path: { [k: string]: { sep: Sep } } = {\n  win32: { sep: '\\\\' },\n  posix: { sep: '/' },\n}\n/* c8 ignore stop */\n\nexport const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep\nminimatch.sep = sep\n\nexport const GLOBSTAR = Symbol('globstar **')\nminimatch.GLOBSTAR = GLOBSTAR\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n\n// ** when dots are allowed.  Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nconst twoStarDot = '(?:(?!(?:\\\\/|^)(?:\\\\.{1,2})($|\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nconst twoStarNoDot = '(?:(?!(?:\\\\/|^)\\\\.).)*?'\n\nexport const filter =\n  (pattern: string, options: MinimatchOptions = {}) =>\n  (p: string) =>\n    minimatch(p, pattern, options)\nminimatch.filter = filter\n\nconst ext = (a: MinimatchOptions, b: MinimatchOptions = {}) =>\n  Object.assign({}, a, b)\n\nexport const defaults = (def: MinimatchOptions): typeof minimatch => {\n  if (!def || typeof def !== 'object' || !Object.keys(def).length) {\n    return minimatch\n  }\n\n  const orig = minimatch\n\n  const m = (p: string, pattern: string, options: MinimatchOptions = {}) =>\n    orig(p, pattern, ext(def, options))\n\n  return Object.assign(m, {\n    Minimatch: class Minimatch extends orig.Minimatch {\n      constructor(pattern: string, options: MinimatchOptions = {}) {\n        super(pattern, ext(def, options))\n      }\n      static defaults(options: MinimatchOptions) {\n        return orig.defaults(ext(def, options)).Minimatch\n      }\n    },\n\n    AST: class AST extends orig.AST {\n      /* c8 ignore start */\n      constructor(\n        type: ExtglobType | null,\n        parent?: AST,\n        options: MinimatchOptions = {}\n      ) {\n        super(type, parent, ext(def, options))\n      }\n      /* c8 ignore stop */\n\n      static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n        return orig.AST.fromGlob(pattern, ext(def, options))\n      }\n    },\n\n    unescape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.unescape(s, ext(def, options)),\n\n    escape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.escape(s, ext(def, options)),\n\n    filter: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.filter(pattern, ext(def, options)),\n\n    defaults: (options: MinimatchOptions) => orig.defaults(ext(def, options)),\n\n    makeRe: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.makeRe(pattern, ext(def, options)),\n\n    braceExpand: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.braceExpand(pattern, ext(def, options)),\n\n    match: (list: string[], pattern: string, options: MinimatchOptions = {}) =>\n      orig.match(list, pattern, ext(def, options)),\n\n    sep: orig.sep,\n    GLOBSTAR: GLOBSTAR as typeof GLOBSTAR,\n  })\n}\nminimatch.defaults = defaults\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nexport const braceExpand = (\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // Thanks to Yeting Li  for\n  // improving this regexp to avoid a ReDOS vulnerability.\n  if (options.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(pattern)) {\n    // shortcut. no need to expand.\n    return [pattern]\n  }\n\n  return expand(pattern)\n}\nminimatch.braceExpand = braceExpand\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion.  Otherwise, any series\n// of * is equivalent to a single *.  Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\n\nexport const makeRe = (pattern: string, options: MinimatchOptions = {}) =>\n  new Minimatch(pattern, options).makeRe()\nminimatch.makeRe = makeRe\n\nexport const match = (\n  list: string[],\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  const mm = new Minimatch(pattern, options)\n  list = list.filter(f => mm.match(f))\n  if (mm.options.nonull && !list.length) {\n    list.push(pattern)\n  }\n  return list\n}\nminimatch.match = match\n\n// replace stuff like \\* with *\nconst globMagic = /[?*]|[+@!]\\(.*?\\)|\\[|\\]/\nconst regExpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\nexport type MMRegExp = RegExp & {\n  _src?: string\n  _glob?: string\n}\n\nexport type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR\nexport type ParseReturn = ParseReturnFiltered | false\n\nexport class Minimatch {\n  options: MinimatchOptions\n  set: ParseReturnFiltered[][]\n  pattern: string\n\n  windowsPathsNoEscape: boolean\n  nonegate: boolean\n  negate: boolean\n  comment: boolean\n  empty: boolean\n  preserveMultipleSlashes: boolean\n  partial: boolean\n  globSet: string[]\n  globParts: string[][]\n  nocase: boolean\n\n  isWindows: boolean\n  platform: Platform\n  windowsNoMagicRoot: boolean\n\n  regexp: false | null | MMRegExp\n  constructor(pattern: string, options: MinimatchOptions = {}) {\n    assertValidPattern(pattern)\n\n    options = options || {}\n    this.options = options\n    this.pattern = pattern\n    this.platform = options.platform || defaultPlatform\n    this.isWindows = this.platform === 'win32'\n    this.windowsPathsNoEscape =\n      !!options.windowsPathsNoEscape || options.allowWindowsEscape === false\n    if (this.windowsPathsNoEscape) {\n      this.pattern = this.pattern.replace(/\\\\/g, '/')\n    }\n    this.preserveMultipleSlashes = !!options.preserveMultipleSlashes\n    this.regexp = null\n    this.negate = false\n    this.nonegate = !!options.nonegate\n    this.comment = false\n    this.empty = false\n    this.partial = !!options.partial\n    this.nocase = !!this.options.nocase\n    this.windowsNoMagicRoot =\n      options.windowsNoMagicRoot !== undefined\n        ? options.windowsNoMagicRoot\n        : !!(this.isWindows && this.nocase)\n\n    this.globSet = []\n    this.globParts = []\n    this.set = []\n\n    // make the set of regexps etc.\n    this.make()\n  }\n\n  hasMagic(): boolean {\n    if (this.options.magicalBraces && this.set.length > 1) {\n      return true\n    }\n    for (const pattern of this.set) {\n      for (const part of pattern) {\n        if (typeof part !== 'string') return true\n      }\n    }\n    return false\n  }\n\n  debug(..._: any[]) {}\n\n  make() {\n    const pattern = this.pattern\n    const options = this.options\n\n    // empty patterns and comments match nothing.\n    if (!options.nocomment && pattern.charAt(0) === '#') {\n      this.comment = true\n      return\n    }\n\n    if (!pattern) {\n      this.empty = true\n      return\n    }\n\n    // step 1: figure out negation, etc.\n    this.parseNegate()\n\n    // step 2: expand braces\n    this.globSet = [...new Set(this.braceExpand())]\n\n    if (options.debug) {\n      this.debug = (...args: any[]) => console.error(...args)\n    }\n\n    this.debug(this.pattern, this.globSet)\n\n    // step 3: now we have a set, so turn each one into a series of\n    // path-portion matching patterns.\n    // These will be regexps, except in the case of \"**\", which is\n    // set to the GLOBSTAR object for globstar behavior,\n    // and will not contain any / characters\n    //\n    // First, we preprocess to make the glob pattern sets a bit simpler\n    // and deduped.  There are some perf-killing patterns that can cause\n    // problems with a glob walk, but we can simplify them down a bit.\n    const rawGlobParts = this.globSet.map(s => this.slashSplit(s))\n    this.globParts = this.preprocess(rawGlobParts)\n    this.debug(this.pattern, this.globParts)\n\n    // glob --> regexps\n    let set = this.globParts.map((s, _, __) => {\n      if (this.isWindows && this.windowsNoMagicRoot) {\n        // check if it's a drive or unc path.\n        const isUNC =\n          s[0] === '' &&\n          s[1] === '' &&\n          (s[2] === '?' || !globMagic.test(s[2])) &&\n          !globMagic.test(s[3])\n        const isDrive = /^[a-z]:/i.test(s[0])\n        if (isUNC) {\n          return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]\n        } else if (isDrive) {\n          return [s[0], ...s.slice(1).map(ss => this.parse(ss))]\n        }\n      }\n      return s.map(ss => this.parse(ss))\n    })\n\n    this.debug(this.pattern, set)\n\n    // filter out everything that didn't compile properly.\n    this.set = set.filter(\n      s => s.indexOf(false) === -1\n    ) as ParseReturnFiltered[][]\n\n    // do not treat the ? in UNC paths as magic\n    if (this.isWindows) {\n      for (let i = 0; i < this.set.length; i++) {\n        const p = this.set[i]\n        if (\n          p[0] === '' &&\n          p[1] === '' &&\n          this.globParts[i][2] === '?' &&\n          typeof p[3] === 'string' &&\n          /^[a-z]:$/i.test(p[3])\n        ) {\n          p[2] = '?'\n        }\n      }\n    }\n\n    this.debug(this.pattern, this.set)\n  }\n\n  // various transforms to equivalent pattern sets that are\n  // faster to process in a filesystem walk.  The goal is to\n  // eliminate what we can, and push all ** patterns as far\n  // to the right as possible, even if it increases the number\n  // of patterns that we have to process.\n  preprocess(globParts: string[][]) {\n    // if we're not in globstar mode, then turn all ** into *\n    if (this.options.noglobstar) {\n      for (let i = 0; i < globParts.length; i++) {\n        for (let j = 0; j < globParts[i].length; j++) {\n          if (globParts[i][j] === '**') {\n            globParts[i][j] = '*'\n          }\n        }\n      }\n    }\n\n    const { optimizationLevel = 1 } = this.options\n\n    if (optimizationLevel >= 2) {\n      // aggressive optimization for the purpose of fs walking\n      globParts = this.firstPhasePreProcess(globParts)\n      globParts = this.secondPhasePreProcess(globParts)\n    } else if (optimizationLevel >= 1) {\n      // just basic optimizations to remove some .. parts\n      globParts = this.levelOneOptimize(globParts)\n    } else {\n      // just collapse multiple ** portions into one\n      globParts = this.adjascentGlobstarOptimize(globParts)\n    }\n\n    return globParts\n  }\n\n  // just get rid of adjascent ** portions\n  adjascentGlobstarOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      let gs: number = -1\n      while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n        let i = gs\n        while (parts[i + 1] === '**') {\n          i++\n        }\n        if (i !== gs) {\n          parts.splice(gs, i - gs)\n        }\n      }\n      return parts\n    })\n  }\n\n  // get rid of adjascent ** and resolve .. portions\n  levelOneOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      parts = parts.reduce((set: string[], part) => {\n        const prev = set[set.length - 1]\n        if (part === '**' && prev === '**') {\n          return set\n        }\n        if (part === '..') {\n          if (prev && prev !== '..' && prev !== '.' && prev !== '**') {\n            set.pop()\n            return set\n          }\n        }\n        set.push(part)\n        return set\n      }, [])\n      return parts.length === 0 ? [''] : parts\n    })\n  }\n\n  levelTwoFileOptimize(parts: string | string[]) {\n    if (!Array.isArray(parts)) {\n      parts = this.slashSplit(parts)\n    }\n    let didSomething: boolean = false\n    do {\n      didSomething = false\n      // 
// -> 
/\n      if (!this.preserveMultipleSlashes) {\n        for (let i = 1; i < parts.length - 1; i++) {\n          const p = parts[i]\n          // don't squeeze out UNC patterns\n          if (i === 1 && p === '' && parts[0] === '') continue\n          if (p === '.' || p === '') {\n            didSomething = true\n            parts.splice(i, 1)\n            i--\n          }\n        }\n        if (\n          parts[0] === '.' &&\n          parts.length === 2 &&\n          (parts[1] === '.' || parts[1] === '')\n        ) {\n          didSomething = true\n          parts.pop()\n        }\n      }\n\n      // 
/

/../ ->

/\n      let dd: number = 0\n      while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n        const p = parts[dd - 1]\n        if (p && p !== '.' && p !== '..' && p !== '**') {\n          didSomething = true\n          parts.splice(dd - 1, 2)\n          dd -= 2\n        }\n      }\n    } while (didSomething)\n    return parts.length === 0 ? [''] : parts\n  }\n\n  // First phase: single-pattern processing\n  // 
 is 1 or more portions\n  //  is 1 or more portions\n  // 

is any portion other than ., .., '', or **\n // is . or ''\n //\n // **/.. is *brutal* for filesystem walking performance, because\n // it effectively resets the recursive walk each time it occurs,\n // and ** cannot be reduced out by a .. pattern part like a regexp\n // or most strings (other than .., ., and '') can be.\n //\n //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n //

// -> 
/\n  // 
/

/../ ->

/\n  // **/**/ -> **/\n  //\n  // **/*/ -> */**/ <== not valid because ** doesn't follow\n  // this WOULD be allowed if ** did follow symlinks, or * didn't\n  firstPhasePreProcess(globParts: string[][]) {\n    let didSomething = false\n    do {\n      didSomething = false\n      // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n for (let parts of globParts) {\n let gs: number = -1\n while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n let gss: number = gs\n while (parts[gss + 1] === '**') {\n //

/**/**/ -> 
/**/\n            gss++\n          }\n          // eg, if gs is 2 and gss is 4, that means we have 3 **\n          // parts, and can remove 2 of them.\n          if (gss > gs) {\n            parts.splice(gs + 1, gss - gs)\n          }\n\n          let next = parts[gs + 1]\n          const p = parts[gs + 2]\n          const p2 = parts[gs + 3]\n          if (next !== '..') continue\n          if (\n            !p ||\n            p === '.' ||\n            p === '..' ||\n            !p2 ||\n            p2 === '.' ||\n            p2 === '..'\n          ) {\n            continue\n          }\n          didSomething = true\n          // edit parts in place, and push the new one\n          parts.splice(gs, 1)\n          const other = parts.slice(0)\n          other[gs] = '**'\n          globParts.push(other)\n          gs--\n        }\n\n        // 
// -> 
/\n        if (!this.preserveMultipleSlashes) {\n          for (let i = 1; i < parts.length - 1; i++) {\n            const p = parts[i]\n            // don't squeeze out UNC patterns\n            if (i === 1 && p === '' && parts[0] === '') continue\n            if (p === '.' || p === '') {\n              didSomething = true\n              parts.splice(i, 1)\n              i--\n            }\n          }\n          if (\n            parts[0] === '.' &&\n            parts.length === 2 &&\n            (parts[1] === '.' || parts[1] === '')\n          ) {\n            didSomething = true\n            parts.pop()\n          }\n        }\n\n        // 
/

/../ ->

/\n        let dd: number = 0\n        while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n          const p = parts[dd - 1]\n          if (p && p !== '.' && p !== '..' && p !== '**') {\n            didSomething = true\n            const needDot = dd === 1 && parts[dd + 1] === '**'\n            const splin = needDot ? ['.'] : []\n            parts.splice(dd - 1, 2, ...splin)\n            if (parts.length === 0) parts.push('')\n            dd -= 2\n          }\n        }\n      }\n    } while (didSomething)\n\n    return globParts\n  }\n\n  // second phase: multi-pattern dedupes\n  // {
/*/,
/

/} ->

/*/\n  // {
/,
/} -> 
/\n  // {
/**/,
/} -> 
/**/\n  //\n  // {
/**/,
/**/

/} ->

/**/\n  // ^-- not valid because ** doens't follow symlinks\n  secondPhasePreProcess(globParts: string[][]): string[][] {\n    for (let i = 0; i < globParts.length - 1; i++) {\n      for (let j = i + 1; j < globParts.length; j++) {\n        const matched = this.partsMatch(\n          globParts[i],\n          globParts[j],\n          !this.preserveMultipleSlashes\n        )\n        if (matched) {\n          globParts[i] = []\n          globParts[j] = matched\n          break\n        }\n      }\n    }\n    return globParts.filter(gs => gs.length)\n  }\n\n  partsMatch(\n    a: string[],\n    b: string[],\n    emptyGSMatch: boolean = false\n  ): false | string[] {\n    let ai = 0\n    let bi = 0\n    let result: string[] = []\n    let which: string = ''\n    while (ai < a.length && bi < b.length) {\n      if (a[ai] === b[bi]) {\n        result.push(which === 'b' ? b[bi] : a[ai])\n        ai++\n        bi++\n      } else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {\n        result.push(a[ai])\n        ai++\n      } else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {\n        result.push(b[bi])\n        bi++\n      } else if (\n        a[ai] === '*' &&\n        b[bi] &&\n        (this.options.dot || !b[bi].startsWith('.')) &&\n        b[bi] !== '**'\n      ) {\n        if (which === 'b') return false\n        which = 'a'\n        result.push(a[ai])\n        ai++\n        bi++\n      } else if (\n        b[bi] === '*' &&\n        a[ai] &&\n        (this.options.dot || !a[ai].startsWith('.')) &&\n        a[ai] !== '**'\n      ) {\n        if (which === 'a') return false\n        which = 'b'\n        result.push(b[bi])\n        ai++\n        bi++\n      } else {\n        return false\n      }\n    }\n    // if we fall out of the loop, it means they two are identical\n    // as long as their lengths match\n    return a.length === b.length && result\n  }\n\n  parseNegate() {\n    if (this.nonegate) return\n\n    const pattern = this.pattern\n    let negate = false\n    let negateOffset = 0\n\n    for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {\n      negate = !negate\n      negateOffset++\n    }\n\n    if (negateOffset) this.pattern = pattern.slice(negateOffset)\n    this.negate = negate\n  }\n\n  // set partial to true to test if, for example,\n  // \"/a/b\" matches the start of \"/*/b/*/d\"\n  // Partial means, if you run out of file before you run\n  // out of pattern, then that's fine, as long as all\n  // the parts match.\n  matchOne(file: string[], pattern: ParseReturn[], partial: boolean = false) {\n    const options = this.options\n\n    // UNC paths like //?/X:/... can match X:/... and vice versa\n    // Drive letters in absolute drive or unc paths are always compared\n    // case-insensitively.\n    if (this.isWindows) {\n      const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0])\n      const fileUNC =\n        !fileDrive &&\n        file[0] === '' &&\n        file[1] === '' &&\n        file[2] === '?' &&\n        /^[a-z]:$/i.test(file[3])\n\n      const patternDrive =\n        typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0])\n      const patternUNC =\n        !patternDrive &&\n        pattern[0] === '' &&\n        pattern[1] === '' &&\n        pattern[2] === '?' &&\n        typeof pattern[3] === 'string' &&\n        /^[a-z]:$/i.test(pattern[3])\n\n      const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined\n      const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined\n      if (typeof fdi === 'number' && typeof pdi === 'number') {\n        const [fd, pd]: [string, string] = [file[fdi], pattern[pdi] as string]\n        if (fd.toLowerCase() === pd.toLowerCase()) {\n          pattern[pdi] = fd\n          if (pdi > fdi) {\n            pattern = pattern.slice(pdi)\n          } else if (fdi > pdi) {\n            file = file.slice(fdi)\n          }\n        }\n      }\n    }\n\n    // resolve and reduce . and .. portions in the file as well.\n    // dont' need to do the second phase, because it's only one string[]\n    const { optimizationLevel = 1 } = this.options\n    if (optimizationLevel >= 2) {\n      file = this.levelTwoFileOptimize(file)\n    }\n\n    this.debug('matchOne', this, { file, pattern })\n    this.debug('matchOne', file.length, pattern.length)\n\n    for (\n      var fi = 0, pi = 0, fl = file.length, pl = pattern.length;\n      fi < fl && pi < pl;\n      fi++, pi++\n    ) {\n      this.debug('matchOne loop')\n      var p = pattern[pi]\n      var f = file[fi]\n\n      this.debug(pattern, p, f)\n\n      // should be impossible.\n      // some invalid regexp stuff in the set.\n      /* c8 ignore start */\n      if (p === false) {\n        return false\n      }\n      /* c8 ignore stop */\n\n      if (p === GLOBSTAR) {\n        this.debug('GLOBSTAR', [pattern, p, f])\n\n        // \"**\"\n        // a/**/b/**/c would match the following:\n        // a/b/x/y/z/c\n        // a/x/y/z/b/c\n        // a/b/x/b/x/c\n        // a/b/c\n        // To do this, take the rest of the pattern after\n        // the **, and see if it would match the file remainder.\n        // If so, return success.\n        // If not, the ** \"swallows\" a segment, and try again.\n        // This is recursively awful.\n        //\n        // a/**/b/**/c matching a/b/x/y/z/c\n        // - a matches a\n        // - doublestar\n        //   - matchOne(b/x/y/z/c, b/**/c)\n        //     - b matches b\n        //     - doublestar\n        //       - matchOne(x/y/z/c, c) -> no\n        //       - matchOne(y/z/c, c) -> no\n        //       - matchOne(z/c, c) -> no\n        //       - matchOne(c, c) yes, hit\n        var fr = fi\n        var pr = pi + 1\n        if (pr === pl) {\n          this.debug('** at the end')\n          // a ** at the end will just swallow the rest.\n          // We have found a match.\n          // however, it will not swallow /.x, unless\n          // options.dot is set.\n          // . and .. are *never* matched by **, for explosively\n          // exponential reasons.\n          for (; fi < fl; fi++) {\n            if (\n              file[fi] === '.' ||\n              file[fi] === '..' ||\n              (!options.dot && file[fi].charAt(0) === '.')\n            )\n              return false\n          }\n          return true\n        }\n\n        // ok, let's see if we can swallow whatever we can.\n        while (fr < fl) {\n          var swallowee = file[fr]\n\n          this.debug('\\nglobstar while', file, fr, pattern, pr, swallowee)\n\n          // XXX remove this slice.  Just pass the start index.\n          if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {\n            this.debug('globstar found match!', fr, fl, swallowee)\n            // found a match.\n            return true\n          } else {\n            // can't swallow \".\" or \"..\" ever.\n            // can only swallow \".foo\" when explicitly asked.\n            if (\n              swallowee === '.' ||\n              swallowee === '..' ||\n              (!options.dot && swallowee.charAt(0) === '.')\n            ) {\n              this.debug('dot detected!', file, fr, pattern, pr)\n              break\n            }\n\n            // ** swallows a segment, and continue.\n            this.debug('globstar swallow a segment, and continue')\n            fr++\n          }\n        }\n\n        // no match was found.\n        // However, in partial mode, we can't say this is necessarily over.\n        /* c8 ignore start */\n        if (partial) {\n          // ran out of file\n          this.debug('\\n>>> no match, partial?', file, fr, pattern, pr)\n          if (fr === fl) {\n            return true\n          }\n        }\n        /* c8 ignore stop */\n        return false\n      }\n\n      // something other than **\n      // non-magic patterns just have to match exactly\n      // patterns with magic have been turned into regexps.\n      let hit: boolean\n      if (typeof p === 'string') {\n        hit = f === p\n        this.debug('string match', p, f, hit)\n      } else {\n        hit = p.test(f)\n        this.debug('pattern match', p, f, hit)\n      }\n\n      if (!hit) return false\n    }\n\n    // Note: ending in / means that we'll get a final \"\"\n    // at the end of the pattern.  This can only match a\n    // corresponding \"\" at the end of the file.\n    // If the file ends in /, then it can only match a\n    // a pattern that ends in /, unless the pattern just\n    // doesn't have any more for it. But, a/b/ should *not*\n    // match \"a/b/*\", even though \"\" matches against the\n    // [^/]*? pattern, except in partial mode, where it might\n    // simply not be reached yet.\n    // However, a/b/ should still satisfy a/*\n\n    // now either we fell off the end of the pattern, or we're done.\n    if (fi === fl && pi === pl) {\n      // ran out of pattern and filename at the same time.\n      // an exact hit!\n      return true\n    } else if (fi === fl) {\n      // ran out of file, but still had pattern left.\n      // this is ok if we're doing the match as part of\n      // a glob fs traversal.\n      return partial\n    } else if (pi === pl) {\n      // ran out of pattern, still have file left.\n      // this is only acceptable if we're on the very last\n      // empty segment of a file with a trailing slash.\n      // a/* should match a/b/\n      return fi === fl - 1 && file[fi] === ''\n\n      /* c8 ignore start */\n    } else {\n      // should be unreachable.\n      throw new Error('wtf?')\n    }\n    /* c8 ignore stop */\n  }\n\n  braceExpand() {\n    return braceExpand(this.pattern, this.options)\n  }\n\n  parse(pattern: string): ParseReturn {\n    assertValidPattern(pattern)\n\n    const options = this.options\n\n    // shortcuts\n    if (pattern === '**') return GLOBSTAR\n    if (pattern === '') return ''\n\n    // far and away, the most common glob pattern parts are\n    // *, *.*, and *.  Add a fast check method for those.\n    let m: RegExpMatchArray | null\n    let fastTest: null | ((f: string) => boolean) = null\n    if ((m = pattern.match(starRE))) {\n      fastTest = options.dot ? starTestDot : starTest\n    } else if ((m = pattern.match(starDotExtRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? starDotExtTestNocaseDot\n            : starDotExtTestNocase\n          : options.dot\n          ? starDotExtTestDot\n          : starDotExtTest\n      )(m[1])\n    } else if ((m = pattern.match(qmarksRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? qmarksTestNocaseDot\n            : qmarksTestNocase\n          : options.dot\n          ? qmarksTestDot\n          : qmarksTest\n      )(m)\n    } else if ((m = pattern.match(starDotStarRE))) {\n      fastTest = options.dot ? starDotStarTestDot : starDotStarTest\n    } else if ((m = pattern.match(dotStarRE))) {\n      fastTest = dotStarTest\n    }\n\n    const re = AST.fromGlob(pattern, this.options).toMMPattern()\n    if (fastTest && typeof re === 'object') {\n      // Avoids overriding in frozen environments\n      Reflect.defineProperty(re, 'test', { value: fastTest })\n    }\n    return re\n  }\n\n  makeRe() {\n    if (this.regexp || this.regexp === false) return this.regexp\n\n    // at this point, this.set is a 2d array of partial\n    // pattern strings, or \"**\".\n    //\n    // It's better to use .match().  This function shouldn't\n    // be used, really, but it's pretty convenient sometimes,\n    // when you just want to work with a regex.\n    const set = this.set\n\n    if (!set.length) {\n      this.regexp = false\n      return this.regexp\n    }\n    const options = this.options\n\n    const twoStar = options.noglobstar\n      ? star\n      : options.dot\n      ? twoStarDot\n      : twoStarNoDot\n    const flags = new Set(options.nocase ? ['i'] : [])\n\n    // regexpify non-globstar patterns\n    // if ** is only item, then we just do one twoStar\n    // if ** is first, and there are more, prepend (\\/|twoStar\\/)? to next\n    // if ** is last, append (\\/twoStar|) to previous\n    // if ** is in the middle, append (\\/|\\/twoStar\\/) to previous\n    // then filter out GLOBSTAR symbols\n    let re = set\n      .map(pattern => {\n        const pp: (string | typeof GLOBSTAR)[] = pattern.map(p => {\n          if (p instanceof RegExp) {\n            for (const f of p.flags.split('')) flags.add(f)\n          }\n          return typeof p === 'string'\n            ? regExpEscape(p)\n            : p === GLOBSTAR\n            ? GLOBSTAR\n            : p._src\n        }) as (string | typeof GLOBSTAR)[]\n        pp.forEach((p, i) => {\n          const next = pp[i + 1]\n          const prev = pp[i - 1]\n          if (p !== GLOBSTAR || prev === GLOBSTAR) {\n            return\n          }\n          if (prev === undefined) {\n            if (next !== undefined && next !== GLOBSTAR) {\n              pp[i + 1] = '(?:\\\\/|' + twoStar + '\\\\/)?' + next\n            } else {\n              pp[i] = twoStar\n            }\n          } else if (next === undefined) {\n            pp[i - 1] = prev + '(?:\\\\/|' + twoStar + ')?'\n          } else if (next !== GLOBSTAR) {\n            pp[i - 1] = prev + '(?:\\\\/|\\\\/' + twoStar + '\\\\/)' + next\n            pp[i + 1] = GLOBSTAR\n          }\n        })\n        return pp.filter(p => p !== GLOBSTAR).join('/')\n      })\n      .join('|')\n\n    // need to wrap in parens if we had more than one thing with |,\n    // otherwise only the first will be anchored to ^ and the last to $\n    const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']\n    // must match entire pattern\n    // ending in a * or ** will make it less strict.\n    re = '^' + open + re + close + '$'\n\n    // can match anything, as long as it's not this.\n    if (this.negate) re = '^(?!' + re + ').+$'\n\n    try {\n      this.regexp = new RegExp(re, [...flags].join(''))\n      /* c8 ignore start */\n    } catch (ex) {\n      // should be impossible\n      this.regexp = false\n    }\n    /* c8 ignore stop */\n    return this.regexp\n  }\n\n  slashSplit(p: string) {\n    // if p starts with // on windows, we preserve that\n    // so that UNC paths aren't broken.  Otherwise, any number of\n    // / characters are coalesced into one, unless\n    // preserveMultipleSlashes is set to true.\n    if (this.preserveMultipleSlashes) {\n      return p.split('/')\n    } else if (this.isWindows && /^\\/\\/[^\\/]+/.test(p)) {\n      // add an extra '' for the one we lose\n      return ['', ...p.split(/\\/+/)]\n    } else {\n      return p.split(/\\/+/)\n    }\n  }\n\n  match(f: string, partial = this.partial) {\n    this.debug('match', f, this.pattern)\n    // short-circuit in the case of busted things.\n    // comments, etc.\n    if (this.comment) {\n      return false\n    }\n    if (this.empty) {\n      return f === ''\n    }\n\n    if (f === '/' && partial) {\n      return true\n    }\n\n    const options = this.options\n\n    // windows: need to use /, not \\\n    if (this.isWindows) {\n      f = f.split('\\\\').join('/')\n    }\n\n    // treat the test path as a set of pathparts.\n    const ff = this.slashSplit(f)\n    this.debug(this.pattern, 'split', ff)\n\n    // just ONE of the pattern sets in this.set needs to match\n    // in order for it to be valid.  If negating, then just one\n    // match means that we have failed.\n    // Either way, return on the first hit.\n\n    const set = this.set\n    this.debug(this.pattern, 'set', set)\n\n    // Find the basename of the path by looking for the last non-empty segment\n    let filename: string = ff[ff.length - 1]\n    if (!filename) {\n      for (let i = ff.length - 2; !filename && i >= 0; i--) {\n        filename = ff[i]\n      }\n    }\n\n    for (let i = 0; i < set.length; i++) {\n      const pattern = set[i]\n      let file = ff\n      if (options.matchBase && pattern.length === 1) {\n        file = [filename]\n      }\n      const hit = this.matchOne(file, pattern, partial)\n      if (hit) {\n        if (options.flipNegate) {\n          return true\n        }\n        return !this.negate\n      }\n    }\n\n    // didn't get any hits.  this is success if it's a negative\n    // pattern, failure otherwise.\n    if (options.flipNegate) {\n      return false\n    }\n    return this.negate\n  }\n\n  static defaults(def: MinimatchOptions) {\n    return minimatch.defaults(def).Minimatch\n  }\n}\n/* c8 ignore start */\nexport { AST } from './ast.js'\nexport { escape } from './escape.js'\nexport { unescape } from './unescape.js'\n/* c8 ignore stop */\nminimatch.AST = AST\nminimatch.Minimatch = Minimatch\nminimatch.escape = escape\nminimatch.unescape = unescape\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/package.json b/backend/node_modules/minimatch/dist/commonjs/package.json
new file mode 100644
index 00000000..5bbefffb
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/commonjs/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "commonjs"
+}
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts b/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts
new file mode 100644
index 00000000..23a7b387
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts
@@ -0,0 +1,17 @@
+import { MinimatchOptions } from './index.js';
+/**
+ * Un-escape a string that has been escaped with {@link escape}.
+ *
+ * If the {@link windowsPathsNoEscape} option is used, then square-brace
+ * escapes are removed, but not backslash escapes.  For example, it will turn
+ * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
+ * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
+ *
+ * When `windowsPathsNoEscape` is not set, then both brace escapes and
+ * backslash escapes are removed.
+ *
+ * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
+ * or unescaped.
+ */
+export declare const unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
+//# sourceMappingURL=unescape.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map
new file mode 100644
index 00000000..7ace0701
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,MAChB,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAKlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.js b/backend/node_modules/minimatch/dist/commonjs/unescape.js
new file mode 100644
index 00000000..47c36bce
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/commonjs/unescape.js
@@ -0,0 +1,24 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.unescape = void 0;
+/**
+ * Un-escape a string that has been escaped with {@link escape}.
+ *
+ * If the {@link windowsPathsNoEscape} option is used, then square-brace
+ * escapes are removed, but not backslash escapes.  For example, it will turn
+ * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
+ * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
+ *
+ * When `windowsPathsNoEscape` is not set, then both brace escapes and
+ * backslash escapes are removed.
+ *
+ * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
+ * or unescaped.
+ */
+const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
+    return windowsPathsNoEscape
+        ? s.replace(/\[([^\/\\])\]/g, '$1')
+        : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
+};
+exports.unescape = unescape;
+//# sourceMappingURL=unescape.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.js.map b/backend/node_modules/minimatch/dist/commonjs/unescape.js.map
new file mode 100644
index 00000000..353d3aa0
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/commonjs/unescape.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":";;;AACA;;;;;;;;;;;;;GAaG;AACI,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAA;AATY,QAAA,QAAQ,YASpB","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link windowsPathsNoEscape} option is used, then square-brace\n * escapes are removed, but not backslash escapes.  For example, it will turn\n * the string `'[*]'` into `*`, but it will not turn `'\\\\*'` into `'*'`,\n * becuase `\\` is a path separator in `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both brace escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n */\nexport const unescape = (\n  s: string,\n  {\n    windowsPathsNoEscape = false,\n  }: Pick = {}\n) => {\n  return windowsPathsNoEscape\n    ? s.replace(/\\[([^\\/\\\\])\\]/g, '$1')\n    : s.replace(/((?!\\\\).|^)\\[([^\\/\\\\])\\]/g, '$1$2').replace(/\\\\([^\\/])/g, '$1')\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts
new file mode 100644
index 00000000..8e318b23
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts
@@ -0,0 +1,2 @@
+export declare const assertValidPattern: (pattern: any) => void;
+//# sourceMappingURL=assert-valid-pattern.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map
new file mode 100644
index 00000000..c61c0310
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAUlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js
new file mode 100644
index 00000000..7b534fc3
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js
@@ -0,0 +1,10 @@
+const MAX_PATTERN_LENGTH = 1024 * 64;
+export const assertValidPattern = (pattern) => {
+    if (typeof pattern !== 'string') {
+        throw new TypeError('invalid pattern');
+    }
+    if (pattern.length > MAX_PATTERN_LENGTH) {
+        throw new TypeError('pattern is too long');
+    }
+};
+//# sourceMappingURL=assert-valid-pattern.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map
new file mode 100644
index 00000000..b1a5a0b9
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAA2B,CACxD,OAAY,EACe,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;KACvC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE;QACvC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;KAC3C;AACH,CAAC,CAAA","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: any) => void = (\n  pattern: any\n): asserts pattern is string => {\n  if (typeof pattern !== 'string') {\n    throw new TypeError('invalid pattern')\n  }\n\n  if (pattern.length > MAX_PATTERN_LENGTH) {\n    throw new TypeError('pattern is too long')\n  }\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.d.ts b/backend/node_modules/minimatch/dist/esm/ast.d.ts
new file mode 100644
index 00000000..b8c1e544
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/ast.d.ts
@@ -0,0 +1,20 @@
+import { MinimatchOptions, MMRegExp } from './index.js';
+export type ExtglobType = '!' | '?' | '+' | '*' | '@';
+export declare class AST {
+    #private;
+    type: ExtglobType | null;
+    constructor(type: ExtglobType | null, parent?: AST, options?: MinimatchOptions);
+    get hasMagic(): boolean | undefined;
+    toString(): string;
+    push(...parts: (string | AST)[]): void;
+    toJSON(): any[];
+    isStart(): boolean;
+    isEnd(): boolean;
+    copyIn(part: AST | string): void;
+    clone(parent: AST): AST;
+    static fromGlob(pattern: string, options?: MinimatchOptions): AST;
+    toMMPattern(): MMRegExp | string;
+    get options(): MinimatchOptions;
+    toRegExpSource(allowDot?: boolean): [re: string, body: string, hasMagic: boolean, uflag: boolean];
+}
+//# sourceMappingURL=ast.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.d.ts.map b/backend/node_modules/minimatch/dist/esm/ast.d.ts.map
new file mode 100644
index 00000000..9e7bfb9a
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/ast.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwCvD,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAkCrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;gBAiBtB,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IA+ClB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAY/B,MAAM;IAgBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsIjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CAiMjE"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.js b/backend/node_modules/minimatch/dist/esm/ast.js
new file mode 100644
index 00000000..2d2bced6
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/ast.js
@@ -0,0 +1,588 @@
+// parse a single path portion
+import { parseClass } from './brace-expressions.js';
+import { unescape } from './unescape.js';
+const types = new Set(['!', '?', '+', '*', '@']);
+const isExtglobType = (c) => types.has(c);
+// Patterns that get prepended to bind to the start of either the
+// entire string, or just a single path portion, to prevent dots
+// and/or traversal patterns, when needed.
+// Exts don't need the ^ or / bit, because the root binds that already.
+const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))';
+const startNoDot = '(?!\\.)';
+// characters that indicate a start of pattern needs the "no dots" bit,
+// because a dot *might* be matched. ( is not in the list, because in
+// the case of a child extglob, it will handle the prevention itself.
+const addPatternStart = new Set(['[', '.']);
+// cases where traversal is A-OK, no dot prevention needed
+const justDots = new Set(['..', '.']);
+const reSpecials = new Set('().*{}+?[]^$\\!');
+const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+// any single thing other than /
+const qmark = '[^/]';
+// * => any number of characters
+const star = qmark + '*?';
+// use + when we need to ensure that *something* matches, because the * is
+// the only thing in the path portion.
+const starNoEmpty = qmark + '+?';
+// remove the \ chars that we added if we end up doing a nonmagic compare
+// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
+export class AST {
+    type;
+    #root;
+    #hasMagic;
+    #uflag = false;
+    #parts = [];
+    #parent;
+    #parentIndex;
+    #negs;
+    #filledNegs = false;
+    #options;
+    #toString;
+    // set to true if it's an extglob with no children
+    // (which really means one child of '')
+    #emptyExt = false;
+    constructor(type, parent, options = {}) {
+        this.type = type;
+        // extglobs are inherently magical
+        if (type)
+            this.#hasMagic = true;
+        this.#parent = parent;
+        this.#root = this.#parent ? this.#parent.#root : this;
+        this.#options = this.#root === this ? options : this.#root.#options;
+        this.#negs = this.#root === this ? [] : this.#root.#negs;
+        if (type === '!' && !this.#root.#filledNegs)
+            this.#negs.push(this);
+        this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;
+    }
+    get hasMagic() {
+        /* c8 ignore start */
+        if (this.#hasMagic !== undefined)
+            return this.#hasMagic;
+        /* c8 ignore stop */
+        for (const p of this.#parts) {
+            if (typeof p === 'string')
+                continue;
+            if (p.type || p.hasMagic)
+                return (this.#hasMagic = true);
+        }
+        // note: will be undefined until we generate the regexp src and find out
+        return this.#hasMagic;
+    }
+    // reconstructs the pattern
+    toString() {
+        if (this.#toString !== undefined)
+            return this.#toString;
+        if (!this.type) {
+            return (this.#toString = this.#parts.map(p => String(p)).join(''));
+        }
+        else {
+            return (this.#toString =
+                this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')');
+        }
+    }
+    #fillNegs() {
+        /* c8 ignore start */
+        if (this !== this.#root)
+            throw new Error('should only call on root');
+        if (this.#filledNegs)
+            return this;
+        /* c8 ignore stop */
+        // call toString() once to fill this out
+        this.toString();
+        this.#filledNegs = true;
+        let n;
+        while ((n = this.#negs.pop())) {
+            if (n.type !== '!')
+                continue;
+            // walk up the tree, appending everthing that comes AFTER parentIndex
+            let p = n;
+            let pp = p.#parent;
+            while (pp) {
+                for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {
+                    for (const part of n.#parts) {
+                        /* c8 ignore start */
+                        if (typeof part === 'string') {
+                            throw new Error('string part in extglob AST??');
+                        }
+                        /* c8 ignore stop */
+                        part.copyIn(pp.#parts[i]);
+                    }
+                }
+                p = pp;
+                pp = p.#parent;
+            }
+        }
+        return this;
+    }
+    push(...parts) {
+        for (const p of parts) {
+            if (p === '')
+                continue;
+            /* c8 ignore start */
+            if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {
+                throw new Error('invalid part: ' + p);
+            }
+            /* c8 ignore stop */
+            this.#parts.push(p);
+        }
+    }
+    toJSON() {
+        const ret = this.type === null
+            ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))
+            : [this.type, ...this.#parts.map(p => p.toJSON())];
+        if (this.isStart() && !this.type)
+            ret.unshift([]);
+        if (this.isEnd() &&
+            (this === this.#root ||
+                (this.#root.#filledNegs && this.#parent?.type === '!'))) {
+            ret.push({});
+        }
+        return ret;
+    }
+    isStart() {
+        if (this.#root === this)
+            return true;
+        // if (this.type) return !!this.#parent?.isStart()
+        if (!this.#parent?.isStart())
+            return false;
+        if (this.#parentIndex === 0)
+            return true;
+        // if everything AHEAD of this is a negation, then it's still the "start"
+        const p = this.#parent;
+        for (let i = 0; i < this.#parentIndex; i++) {
+            const pp = p.#parts[i];
+            if (!(pp instanceof AST && pp.type === '!')) {
+                return false;
+            }
+        }
+        return true;
+    }
+    isEnd() {
+        if (this.#root === this)
+            return true;
+        if (this.#parent?.type === '!')
+            return true;
+        if (!this.#parent?.isEnd())
+            return false;
+        if (!this.type)
+            return this.#parent?.isEnd();
+        // if not root, it'll always have a parent
+        /* c8 ignore start */
+        const pl = this.#parent ? this.#parent.#parts.length : 0;
+        /* c8 ignore stop */
+        return this.#parentIndex === pl - 1;
+    }
+    copyIn(part) {
+        if (typeof part === 'string')
+            this.push(part);
+        else
+            this.push(part.clone(this));
+    }
+    clone(parent) {
+        const c = new AST(this.type, parent);
+        for (const p of this.#parts) {
+            c.copyIn(p);
+        }
+        return c;
+    }
+    static #parseAST(str, ast, pos, opt) {
+        let escaping = false;
+        let inBrace = false;
+        let braceStart = -1;
+        let braceNeg = false;
+        if (ast.type === null) {
+            // outside of a extglob, append until we find a start
+            let i = pos;
+            let acc = '';
+            while (i < str.length) {
+                const c = str.charAt(i++);
+                // still accumulate escapes at this point, but we do ignore
+                // starts that are escaped
+                if (escaping || c === '\\') {
+                    escaping = !escaping;
+                    acc += c;
+                    continue;
+                }
+                if (inBrace) {
+                    if (i === braceStart + 1) {
+                        if (c === '^' || c === '!') {
+                            braceNeg = true;
+                        }
+                    }
+                    else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
+                        inBrace = false;
+                    }
+                    acc += c;
+                    continue;
+                }
+                else if (c === '[') {
+                    inBrace = true;
+                    braceStart = i;
+                    braceNeg = false;
+                    acc += c;
+                    continue;
+                }
+                if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {
+                    ast.push(acc);
+                    acc = '';
+                    const ext = new AST(c, ast);
+                    i = AST.#parseAST(str, ext, i, opt);
+                    ast.push(ext);
+                    continue;
+                }
+                acc += c;
+            }
+            ast.push(acc);
+            return i;
+        }
+        // some kind of extglob, pos is at the (
+        // find the next | or )
+        let i = pos + 1;
+        let part = new AST(null, ast);
+        const parts = [];
+        let acc = '';
+        while (i < str.length) {
+            const c = str.charAt(i++);
+            // still accumulate escapes at this point, but we do ignore
+            // starts that are escaped
+            if (escaping || c === '\\') {
+                escaping = !escaping;
+                acc += c;
+                continue;
+            }
+            if (inBrace) {
+                if (i === braceStart + 1) {
+                    if (c === '^' || c === '!') {
+                        braceNeg = true;
+                    }
+                }
+                else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
+                    inBrace = false;
+                }
+                acc += c;
+                continue;
+            }
+            else if (c === '[') {
+                inBrace = true;
+                braceStart = i;
+                braceNeg = false;
+                acc += c;
+                continue;
+            }
+            if (isExtglobType(c) && str.charAt(i) === '(') {
+                part.push(acc);
+                acc = '';
+                const ext = new AST(c, part);
+                part.push(ext);
+                i = AST.#parseAST(str, ext, i, opt);
+                continue;
+            }
+            if (c === '|') {
+                part.push(acc);
+                acc = '';
+                parts.push(part);
+                part = new AST(null, ast);
+                continue;
+            }
+            if (c === ')') {
+                if (acc === '' && ast.#parts.length === 0) {
+                    ast.#emptyExt = true;
+                }
+                part.push(acc);
+                acc = '';
+                ast.push(...parts, part);
+                return i;
+            }
+            acc += c;
+        }
+        // unfinished extglob
+        // if we got here, it was a malformed extglob! not an extglob, but
+        // maybe something else in there.
+        ast.type = null;
+        ast.#hasMagic = undefined;
+        ast.#parts = [str.substring(pos - 1)];
+        return i;
+    }
+    static fromGlob(pattern, options = {}) {
+        const ast = new AST(null, undefined, options);
+        AST.#parseAST(pattern, ast, 0, options);
+        return ast;
+    }
+    // returns the regular expression if there's magic, or the unescaped
+    // string if not.
+    toMMPattern() {
+        // should only be called on root
+        /* c8 ignore start */
+        if (this !== this.#root)
+            return this.#root.toMMPattern();
+        /* c8 ignore stop */
+        const glob = this.toString();
+        const [re, body, hasMagic, uflag] = this.toRegExpSource();
+        // if we're in nocase mode, and not nocaseMagicOnly, then we do
+        // still need a regular expression if we have to case-insensitively
+        // match capital/lowercase characters.
+        const anyMagic = hasMagic ||
+            this.#hasMagic ||
+            (this.#options.nocase &&
+                !this.#options.nocaseMagicOnly &&
+                glob.toUpperCase() !== glob.toLowerCase());
+        if (!anyMagic) {
+            return body;
+        }
+        const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '');
+        return Object.assign(new RegExp(`^${re}$`, flags), {
+            _src: re,
+            _glob: glob,
+        });
+    }
+    get options() {
+        return this.#options;
+    }
+    // returns the string match, the regexp source, whether there's magic
+    // in the regexp (so a regular expression is required) and whether or
+    // not the uflag is needed for the regular expression (for posix classes)
+    // TODO: instead of injecting the start/end at this point, just return
+    // the BODY of the regexp, along with the start/end portions suitable
+    // for binding the start/end in either a joined full-path makeRe context
+    // (where we bind to (^|/), or a standalone matchPart context (where
+    // we bind to ^, and not /).  Otherwise slashes get duped!
+    //
+    // In part-matching mode, the start is:
+    // - if not isStart: nothing
+    // - if traversal possible, but not allowed: ^(?!\.\.?$)
+    // - if dots allowed or not possible: ^
+    // - if dots possible and not allowed: ^(?!\.)
+    // end is:
+    // - if not isEnd(): nothing
+    // - else: $
+    //
+    // In full-path matching mode, we put the slash at the START of the
+    // pattern, so start is:
+    // - if first pattern: same as part-matching mode
+    // - if not isStart(): nothing
+    // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
+    // - if dots allowed or not possible: /
+    // - if dots possible and not allowed: /(?!\.)
+    // end is:
+    // - if last pattern, same as part-matching mode
+    // - else nothing
+    //
+    // Always put the (?:$|/) on negated tails, though, because that has to be
+    // there to bind the end of the negated pattern portion, and it's easier to
+    // just stick it in now rather than try to inject it later in the middle of
+    // the pattern.
+    //
+    // We can just always return the same end, and leave it up to the caller
+    // to know whether it's going to be used joined or in parts.
+    // And, if the start is adjusted slightly, can do the same there:
+    // - if not isStart: nothing
+    // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
+    // - if dots allowed or not possible: (?:/|^)
+    // - if dots possible and not allowed: (?:/|^)(?!\.)
+    //
+    // But it's better to have a simpler binding without a conditional, for
+    // performance, so probably better to return both start options.
+    //
+    // Then the caller just ignores the end if it's not the first pattern,
+    // and the start always gets applied.
+    //
+    // But that's always going to be $ if it's the ending pattern, or nothing,
+    // so the caller can just attach $ at the end of the pattern when building.
+    //
+    // So the todo is:
+    // - better detect what kind of start is needed
+    // - return both flavors of starting pattern
+    // - attach $ at the end of the pattern when creating the actual RegExp
+    //
+    // Ah, but wait, no, that all only applies to the root when the first pattern
+    // is not an extglob. If the first pattern IS an extglob, then we need all
+    // that dot prevention biz to live in the extglob portions, because eg
+    // +(*|.x*) can match .xy but not .yx.
+    //
+    // So, return the two flavors if it's #root and the first child is not an
+    // AST, otherwise leave it to the child AST to handle it, and there,
+    // use the (?:^|/) style of start binding.
+    //
+    // Even simplified further:
+    // - Since the start for a join is eg /(?!\.) and the start for a part
+    // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
+    // or start or whatever) and prepend ^ or / at the Regexp construction.
+    toRegExpSource(allowDot) {
+        const dot = allowDot ?? !!this.#options.dot;
+        if (this.#root === this)
+            this.#fillNegs();
+        if (!this.type) {
+            const noEmpty = this.isStart() && this.isEnd();
+            const src = this.#parts
+                .map(p => {
+                const [re, _, hasMagic, uflag] = typeof p === 'string'
+                    ? AST.#parseGlob(p, this.#hasMagic, noEmpty)
+                    : p.toRegExpSource(allowDot);
+                this.#hasMagic = this.#hasMagic || hasMagic;
+                this.#uflag = this.#uflag || uflag;
+                return re;
+            })
+                .join('');
+            let start = '';
+            if (this.isStart()) {
+                if (typeof this.#parts[0] === 'string') {
+                    // this is the string that will match the start of the pattern,
+                    // so we need to protect against dots and such.
+                    // '.' and '..' cannot match unless the pattern is that exactly,
+                    // even if it starts with . or dot:true is set.
+                    const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
+                    if (!dotTravAllowed) {
+                        const aps = addPatternStart;
+                        // check if we have a possibility of matching . or ..,
+                        // and prevent that.
+                        const needNoTrav = 
+                        // dots are allowed, and the pattern starts with [ or .
+                        (dot && aps.has(src.charAt(0))) ||
+                            // the pattern starts with \., and then [ or .
+                            (src.startsWith('\\.') && aps.has(src.charAt(2))) ||
+                            // the pattern starts with \.\., and then [ or .
+                            (src.startsWith('\\.\\.') && aps.has(src.charAt(4)));
+                        // no need to prevent dots if it can't match a dot, or if a
+                        // sub-pattern will be preventing it anyway.
+                        const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
+                        start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : '';
+                    }
+                }
+            }
+            // append the "end of path portion" pattern to negation tails
+            let end = '';
+            if (this.isEnd() &&
+                this.#root.#filledNegs &&
+                this.#parent?.type === '!') {
+                end = '(?:$|\\/)';
+            }
+            const final = start + src + end;
+            return [
+                final,
+                unescape(src),
+                (this.#hasMagic = !!this.#hasMagic),
+                this.#uflag,
+            ];
+        }
+        // We need to calculate the body *twice* if it's a repeat pattern
+        // at the start, once in nodot mode, then again in dot mode, so a
+        // pattern like *(?) can match 'x.y'
+        const repeated = this.type === '*' || this.type === '+';
+        // some kind of extglob
+        const start = this.type === '!' ? '(?:(?!(?:' : '(?:';
+        let body = this.#partsToRegExp(dot);
+        if (this.isStart() && this.isEnd() && !body && this.type !== '!') {
+            // invalid extglob, has to at least be *something* present, if it's
+            // the entire path portion.
+            const s = this.toString();
+            this.#parts = [s];
+            this.type = null;
+            this.#hasMagic = undefined;
+            return [s, unescape(this.toString()), false, false];
+        }
+        // XXX abstract out this map method
+        let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot
+            ? ''
+            : this.#partsToRegExp(true);
+        if (bodyDotAllowed === body) {
+            bodyDotAllowed = '';
+        }
+        if (bodyDotAllowed) {
+            body = `(?:${body})(?:${bodyDotAllowed})*?`;
+        }
+        // an empty !() is exactly equivalent to a starNoEmpty
+        let final = '';
+        if (this.type === '!' && this.#emptyExt) {
+            final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty;
+        }
+        else {
+            const close = this.type === '!'
+                ? // !() must match something,but !(x) can match ''
+                    '))' +
+                        (this.isStart() && !dot && !allowDot ? startNoDot : '') +
+                        star +
+                        ')'
+                : this.type === '@'
+                    ? ')'
+                    : this.type === '?'
+                        ? ')?'
+                        : this.type === '+' && bodyDotAllowed
+                            ? ')'
+                            : this.type === '*' && bodyDotAllowed
+                                ? `)?`
+                                : `)${this.type}`;
+            final = start + body + close;
+        }
+        return [
+            final,
+            unescape(body),
+            (this.#hasMagic = !!this.#hasMagic),
+            this.#uflag,
+        ];
+    }
+    #partsToRegExp(dot) {
+        return this.#parts
+            .map(p => {
+            // extglob ASTs should only contain parent ASTs
+            /* c8 ignore start */
+            if (typeof p === 'string') {
+                throw new Error('string type in extglob ast??');
+            }
+            /* c8 ignore stop */
+            // can ignore hasMagic, because extglobs are already always magic
+            const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
+            this.#uflag = this.#uflag || uflag;
+            return re;
+        })
+            .filter(p => !(this.isStart() && this.isEnd()) || !!p)
+            .join('|');
+    }
+    static #parseGlob(glob, hasMagic, noEmpty = false) {
+        let escaping = false;
+        let re = '';
+        let uflag = false;
+        for (let i = 0; i < glob.length; i++) {
+            const c = glob.charAt(i);
+            if (escaping) {
+                escaping = false;
+                re += (reSpecials.has(c) ? '\\' : '') + c;
+                continue;
+            }
+            if (c === '\\') {
+                if (i === glob.length - 1) {
+                    re += '\\\\';
+                }
+                else {
+                    escaping = true;
+                }
+                continue;
+            }
+            if (c === '[') {
+                const [src, needUflag, consumed, magic] = parseClass(glob, i);
+                if (consumed) {
+                    re += src;
+                    uflag = uflag || needUflag;
+                    i += consumed - 1;
+                    hasMagic = hasMagic || magic;
+                    continue;
+                }
+            }
+            if (c === '*') {
+                if (noEmpty && glob === '*')
+                    re += starNoEmpty;
+                else
+                    re += star;
+                hasMagic = true;
+                continue;
+            }
+            if (c === '?') {
+                re += qmark;
+                hasMagic = true;
+                continue;
+            }
+            re += regExpEscape(c);
+        }
+        return [re, unescape(glob), !!hasMagic, uflag];
+    }
+}
+//# sourceMappingURL=ast.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.js.map b/backend/node_modules/minimatch/dist/esm/ast.js.map
new file mode 100644
index 00000000..f1f8b34c
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/ast.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"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","sourcesContent":["// parse a single path portion\n\nimport { parseClass } from './brace-expressions.js'\nimport { MinimatchOptions, MMRegExp } from './index.js'\nimport { unescape } from './unescape.js'\n\n// classes [] are handled by the parseClass method\n// for positive extglobs, we sub-parse the contents, and combine,\n// with the appropriate regexp close.\n// for negative extglobs, we sub-parse the contents, but then\n// have to include the rest of the pattern, then the parent, etc.,\n// as the thing that cannot be because RegExp negative lookaheads\n// are different from globs.\n//\n// So for example:\n// a@(i|w!(x|y)z|j)b => ^a(i|w((!?(x|y)zb).*)z|j)b$\n//   1   2 3   4 5 6      1   2    3   46      5 6\n//\n// Assembling the extglob requires not just the negated patterns themselves,\n// but also anything following the negative patterns up to the boundary\n// of the current pattern, plus anything following in the parent pattern.\n//\n//\n// So, first, we parse the string into an AST of extglobs, without turning\n// anything into regexps yet.\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y']}, 'z'], ['j']]}, 'b']\n//\n// Then, for all the negative extglobs, we append whatever comes after in\n// each parent as their tail\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y'], 'z', 'b'}, 'z'], ['j']]}, 'b']\n//\n// Lastly, we turn each of these pieces into a regexp, and join\n//\n//                                 v----- .* because there's more following,\n//                                 v    v  otherwise, .+ because it must be\n//                                 v    v  *something* there.\n// ['^a', {@ ['i', 'w(?:(!?(?:x|y).*zb$).*)z', 'j' ]}, 'b$']\n//   copy what follows into here--^^^^^\n// ['^a', '(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)', 'b$']\n// ['^a(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)b$']\n\nexport type ExtglobType = '!' | '?' | '+' | '*' | '@'\nconst types = new Set(['!', '?', '+', '*', '@'])\nconst isExtglobType = (c: string): c is ExtglobType =>\n  types.has(c as ExtglobType)\n\n// Patterns that get prepended to bind to the start of either the\n// entire string, or just a single path portion, to prevent dots\n// and/or traversal patterns, when needed.\n// Exts don't need the ^ or / bit, because the root binds that already.\nconst startNoTraversal = '(?!(?:^|/)\\\\.\\\\.?(?:$|/))'\nconst startNoDot = '(?!\\\\.)'\n\n// characters that indicate a start of pattern needs the \"no dots\" bit,\n// because a dot *might* be matched. ( is not in the list, because in\n// the case of a child extglob, it will handle the prevention itself.\nconst addPatternStart = new Set(['[', '.'])\n// cases where traversal is A-OK, no dot prevention needed\nconst justDots = new Set(['..', '.'])\nconst reSpecials = new Set('().*{}+?[]^$\\\\!')\nconst regExpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// any single thing other than /\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n// use + when we need to ensure that *something* matches, because the * is\n// the only thing in the path portion.\nconst starNoEmpty = qmark + '+?'\n\n// remove the \\ chars that we added if we end up doing a nonmagic compare\n// const deslash = (s: string) => s.replace(/\\\\(.)/g, '$1')\n\nexport class AST {\n  type: ExtglobType | null\n  readonly #root: AST\n\n  #hasMagic?: boolean\n  #uflag: boolean = false\n  #parts: (string | AST)[] = []\n  readonly #parent?: AST\n  readonly #parentIndex: number\n  #negs: AST[]\n  #filledNegs: boolean = false\n  #options: MinimatchOptions\n  #toString?: string\n  // set to true if it's an extglob with no children\n  // (which really means one child of '')\n  #emptyExt: boolean = false\n\n  constructor(\n    type: ExtglobType | null,\n    parent?: AST,\n    options: MinimatchOptions = {}\n  ) {\n    this.type = type\n    // extglobs are inherently magical\n    if (type) this.#hasMagic = true\n    this.#parent = parent\n    this.#root = this.#parent ? this.#parent.#root : this\n    this.#options = this.#root === this ? options : this.#root.#options\n    this.#negs = this.#root === this ? [] : this.#root.#negs\n    if (type === '!' && !this.#root.#filledNegs) this.#negs.push(this)\n    this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0\n  }\n\n  get hasMagic(): boolean | undefined {\n    /* c8 ignore start */\n    if (this.#hasMagic !== undefined) return this.#hasMagic\n    /* c8 ignore stop */\n    for (const p of this.#parts) {\n      if (typeof p === 'string') continue\n      if (p.type || p.hasMagic) return (this.#hasMagic = true)\n    }\n    // note: will be undefined until we generate the regexp src and find out\n    return this.#hasMagic\n  }\n\n  // reconstructs the pattern\n  toString(): string {\n    if (this.#toString !== undefined) return this.#toString\n    if (!this.type) {\n      return (this.#toString = this.#parts.map(p => String(p)).join(''))\n    } else {\n      return (this.#toString =\n        this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')')\n    }\n  }\n\n  #fillNegs() {\n    /* c8 ignore start */\n    if (this !== this.#root) throw new Error('should only call on root')\n    if (this.#filledNegs) return this\n    /* c8 ignore stop */\n\n    // call toString() once to fill this out\n    this.toString()\n    this.#filledNegs = true\n    let n: AST | undefined\n    while ((n = this.#negs.pop())) {\n      if (n.type !== '!') continue\n      // walk up the tree, appending everthing that comes AFTER parentIndex\n      let p: AST | undefined = n\n      let pp = p.#parent\n      while (pp) {\n        for (\n          let i = p.#parentIndex + 1;\n          !pp.type && i < pp.#parts.length;\n          i++\n        ) {\n          for (const part of n.#parts) {\n            /* c8 ignore start */\n            if (typeof part === 'string') {\n              throw new Error('string part in extglob AST??')\n            }\n            /* c8 ignore stop */\n            part.copyIn(pp.#parts[i])\n          }\n        }\n        p = pp\n        pp = p.#parent\n      }\n    }\n    return this\n  }\n\n  push(...parts: (string | AST)[]) {\n    for (const p of parts) {\n      if (p === '') continue\n      /* c8 ignore start */\n      if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {\n        throw new Error('invalid part: ' + p)\n      }\n      /* c8 ignore stop */\n      this.#parts.push(p)\n    }\n  }\n\n  toJSON() {\n    const ret: any[] =\n      this.type === null\n        ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))\n        : [this.type, ...this.#parts.map(p => (p as AST).toJSON())]\n    if (this.isStart() && !this.type) ret.unshift([])\n    if (\n      this.isEnd() &&\n      (this === this.#root ||\n        (this.#root.#filledNegs && this.#parent?.type === '!'))\n    ) {\n      ret.push({})\n    }\n    return ret\n  }\n\n  isStart(): boolean {\n    if (this.#root === this) return true\n    // if (this.type) return !!this.#parent?.isStart()\n    if (!this.#parent?.isStart()) return false\n    if (this.#parentIndex === 0) return true\n    // if everything AHEAD of this is a negation, then it's still the \"start\"\n    const p = this.#parent\n    for (let i = 0; i < this.#parentIndex; i++) {\n      const pp = p.#parts[i]\n      if (!(pp instanceof AST && pp.type === '!')) {\n        return false\n      }\n    }\n    return true\n  }\n\n  isEnd(): boolean {\n    if (this.#root === this) return true\n    if (this.#parent?.type === '!') return true\n    if (!this.#parent?.isEnd()) return false\n    if (!this.type) return this.#parent?.isEnd()\n    // if not root, it'll always have a parent\n    /* c8 ignore start */\n    const pl = this.#parent ? this.#parent.#parts.length : 0\n    /* c8 ignore stop */\n    return this.#parentIndex === pl - 1\n  }\n\n  copyIn(part: AST | string) {\n    if (typeof part === 'string') this.push(part)\n    else this.push(part.clone(this))\n  }\n\n  clone(parent: AST) {\n    const c = new AST(this.type, parent)\n    for (const p of this.#parts) {\n      c.copyIn(p)\n    }\n    return c\n  }\n\n  static #parseAST(\n    str: string,\n    ast: AST,\n    pos: number,\n    opt: MinimatchOptions\n  ): number {\n    let escaping = false\n    let inBrace = false\n    let braceStart = -1\n    let braceNeg = false\n    if (ast.type === null) {\n      // outside of a extglob, append until we find a start\n      let i = pos\n      let acc = ''\n      while (i < str.length) {\n        const c = str.charAt(i++)\n        // still accumulate escapes at this point, but we do ignore\n        // starts that are escaped\n        if (escaping || c === '\\\\') {\n          escaping = !escaping\n          acc += c\n          continue\n        }\n\n        if (inBrace) {\n          if (i === braceStart + 1) {\n            if (c === '^' || c === '!') {\n              braceNeg = true\n            }\n          } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n            inBrace = false\n          }\n          acc += c\n          continue\n        } else if (c === '[') {\n          inBrace = true\n          braceStart = i\n          braceNeg = false\n          acc += c\n          continue\n        }\n\n        if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {\n          ast.push(acc)\n          acc = ''\n          const ext = new AST(c, ast)\n          i = AST.#parseAST(str, ext, i, opt)\n          ast.push(ext)\n          continue\n        }\n        acc += c\n      }\n      ast.push(acc)\n      return i\n    }\n\n    // some kind of extglob, pos is at the (\n    // find the next | or )\n    let i = pos + 1\n    let part = new AST(null, ast)\n    const parts: AST[] = []\n    let acc = ''\n    while (i < str.length) {\n      const c = str.charAt(i++)\n      // still accumulate escapes at this point, but we do ignore\n      // starts that are escaped\n      if (escaping || c === '\\\\') {\n        escaping = !escaping\n        acc += c\n        continue\n      }\n\n      if (inBrace) {\n        if (i === braceStart + 1) {\n          if (c === '^' || c === '!') {\n            braceNeg = true\n          }\n        } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n          inBrace = false\n        }\n        acc += c\n        continue\n      } else if (c === '[') {\n        inBrace = true\n        braceStart = i\n        braceNeg = false\n        acc += c\n        continue\n      }\n\n      if (isExtglobType(c) && str.charAt(i) === '(') {\n        part.push(acc)\n        acc = ''\n        const ext = new AST(c, part)\n        part.push(ext)\n        i = AST.#parseAST(str, ext, i, opt)\n        continue\n      }\n      if (c === '|') {\n        part.push(acc)\n        acc = ''\n        parts.push(part)\n        part = new AST(null, ast)\n        continue\n      }\n      if (c === ')') {\n        if (acc === '' && ast.#parts.length === 0) {\n          ast.#emptyExt = true\n        }\n        part.push(acc)\n        acc = ''\n        ast.push(...parts, part)\n        return i\n      }\n      acc += c\n    }\n\n    // unfinished extglob\n    // if we got here, it was a malformed extglob! not an extglob, but\n    // maybe something else in there.\n    ast.type = null\n    ast.#hasMagic = undefined\n    ast.#parts = [str.substring(pos - 1)]\n    return i\n  }\n\n  static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n    const ast = new AST(null, undefined, options)\n    AST.#parseAST(pattern, ast, 0, options)\n    return ast\n  }\n\n  // returns the regular expression if there's magic, or the unescaped\n  // string if not.\n  toMMPattern(): MMRegExp | string {\n    // should only be called on root\n    /* c8 ignore start */\n    if (this !== this.#root) return this.#root.toMMPattern()\n    /* c8 ignore stop */\n    const glob = this.toString()\n    const [re, body, hasMagic, uflag] = this.toRegExpSource()\n    // if we're in nocase mode, and not nocaseMagicOnly, then we do\n    // still need a regular expression if we have to case-insensitively\n    // match capital/lowercase characters.\n    const anyMagic =\n      hasMagic ||\n      this.#hasMagic ||\n      (this.#options.nocase &&\n        !this.#options.nocaseMagicOnly &&\n        glob.toUpperCase() !== glob.toLowerCase())\n    if (!anyMagic) {\n      return body\n    }\n\n    const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '')\n    return Object.assign(new RegExp(`^${re}$`, flags), {\n      _src: re,\n      _glob: glob,\n    })\n  }\n\n  get options() {\n    return this.#options\n  }\n\n  // returns the string match, the regexp source, whether there's magic\n  // in the regexp (so a regular expression is required) and whether or\n  // not the uflag is needed for the regular expression (for posix classes)\n  // TODO: instead of injecting the start/end at this point, just return\n  // the BODY of the regexp, along with the start/end portions suitable\n  // for binding the start/end in either a joined full-path makeRe context\n  // (where we bind to (^|/), or a standalone matchPart context (where\n  // we bind to ^, and not /).  Otherwise slashes get duped!\n  //\n  // In part-matching mode, the start is:\n  // - if not isStart: nothing\n  // - if traversal possible, but not allowed: ^(?!\\.\\.?$)\n  // - if dots allowed or not possible: ^\n  // - if dots possible and not allowed: ^(?!\\.)\n  // end is:\n  // - if not isEnd(): nothing\n  // - else: $\n  //\n  // In full-path matching mode, we put the slash at the START of the\n  // pattern, so start is:\n  // - if first pattern: same as part-matching mode\n  // - if not isStart(): nothing\n  // - if traversal possible, but not allowed: /(?!\\.\\.?(?:$|/))\n  // - if dots allowed or not possible: /\n  // - if dots possible and not allowed: /(?!\\.)\n  // end is:\n  // - if last pattern, same as part-matching mode\n  // - else nothing\n  //\n  // Always put the (?:$|/) on negated tails, though, because that has to be\n  // there to bind the end of the negated pattern portion, and it's easier to\n  // just stick it in now rather than try to inject it later in the middle of\n  // the pattern.\n  //\n  // We can just always return the same end, and leave it up to the caller\n  // to know whether it's going to be used joined or in parts.\n  // And, if the start is adjusted slightly, can do the same there:\n  // - if not isStart: nothing\n  // - if traversal possible, but not allowed: (?:/|^)(?!\\.\\.?$)\n  // - if dots allowed or not possible: (?:/|^)\n  // - if dots possible and not allowed: (?:/|^)(?!\\.)\n  //\n  // But it's better to have a simpler binding without a conditional, for\n  // performance, so probably better to return both start options.\n  //\n  // Then the caller just ignores the end if it's not the first pattern,\n  // and the start always gets applied.\n  //\n  // But that's always going to be $ if it's the ending pattern, or nothing,\n  // so the caller can just attach $ at the end of the pattern when building.\n  //\n  // So the todo is:\n  // - better detect what kind of start is needed\n  // - return both flavors of starting pattern\n  // - attach $ at the end of the pattern when creating the actual RegExp\n  //\n  // Ah, but wait, no, that all only applies to the root when the first pattern\n  // is not an extglob. If the first pattern IS an extglob, then we need all\n  // that dot prevention biz to live in the extglob portions, because eg\n  // +(*|.x*) can match .xy but not .yx.\n  //\n  // So, return the two flavors if it's #root and the first child is not an\n  // AST, otherwise leave it to the child AST to handle it, and there,\n  // use the (?:^|/) style of start binding.\n  //\n  // Even simplified further:\n  // - Since the start for a join is eg /(?!\\.) and the start for a part\n  // is ^(?!\\.), we can just prepend (?!\\.) to the pattern (either root\n  // or start or whatever) and prepend ^ or / at the Regexp construction.\n  toRegExpSource(\n    allowDot?: boolean\n  ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n    const dot = allowDot ?? !!this.#options.dot\n    if (this.#root === this) this.#fillNegs()\n    if (!this.type) {\n      const noEmpty = this.isStart() && this.isEnd()\n      const src = this.#parts\n        .map(p => {\n          const [re, _, hasMagic, uflag] =\n            typeof p === 'string'\n              ? AST.#parseGlob(p, this.#hasMagic, noEmpty)\n              : p.toRegExpSource(allowDot)\n          this.#hasMagic = this.#hasMagic || hasMagic\n          this.#uflag = this.#uflag || uflag\n          return re\n        })\n        .join('')\n\n      let start = ''\n      if (this.isStart()) {\n        if (typeof this.#parts[0] === 'string') {\n          // this is the string that will match the start of the pattern,\n          // so we need to protect against dots and such.\n\n          // '.' and '..' cannot match unless the pattern is that exactly,\n          // even if it starts with . or dot:true is set.\n          const dotTravAllowed =\n            this.#parts.length === 1 && justDots.has(this.#parts[0])\n          if (!dotTravAllowed) {\n            const aps = addPatternStart\n            // check if we have a possibility of matching . or ..,\n            // and prevent that.\n            const needNoTrav =\n              // dots are allowed, and the pattern starts with [ or .\n              (dot && aps.has(src.charAt(0))) ||\n              // the pattern starts with \\., and then [ or .\n              (src.startsWith('\\\\.') && aps.has(src.charAt(2))) ||\n              // the pattern starts with \\.\\., and then [ or .\n              (src.startsWith('\\\\.\\\\.') && aps.has(src.charAt(4)))\n            // no need to prevent dots if it can't match a dot, or if a\n            // sub-pattern will be preventing it anyway.\n            const needNoDot = !dot && !allowDot && aps.has(src.charAt(0))\n\n            start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''\n          }\n        }\n      }\n\n      // append the \"end of path portion\" pattern to negation tails\n      let end = ''\n      if (\n        this.isEnd() &&\n        this.#root.#filledNegs &&\n        this.#parent?.type === '!'\n      ) {\n        end = '(?:$|\\\\/)'\n      }\n      const final = start + src + end\n      return [\n        final,\n        unescape(src),\n        (this.#hasMagic = !!this.#hasMagic),\n        this.#uflag,\n      ]\n    }\n\n    // We need to calculate the body *twice* if it's a repeat pattern\n    // at the start, once in nodot mode, then again in dot mode, so a\n    // pattern like *(?) can match 'x.y'\n\n    const repeated = this.type === '*' || this.type === '+'\n    // some kind of extglob\n    const start = this.type === '!' ? '(?:(?!(?:' : '(?:'\n    let body = this.#partsToRegExp(dot)\n\n    if (this.isStart() && this.isEnd() && !body && this.type !== '!') {\n      // invalid extglob, has to at least be *something* present, if it's\n      // the entire path portion.\n      const s = this.toString()\n      this.#parts = [s]\n      this.type = null\n      this.#hasMagic = undefined\n      return [s, unescape(this.toString()), false, false]\n    }\n\n    // XXX abstract out this map method\n    let bodyDotAllowed =\n      !repeated || allowDot || dot || !startNoDot\n        ? ''\n        : this.#partsToRegExp(true)\n    if (bodyDotAllowed === body) {\n      bodyDotAllowed = ''\n    }\n    if (bodyDotAllowed) {\n      body = `(?:${body})(?:${bodyDotAllowed})*?`\n    }\n\n    // an empty !() is exactly equivalent to a starNoEmpty\n    let final = ''\n    if (this.type === '!' && this.#emptyExt) {\n      final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty\n    } else {\n      const close =\n        this.type === '!'\n          ? // !() must match something,but !(x) can match ''\n            '))' +\n            (this.isStart() && !dot && !allowDot ? startNoDot : '') +\n            star +\n            ')'\n          : this.type === '@'\n          ? ')'\n          : this.type === '?'\n          ? ')?'\n          : this.type === '+' && bodyDotAllowed\n          ? ')'\n          : this.type === '*' && bodyDotAllowed\n          ? `)?`\n          : `)${this.type}`\n      final = start + body + close\n    }\n    return [\n      final,\n      unescape(body),\n      (this.#hasMagic = !!this.#hasMagic),\n      this.#uflag,\n    ]\n  }\n\n  #partsToRegExp(dot: boolean) {\n    return this.#parts\n      .map(p => {\n        // extglob ASTs should only contain parent ASTs\n        /* c8 ignore start */\n        if (typeof p === 'string') {\n          throw new Error('string type in extglob ast??')\n        }\n        /* c8 ignore stop */\n        // can ignore hasMagic, because extglobs are already always magic\n        const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot)\n        this.#uflag = this.#uflag || uflag\n        return re\n      })\n      .filter(p => !(this.isStart() && this.isEnd()) || !!p)\n      .join('|')\n  }\n\n  static #parseGlob(\n    glob: string,\n    hasMagic: boolean | undefined,\n    noEmpty: boolean = false\n  ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n    let escaping = false\n    let re = ''\n    let uflag = false\n    for (let i = 0; i < glob.length; i++) {\n      const c = glob.charAt(i)\n      if (escaping) {\n        escaping = false\n        re += (reSpecials.has(c) ? '\\\\' : '') + c\n        continue\n      }\n      if (c === '\\\\') {\n        if (i === glob.length - 1) {\n          re += '\\\\\\\\'\n        } else {\n          escaping = true\n        }\n        continue\n      }\n      if (c === '[') {\n        const [src, needUflag, consumed, magic] = parseClass(glob, i)\n        if (consumed) {\n          re += src\n          uflag = uflag || needUflag\n          i += consumed - 1\n          hasMagic = hasMagic || magic\n          continue\n        }\n      }\n      if (c === '*') {\n        if (noEmpty && glob === '*') re += starNoEmpty\n        else re += star\n        hasMagic = true\n        continue\n      }\n      if (c === '?') {\n        re += qmark\n        hasMagic = true\n        continue\n      }\n      re += regExpEscape(c)\n    }\n    return [re, unescape(glob), !!hasMagic, uflag]\n  }\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts b/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts
new file mode 100644
index 00000000..b1572deb
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts
@@ -0,0 +1,8 @@
+export type ParseClassResult = [
+    src: string,
+    uFlag: boolean,
+    consumed: number,
+    hasMagic: boolean
+];
+export declare const parseClass: (glob: string, position: number) => ParseClassResult;
+//# sourceMappingURL=brace-expressions.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map b/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map
new file mode 100644
index 00000000..d3949648
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,SACf,MAAM,YACF,MAAM,qBA8HjB,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.js b/backend/node_modules/minimatch/dist/esm/brace-expressions.js
new file mode 100644
index 00000000..c629d6ae
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/brace-expressions.js
@@ -0,0 +1,148 @@
+// translate the various posix character classes into unicode properties
+// this works across all unicode locales
+// { : [, /u flag required, negated]
+const posixClasses = {
+    '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true],
+    '[:alpha:]': ['\\p{L}\\p{Nl}', true],
+    '[:ascii:]': ['\\x' + '00-\\x' + '7f', false],
+    '[:blank:]': ['\\p{Zs}\\t', true],
+    '[:cntrl:]': ['\\p{Cc}', true],
+    '[:digit:]': ['\\p{Nd}', true],
+    '[:graph:]': ['\\p{Z}\\p{C}', true, true],
+    '[:lower:]': ['\\p{Ll}', true],
+    '[:print:]': ['\\p{C}', true],
+    '[:punct:]': ['\\p{P}', true],
+    '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true],
+    '[:upper:]': ['\\p{Lu}', true],
+    '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true],
+    '[:xdigit:]': ['A-Fa-f0-9', false],
+};
+// only need to escape a few things inside of brace expressions
+// escapes: [ \ ] -
+const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&');
+// escape all regexp magic characters
+const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+// everything has already been escaped, we just have to join
+const rangesToString = (ranges) => ranges.join('');
+// takes a glob string at a posix brace expression, and returns
+// an equivalent regular expression source, and boolean indicating
+// whether the /u flag needs to be applied, and the number of chars
+// consumed to parse the character class.
+// This also removes out of order ranges, and returns ($.) if the
+// entire class just no good.
+export const parseClass = (glob, position) => {
+    const pos = position;
+    /* c8 ignore start */
+    if (glob.charAt(pos) !== '[') {
+        throw new Error('not in a brace expression');
+    }
+    /* c8 ignore stop */
+    const ranges = [];
+    const negs = [];
+    let i = pos + 1;
+    let sawStart = false;
+    let uflag = false;
+    let escaping = false;
+    let negate = false;
+    let endPos = pos;
+    let rangeStart = '';
+    WHILE: while (i < glob.length) {
+        const c = glob.charAt(i);
+        if ((c === '!' || c === '^') && i === pos + 1) {
+            negate = true;
+            i++;
+            continue;
+        }
+        if (c === ']' && sawStart && !escaping) {
+            endPos = i + 1;
+            break;
+        }
+        sawStart = true;
+        if (c === '\\') {
+            if (!escaping) {
+                escaping = true;
+                i++;
+                continue;
+            }
+            // escaped \ char, fall through and treat like normal char
+        }
+        if (c === '[' && !escaping) {
+            // either a posix class, a collation equivalent, or just a [
+            for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
+                if (glob.startsWith(cls, i)) {
+                    // invalid, [a-[] is fine, but not [a-[:alpha]]
+                    if (rangeStart) {
+                        return ['$.', false, glob.length - pos, true];
+                    }
+                    i += cls.length;
+                    if (neg)
+                        negs.push(unip);
+                    else
+                        ranges.push(unip);
+                    uflag = uflag || u;
+                    continue WHILE;
+                }
+            }
+        }
+        // now it's just a normal character, effectively
+        escaping = false;
+        if (rangeStart) {
+            // throw this range away if it's not valid, but others
+            // can still match.
+            if (c > rangeStart) {
+                ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c));
+            }
+            else if (c === rangeStart) {
+                ranges.push(braceEscape(c));
+            }
+            rangeStart = '';
+            i++;
+            continue;
+        }
+        // now might be the start of a range.
+        // can be either c-d or c-] or c] or c] at this point
+        if (glob.startsWith('-]', i + 1)) {
+            ranges.push(braceEscape(c + '-'));
+            i += 2;
+            continue;
+        }
+        if (glob.startsWith('-', i + 1)) {
+            rangeStart = c;
+            i += 2;
+            continue;
+        }
+        // not the start of a range, just a single character
+        ranges.push(braceEscape(c));
+        i++;
+    }
+    if (endPos < i) {
+        // didn't see the end of the class, not a valid class,
+        // but might still be valid as a literal match.
+        return ['', false, 0, false];
+    }
+    // if we got no ranges and no negates, then we have a range that
+    // cannot possibly match anything, and that poisons the whole glob
+    if (!ranges.length && !negs.length) {
+        return ['$.', false, glob.length - pos, true];
+    }
+    // if we got one positive range, and it's a single character, then that's
+    // not actually a magic pattern, it's just that one literal character.
+    // we should not treat that as "magic", we should just return the literal
+    // character. [_] is a perfectly valid way to escape glob magic chars.
+    if (negs.length === 0 &&
+        ranges.length === 1 &&
+        /^\\?.$/.test(ranges[0]) &&
+        !negate) {
+        const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
+        return [regexpEscape(r), false, endPos - pos, false];
+    }
+    const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']';
+    const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']';
+    const comb = ranges.length && negs.length
+        ? '(' + sranges + '|' + snegs + ')'
+        : ranges.length
+            ? sranges
+            : snegs;
+    return [comb, uflag, endPos - pos, true];
+};
+//# sourceMappingURL=brace-expressions.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.js.map b/backend/node_modules/minimatch/dist/esm/brace-expressions.js.map
new file mode 100644
index 00000000..cdba30da
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/brace-expressions.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"brace-expressions.js","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"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","sourcesContent":["// translate the various posix character classes into unicode properties\n// this works across all unicode locales\n\n// { : [, /u flag required, negated]\nconst posixClasses: { [k: string]: [e: string, u: boolean, n?: boolean] } = {\n  '[:alnum:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}', true],\n  '[:alpha:]': ['\\\\p{L}\\\\p{Nl}', true],\n  '[:ascii:]': ['\\\\x' + '00-\\\\x' + '7f', false],\n  '[:blank:]': ['\\\\p{Zs}\\\\t', true],\n  '[:cntrl:]': ['\\\\p{Cc}', true],\n  '[:digit:]': ['\\\\p{Nd}', true],\n  '[:graph:]': ['\\\\p{Z}\\\\p{C}', true, true],\n  '[:lower:]': ['\\\\p{Ll}', true],\n  '[:print:]': ['\\\\p{C}', true],\n  '[:punct:]': ['\\\\p{P}', true],\n  '[:space:]': ['\\\\p{Z}\\\\t\\\\r\\\\n\\\\v\\\\f', true],\n  '[:upper:]': ['\\\\p{Lu}', true],\n  '[:word:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}\\\\p{Pc}', true],\n  '[:xdigit:]': ['A-Fa-f0-9', false],\n}\n\n// only need to escape a few things inside of brace expressions\n// escapes: [ \\ ] -\nconst braceEscape = (s: string) => s.replace(/[[\\]\\\\-]/g, '\\\\$&')\n// escape all regexp magic characters\nconst regexpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// everything has already been escaped, we just have to join\nconst rangesToString = (ranges: string[]): string => ranges.join('')\n\nexport type ParseClassResult = [\n  src: string,\n  uFlag: boolean,\n  consumed: number,\n  hasMagic: boolean\n]\n\n// takes a glob string at a posix brace expression, and returns\n// an equivalent regular expression source, and boolean indicating\n// whether the /u flag needs to be applied, and the number of chars\n// consumed to parse the character class.\n// This also removes out of order ranges, and returns ($.) if the\n// entire class just no good.\nexport const parseClass = (\n  glob: string,\n  position: number\n): ParseClassResult => {\n  const pos = position\n  /* c8 ignore start */\n  if (glob.charAt(pos) !== '[') {\n    throw new Error('not in a brace expression')\n  }\n  /* c8 ignore stop */\n  const ranges: string[] = []\n  const negs: string[] = []\n\n  let i = pos + 1\n  let sawStart = false\n  let uflag = false\n  let escaping = false\n  let negate = false\n  let endPos = pos\n  let rangeStart = ''\n  WHILE: while (i < glob.length) {\n    const c = glob.charAt(i)\n    if ((c === '!' || c === '^') && i === pos + 1) {\n      negate = true\n      i++\n      continue\n    }\n\n    if (c === ']' && sawStart && !escaping) {\n      endPos = i + 1\n      break\n    }\n\n    sawStart = true\n    if (c === '\\\\') {\n      if (!escaping) {\n        escaping = true\n        i++\n        continue\n      }\n      // escaped \\ char, fall through and treat like normal char\n    }\n    if (c === '[' && !escaping) {\n      // either a posix class, a collation equivalent, or just a [\n      for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {\n        if (glob.startsWith(cls, i)) {\n          // invalid, [a-[] is fine, but not [a-[:alpha]]\n          if (rangeStart) {\n            return ['$.', false, glob.length - pos, true]\n          }\n          i += cls.length\n          if (neg) negs.push(unip)\n          else ranges.push(unip)\n          uflag = uflag || u\n          continue WHILE\n        }\n      }\n    }\n\n    // now it's just a normal character, effectively\n    escaping = false\n    if (rangeStart) {\n      // throw this range away if it's not valid, but others\n      // can still match.\n      if (c > rangeStart) {\n        ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c))\n      } else if (c === rangeStart) {\n        ranges.push(braceEscape(c))\n      }\n      rangeStart = ''\n      i++\n      continue\n    }\n\n    // now might be the start of a range.\n    // can be either c-d or c-] or c] or c] at this point\n    if (glob.startsWith('-]', i + 1)) {\n      ranges.push(braceEscape(c + '-'))\n      i += 2\n      continue\n    }\n    if (glob.startsWith('-', i + 1)) {\n      rangeStart = c\n      i += 2\n      continue\n    }\n\n    // not the start of a range, just a single character\n    ranges.push(braceEscape(c))\n    i++\n  }\n\n  if (endPos < i) {\n    // didn't see the end of the class, not a valid class,\n    // but might still be valid as a literal match.\n    return ['', false, 0, false]\n  }\n\n  // if we got no ranges and no negates, then we have a range that\n  // cannot possibly match anything, and that poisons the whole glob\n  if (!ranges.length && !negs.length) {\n    return ['$.', false, glob.length - pos, true]\n  }\n\n  // if we got one positive range, and it's a single character, then that's\n  // not actually a magic pattern, it's just that one literal character.\n  // we should not treat that as \"magic\", we should just return the literal\n  // character. [_] is a perfectly valid way to escape glob magic chars.\n  if (\n    negs.length === 0 &&\n    ranges.length === 1 &&\n    /^\\\\?.$/.test(ranges[0]) &&\n    !negate\n  ) {\n    const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]\n    return [regexpEscape(r), false, endPos - pos, false]\n  }\n\n  const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'\n  const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'\n  const comb =\n    ranges.length && negs.length\n      ? '(' + sranges + '|' + snegs + ')'\n      : ranges.length\n      ? sranges\n      : snegs\n\n  return [comb, uflag, endPos - pos, true]\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.d.ts b/backend/node_modules/minimatch/dist/esm/escape.d.ts
new file mode 100644
index 00000000..dc3e3163
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/escape.d.ts
@@ -0,0 +1,12 @@
+import { MinimatchOptions } from './index.js';
+/**
+ * Escape all magic characters in a glob pattern.
+ *
+ * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
+ * option is used, then characters are escaped by wrapping in `[]`, because
+ * a magic character wrapped in a character class can only be satisfied by
+ * that exact character.  In this mode, `\` is _not_ escaped, because it is
+ * not interpreted as a magic character, but instead as a path separator.
+ */
+export declare const escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
+//# sourceMappingURL=escape.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.d.ts.map b/backend/node_modules/minimatch/dist/esm/escape.d.ts.map
new file mode 100644
index 00000000..0779dae7
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/escape.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,MACd,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAQlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.js b/backend/node_modules/minimatch/dist/esm/escape.js
new file mode 100644
index 00000000..16f7c8c7
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/escape.js
@@ -0,0 +1,18 @@
+/**
+ * Escape all magic characters in a glob pattern.
+ *
+ * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
+ * option is used, then characters are escaped by wrapping in `[]`, because
+ * a magic character wrapped in a character class can only be satisfied by
+ * that exact character.  In this mode, `\` is _not_ escaped, because it is
+ * not interpreted as a magic character, but instead as a path separator.
+ */
+export const escape = (s, { windowsPathsNoEscape = false, } = {}) => {
+    // don't need to escape +@! because we escape the parens
+    // that make those magic, and escaping ! as [!] isn't valid,
+    // because [!]] is a valid glob class meaning not ']'.
+    return windowsPathsNoEscape
+        ? s.replace(/[?*()[\]]/g, '[$&]')
+        : s.replace(/[?*()[\]\\]/g, '\\$&');
+};
+//# sourceMappingURL=escape.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.js.map b/backend/node_modules/minimatch/dist/esm/escape.js.map
new file mode 100644
index 00000000..170fd1ad
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/escape.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character.  In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n */\nexport const escape = (\n  s: string,\n  {\n    windowsPathsNoEscape = false,\n  }: Pick = {}\n) => {\n  // don't need to escape +@! because we escape the parens\n  // that make those magic, and escaping ! as [!] isn't valid,\n  // because [!]] is a valid glob class meaning not ']'.\n  return windowsPathsNoEscape\n    ? s.replace(/[?*()[\\]]/g, '[$&]')\n    : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.d.ts b/backend/node_modules/minimatch/dist/esm/index.d.ts
new file mode 100644
index 00000000..41d16a98
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/index.d.ts
@@ -0,0 +1,94 @@
+import { AST } from './ast.js';
+type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd';
+export interface MinimatchOptions {
+    nobrace?: boolean;
+    nocomment?: boolean;
+    nonegate?: boolean;
+    debug?: boolean;
+    noglobstar?: boolean;
+    noext?: boolean;
+    nonull?: boolean;
+    windowsPathsNoEscape?: boolean;
+    allowWindowsEscape?: boolean;
+    partial?: boolean;
+    dot?: boolean;
+    nocase?: boolean;
+    nocaseMagicOnly?: boolean;
+    magicalBraces?: boolean;
+    matchBase?: boolean;
+    flipNegate?: boolean;
+    preserveMultipleSlashes?: boolean;
+    optimizationLevel?: number;
+    platform?: Platform;
+    windowsNoMagicRoot?: boolean;
+}
+export declare const minimatch: {
+    (p: string, pattern: string, options?: MinimatchOptions): boolean;
+    sep: Sep;
+    GLOBSTAR: typeof GLOBSTAR;
+    filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean;
+    defaults: (def: MinimatchOptions) => typeof minimatch;
+    braceExpand: (pattern: string, options?: MinimatchOptions) => string[];
+    makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp;
+    match: (list: string[], pattern: string, options?: MinimatchOptions) => string[];
+    AST: typeof AST;
+    Minimatch: typeof Minimatch;
+    escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
+    unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
+};
+type Sep = '\\' | '/';
+export declare const sep: Sep;
+export declare const GLOBSTAR: unique symbol;
+export declare const filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean;
+export declare const defaults: (def: MinimatchOptions) => typeof minimatch;
+export declare const braceExpand: (pattern: string, options?: MinimatchOptions) => string[];
+export declare const makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp;
+export declare const match: (list: string[], pattern: string, options?: MinimatchOptions) => string[];
+export type MMRegExp = RegExp & {
+    _src?: string;
+    _glob?: string;
+};
+export type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR;
+export type ParseReturn = ParseReturnFiltered | false;
+export declare class Minimatch {
+    options: MinimatchOptions;
+    set: ParseReturnFiltered[][];
+    pattern: string;
+    windowsPathsNoEscape: boolean;
+    nonegate: boolean;
+    negate: boolean;
+    comment: boolean;
+    empty: boolean;
+    preserveMultipleSlashes: boolean;
+    partial: boolean;
+    globSet: string[];
+    globParts: string[][];
+    nocase: boolean;
+    isWindows: boolean;
+    platform: Platform;
+    windowsNoMagicRoot: boolean;
+    regexp: false | null | MMRegExp;
+    constructor(pattern: string, options?: MinimatchOptions);
+    hasMagic(): boolean;
+    debug(..._: any[]): void;
+    make(): void;
+    preprocess(globParts: string[][]): string[][];
+    adjascentGlobstarOptimize(globParts: string[][]): string[][];
+    levelOneOptimize(globParts: string[][]): string[][];
+    levelTwoFileOptimize(parts: string | string[]): string[];
+    firstPhasePreProcess(globParts: string[][]): string[][];
+    secondPhasePreProcess(globParts: string[][]): string[][];
+    partsMatch(a: string[], b: string[], emptyGSMatch?: boolean): false | string[];
+    parseNegate(): void;
+    matchOne(file: string[], pattern: ParseReturn[], partial?: boolean): boolean;
+    braceExpand(): string[];
+    parse(pattern: string): ParseReturn;
+    makeRe(): false | MMRegExp;
+    slashSplit(p: string): string[];
+    match(f: string, partial?: boolean): boolean;
+    static defaults(def: MinimatchOptions): typeof Minimatch;
+}
+export { AST } from './ast.js';
+export { escape } from './escape.js';
+export { unescape } from './unescape.js';
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.d.ts.map b/backend/node_modules/minimatch/dist/esm/index.d.ts.map
new file mode 100644
index 00000000..195491d8
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/index.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.js b/backend/node_modules/minimatch/dist/esm/index.js
new file mode 100644
index 00000000..84b577b0
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/index.js
@@ -0,0 +1,1001 @@
+import expand from 'brace-expansion';
+import { assertValidPattern } from './assert-valid-pattern.js';
+import { AST } from './ast.js';
+import { escape } from './escape.js';
+import { unescape } from './unescape.js';
+export const minimatch = (p, pattern, options = {}) => {
+    assertValidPattern(pattern);
+    // shortcut: comments match nothing.
+    if (!options.nocomment && pattern.charAt(0) === '#') {
+        return false;
+    }
+    return new Minimatch(pattern, options).match(p);
+};
+// Optimized checking for the most common glob patterns.
+const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
+const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext);
+const starDotExtTestDot = (ext) => (f) => f.endsWith(ext);
+const starDotExtTestNocase = (ext) => {
+    ext = ext.toLowerCase();
+    return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext);
+};
+const starDotExtTestNocaseDot = (ext) => {
+    ext = ext.toLowerCase();
+    return (f) => f.toLowerCase().endsWith(ext);
+};
+const starDotStarRE = /^\*+\.\*+$/;
+const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.');
+const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.');
+const dotStarRE = /^\.\*+$/;
+const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.');
+const starRE = /^\*+$/;
+const starTest = (f) => f.length !== 0 && !f.startsWith('.');
+const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..';
+const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
+const qmarksTestNocase = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExt([$0]);
+    if (!ext)
+        return noext;
+    ext = ext.toLowerCase();
+    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
+};
+const qmarksTestNocaseDot = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExtDot([$0]);
+    if (!ext)
+        return noext;
+    ext = ext.toLowerCase();
+    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
+};
+const qmarksTestDot = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExtDot([$0]);
+    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
+};
+const qmarksTest = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExt([$0]);
+    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
+};
+const qmarksTestNoExt = ([$0]) => {
+    const len = $0.length;
+    return (f) => f.length === len && !f.startsWith('.');
+};
+const qmarksTestNoExtDot = ([$0]) => {
+    const len = $0.length;
+    return (f) => f.length === len && f !== '.' && f !== '..';
+};
+/* c8 ignore start */
+const defaultPlatform = (typeof process === 'object' && process
+    ? (typeof process.env === 'object' &&
+        process.env &&
+        process.env.__MINIMATCH_TESTING_PLATFORM__) ||
+        process.platform
+    : 'posix');
+const path = {
+    win32: { sep: '\\' },
+    posix: { sep: '/' },
+};
+/* c8 ignore stop */
+export const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep;
+minimatch.sep = sep;
+export const GLOBSTAR = Symbol('globstar **');
+minimatch.GLOBSTAR = GLOBSTAR;
+// any single thing other than /
+// don't need to escape / when using new RegExp()
+const qmark = '[^/]';
+// * => any number of characters
+const star = qmark + '*?';
+// ** when dots are allowed.  Anything goes, except .. and .
+// not (^ or / followed by one or two dots followed by $ or /),
+// followed by anything, any number of times.
+const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?';
+// not a ^ or / followed by a dot,
+// followed by anything, any number of times.
+const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?';
+export const filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
+minimatch.filter = filter;
+const ext = (a, b = {}) => Object.assign({}, a, b);
+export const defaults = (def) => {
+    if (!def || typeof def !== 'object' || !Object.keys(def).length) {
+        return minimatch;
+    }
+    const orig = minimatch;
+    const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
+    return Object.assign(m, {
+        Minimatch: class Minimatch extends orig.Minimatch {
+            constructor(pattern, options = {}) {
+                super(pattern, ext(def, options));
+            }
+            static defaults(options) {
+                return orig.defaults(ext(def, options)).Minimatch;
+            }
+        },
+        AST: class AST extends orig.AST {
+            /* c8 ignore start */
+            constructor(type, parent, options = {}) {
+                super(type, parent, ext(def, options));
+            }
+            /* c8 ignore stop */
+            static fromGlob(pattern, options = {}) {
+                return orig.AST.fromGlob(pattern, ext(def, options));
+            }
+        },
+        unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
+        escape: (s, options = {}) => orig.escape(s, ext(def, options)),
+        filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
+        defaults: (options) => orig.defaults(ext(def, options)),
+        makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
+        braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
+        match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
+        sep: orig.sep,
+        GLOBSTAR: GLOBSTAR,
+    });
+};
+minimatch.defaults = defaults;
+// Brace expansion:
+// a{b,c}d -> abd acd
+// a{b,}c -> abc ac
+// a{0..3}d -> a0d a1d a2d a3d
+// a{b,c{d,e}f}g -> abg acdfg acefg
+// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
+//
+// Invalid sets are not expanded.
+// a{2..}b -> a{2..}b
+// a{b}c -> a{b}c
+export const braceExpand = (pattern, options = {}) => {
+    assertValidPattern(pattern);
+    // Thanks to Yeting Li  for
+    // improving this regexp to avoid a ReDOS vulnerability.
+    if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
+        // shortcut. no need to expand.
+        return [pattern];
+    }
+    return expand(pattern);
+};
+minimatch.braceExpand = braceExpand;
+// parse a component of the expanded set.
+// At this point, no pattern may contain "/" in it
+// so we're going to return a 2d array, where each entry is the full
+// pattern, split on '/', and then turned into a regular expression.
+// A regexp is made at the end which joins each array with an
+// escaped /, and another full one which joins each regexp with |.
+//
+// Following the lead of Bash 4.1, note that "**" only has special meaning
+// when it is the *only* thing in a path portion.  Otherwise, any series
+// of * is equivalent to a single *.  Globstar behavior is enabled by
+// default, and can be disabled by setting options.noglobstar.
+export const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
+minimatch.makeRe = makeRe;
+export const match = (list, pattern, options = {}) => {
+    const mm = new Minimatch(pattern, options);
+    list = list.filter(f => mm.match(f));
+    if (mm.options.nonull && !list.length) {
+        list.push(pattern);
+    }
+    return list;
+};
+minimatch.match = match;
+// replace stuff like \* with *
+const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
+const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+export class Minimatch {
+    options;
+    set;
+    pattern;
+    windowsPathsNoEscape;
+    nonegate;
+    negate;
+    comment;
+    empty;
+    preserveMultipleSlashes;
+    partial;
+    globSet;
+    globParts;
+    nocase;
+    isWindows;
+    platform;
+    windowsNoMagicRoot;
+    regexp;
+    constructor(pattern, options = {}) {
+        assertValidPattern(pattern);
+        options = options || {};
+        this.options = options;
+        this.pattern = pattern;
+        this.platform = options.platform || defaultPlatform;
+        this.isWindows = this.platform === 'win32';
+        this.windowsPathsNoEscape =
+            !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
+        if (this.windowsPathsNoEscape) {
+            this.pattern = this.pattern.replace(/\\/g, '/');
+        }
+        this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
+        this.regexp = null;
+        this.negate = false;
+        this.nonegate = !!options.nonegate;
+        this.comment = false;
+        this.empty = false;
+        this.partial = !!options.partial;
+        this.nocase = !!this.options.nocase;
+        this.windowsNoMagicRoot =
+            options.windowsNoMagicRoot !== undefined
+                ? options.windowsNoMagicRoot
+                : !!(this.isWindows && this.nocase);
+        this.globSet = [];
+        this.globParts = [];
+        this.set = [];
+        // make the set of regexps etc.
+        this.make();
+    }
+    hasMagic() {
+        if (this.options.magicalBraces && this.set.length > 1) {
+            return true;
+        }
+        for (const pattern of this.set) {
+            for (const part of pattern) {
+                if (typeof part !== 'string')
+                    return true;
+            }
+        }
+        return false;
+    }
+    debug(..._) { }
+    make() {
+        const pattern = this.pattern;
+        const options = this.options;
+        // empty patterns and comments match nothing.
+        if (!options.nocomment && pattern.charAt(0) === '#') {
+            this.comment = true;
+            return;
+        }
+        if (!pattern) {
+            this.empty = true;
+            return;
+        }
+        // step 1: figure out negation, etc.
+        this.parseNegate();
+        // step 2: expand braces
+        this.globSet = [...new Set(this.braceExpand())];
+        if (options.debug) {
+            this.debug = (...args) => console.error(...args);
+        }
+        this.debug(this.pattern, this.globSet);
+        // step 3: now we have a set, so turn each one into a series of
+        // path-portion matching patterns.
+        // These will be regexps, except in the case of "**", which is
+        // set to the GLOBSTAR object for globstar behavior,
+        // and will not contain any / characters
+        //
+        // First, we preprocess to make the glob pattern sets a bit simpler
+        // and deduped.  There are some perf-killing patterns that can cause
+        // problems with a glob walk, but we can simplify them down a bit.
+        const rawGlobParts = this.globSet.map(s => this.slashSplit(s));
+        this.globParts = this.preprocess(rawGlobParts);
+        this.debug(this.pattern, this.globParts);
+        // glob --> regexps
+        let set = this.globParts.map((s, _, __) => {
+            if (this.isWindows && this.windowsNoMagicRoot) {
+                // check if it's a drive or unc path.
+                const isUNC = s[0] === '' &&
+                    s[1] === '' &&
+                    (s[2] === '?' || !globMagic.test(s[2])) &&
+                    !globMagic.test(s[3]);
+                const isDrive = /^[a-z]:/i.test(s[0]);
+                if (isUNC) {
+                    return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))];
+                }
+                else if (isDrive) {
+                    return [s[0], ...s.slice(1).map(ss => this.parse(ss))];
+                }
+            }
+            return s.map(ss => this.parse(ss));
+        });
+        this.debug(this.pattern, set);
+        // filter out everything that didn't compile properly.
+        this.set = set.filter(s => s.indexOf(false) === -1);
+        // do not treat the ? in UNC paths as magic
+        if (this.isWindows) {
+            for (let i = 0; i < this.set.length; i++) {
+                const p = this.set[i];
+                if (p[0] === '' &&
+                    p[1] === '' &&
+                    this.globParts[i][2] === '?' &&
+                    typeof p[3] === 'string' &&
+                    /^[a-z]:$/i.test(p[3])) {
+                    p[2] = '?';
+                }
+            }
+        }
+        this.debug(this.pattern, this.set);
+    }
+    // various transforms to equivalent pattern sets that are
+    // faster to process in a filesystem walk.  The goal is to
+    // eliminate what we can, and push all ** patterns as far
+    // to the right as possible, even if it increases the number
+    // of patterns that we have to process.
+    preprocess(globParts) {
+        // if we're not in globstar mode, then turn all ** into *
+        if (this.options.noglobstar) {
+            for (let i = 0; i < globParts.length; i++) {
+                for (let j = 0; j < globParts[i].length; j++) {
+                    if (globParts[i][j] === '**') {
+                        globParts[i][j] = '*';
+                    }
+                }
+            }
+        }
+        const { optimizationLevel = 1 } = this.options;
+        if (optimizationLevel >= 2) {
+            // aggressive optimization for the purpose of fs walking
+            globParts = this.firstPhasePreProcess(globParts);
+            globParts = this.secondPhasePreProcess(globParts);
+        }
+        else if (optimizationLevel >= 1) {
+            // just basic optimizations to remove some .. parts
+            globParts = this.levelOneOptimize(globParts);
+        }
+        else {
+            // just collapse multiple ** portions into one
+            globParts = this.adjascentGlobstarOptimize(globParts);
+        }
+        return globParts;
+    }
+    // just get rid of adjascent ** portions
+    adjascentGlobstarOptimize(globParts) {
+        return globParts.map(parts => {
+            let gs = -1;
+            while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
+                let i = gs;
+                while (parts[i + 1] === '**') {
+                    i++;
+                }
+                if (i !== gs) {
+                    parts.splice(gs, i - gs);
+                }
+            }
+            return parts;
+        });
+    }
+    // get rid of adjascent ** and resolve .. portions
+    levelOneOptimize(globParts) {
+        return globParts.map(parts => {
+            parts = parts.reduce((set, part) => {
+                const prev = set[set.length - 1];
+                if (part === '**' && prev === '**') {
+                    return set;
+                }
+                if (part === '..') {
+                    if (prev && prev !== '..' && prev !== '.' && prev !== '**') {
+                        set.pop();
+                        return set;
+                    }
+                }
+                set.push(part);
+                return set;
+            }, []);
+            return parts.length === 0 ? [''] : parts;
+        });
+    }
+    levelTwoFileOptimize(parts) {
+        if (!Array.isArray(parts)) {
+            parts = this.slashSplit(parts);
+        }
+        let didSomething = false;
+        do {
+            didSomething = false;
+            // 
// -> 
/
+            if (!this.preserveMultipleSlashes) {
+                for (let i = 1; i < parts.length - 1; i++) {
+                    const p = parts[i];
+                    // don't squeeze out UNC patterns
+                    if (i === 1 && p === '' && parts[0] === '')
+                        continue;
+                    if (p === '.' || p === '') {
+                        didSomething = true;
+                        parts.splice(i, 1);
+                        i--;
+                    }
+                }
+                if (parts[0] === '.' &&
+                    parts.length === 2 &&
+                    (parts[1] === '.' || parts[1] === '')) {
+                    didSomething = true;
+                    parts.pop();
+                }
+            }
+            // 
/

/../ ->

/
+            let dd = 0;
+            while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                const p = parts[dd - 1];
+                if (p && p !== '.' && p !== '..' && p !== '**') {
+                    didSomething = true;
+                    parts.splice(dd - 1, 2);
+                    dd -= 2;
+                }
+            }
+        } while (didSomething);
+        return parts.length === 0 ? [''] : parts;
+    }
+    // First phase: single-pattern processing
+    // 
 is 1 or more portions
+    //  is 1 or more portions
+    // 

is any portion other than ., .., '', or ** + // is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + //

// -> 
/
+    // 
/

/../ ->

/
+    // **/**/ -> **/
+    //
+    // **/*/ -> */**/ <== not valid because ** doesn't follow
+    // this WOULD be allowed if ** did follow symlinks, or * didn't
+    firstPhasePreProcess(globParts) {
+        let didSomething = false;
+        do {
+            didSomething = false;
+            // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + for (let parts of globParts) { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let gss = gs; + while (parts[gss + 1] === '**') { + //

/**/**/ -> 
/**/
+                        gss++;
+                    }
+                    // eg, if gs is 2 and gss is 4, that means we have 3 **
+                    // parts, and can remove 2 of them.
+                    if (gss > gs) {
+                        parts.splice(gs + 1, gss - gs);
+                    }
+                    let next = parts[gs + 1];
+                    const p = parts[gs + 2];
+                    const p2 = parts[gs + 3];
+                    if (next !== '..')
+                        continue;
+                    if (!p ||
+                        p === '.' ||
+                        p === '..' ||
+                        !p2 ||
+                        p2 === '.' ||
+                        p2 === '..') {
+                        continue;
+                    }
+                    didSomething = true;
+                    // edit parts in place, and push the new one
+                    parts.splice(gs, 1);
+                    const other = parts.slice(0);
+                    other[gs] = '**';
+                    globParts.push(other);
+                    gs--;
+                }
+                // 
// -> 
/
+                if (!this.preserveMultipleSlashes) {
+                    for (let i = 1; i < parts.length - 1; i++) {
+                        const p = parts[i];
+                        // don't squeeze out UNC patterns
+                        if (i === 1 && p === '' && parts[0] === '')
+                            continue;
+                        if (p === '.' || p === '') {
+                            didSomething = true;
+                            parts.splice(i, 1);
+                            i--;
+                        }
+                    }
+                    if (parts[0] === '.' &&
+                        parts.length === 2 &&
+                        (parts[1] === '.' || parts[1] === '')) {
+                        didSomething = true;
+                        parts.pop();
+                    }
+                }
+                // 
/

/../ ->

/
+                let dd = 0;
+                while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                    const p = parts[dd - 1];
+                    if (p && p !== '.' && p !== '..' && p !== '**') {
+                        didSomething = true;
+                        const needDot = dd === 1 && parts[dd + 1] === '**';
+                        const splin = needDot ? ['.'] : [];
+                        parts.splice(dd - 1, 2, ...splin);
+                        if (parts.length === 0)
+                            parts.push('');
+                        dd -= 2;
+                    }
+                }
+            }
+        } while (didSomething);
+        return globParts;
+    }
+    // second phase: multi-pattern dedupes
+    // {
/*/,
/

/} ->

/*/
+    // {
/,
/} -> 
/
+    // {
/**/,
/} -> 
/**/
+    //
+    // {
/**/,
/**/

/} ->

/**/
+    // ^-- not valid because ** doens't follow symlinks
+    secondPhasePreProcess(globParts) {
+        for (let i = 0; i < globParts.length - 1; i++) {
+            for (let j = i + 1; j < globParts.length; j++) {
+                const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
+                if (matched) {
+                    globParts[i] = [];
+                    globParts[j] = matched;
+                    break;
+                }
+            }
+        }
+        return globParts.filter(gs => gs.length);
+    }
+    partsMatch(a, b, emptyGSMatch = false) {
+        let ai = 0;
+        let bi = 0;
+        let result = [];
+        let which = '';
+        while (ai < a.length && bi < b.length) {
+            if (a[ai] === b[bi]) {
+                result.push(which === 'b' ? b[bi] : a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
+                result.push(a[ai]);
+                ai++;
+            }
+            else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
+                result.push(b[bi]);
+                bi++;
+            }
+            else if (a[ai] === '*' &&
+                b[bi] &&
+                (this.options.dot || !b[bi].startsWith('.')) &&
+                b[bi] !== '**') {
+                if (which === 'b')
+                    return false;
+                which = 'a';
+                result.push(a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (b[bi] === '*' &&
+                a[ai] &&
+                (this.options.dot || !a[ai].startsWith('.')) &&
+                a[ai] !== '**') {
+                if (which === 'a')
+                    return false;
+                which = 'b';
+                result.push(b[bi]);
+                ai++;
+                bi++;
+            }
+            else {
+                return false;
+            }
+        }
+        // if we fall out of the loop, it means they two are identical
+        // as long as their lengths match
+        return a.length === b.length && result;
+    }
+    parseNegate() {
+        if (this.nonegate)
+            return;
+        const pattern = this.pattern;
+        let negate = false;
+        let negateOffset = 0;
+        for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
+            negate = !negate;
+            negateOffset++;
+        }
+        if (negateOffset)
+            this.pattern = pattern.slice(negateOffset);
+        this.negate = negate;
+    }
+    // set partial to true to test if, for example,
+    // "/a/b" matches the start of "/*/b/*/d"
+    // Partial means, if you run out of file before you run
+    // out of pattern, then that's fine, as long as all
+    // the parts match.
+    matchOne(file, pattern, partial = false) {
+        const options = this.options;
+        // UNC paths like //?/X:/... can match X:/... and vice versa
+        // Drive letters in absolute drive or unc paths are always compared
+        // case-insensitively.
+        if (this.isWindows) {
+            const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
+            const fileUNC = !fileDrive &&
+                file[0] === '' &&
+                file[1] === '' &&
+                file[2] === '?' &&
+                /^[a-z]:$/i.test(file[3]);
+            const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
+            const patternUNC = !patternDrive &&
+                pattern[0] === '' &&
+                pattern[1] === '' &&
+                pattern[2] === '?' &&
+                typeof pattern[3] === 'string' &&
+                /^[a-z]:$/i.test(pattern[3]);
+            const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
+            const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
+            if (typeof fdi === 'number' && typeof pdi === 'number') {
+                const [fd, pd] = [file[fdi], pattern[pdi]];
+                if (fd.toLowerCase() === pd.toLowerCase()) {
+                    pattern[pdi] = fd;
+                    if (pdi > fdi) {
+                        pattern = pattern.slice(pdi);
+                    }
+                    else if (fdi > pdi) {
+                        file = file.slice(fdi);
+                    }
+                }
+            }
+        }
+        // resolve and reduce . and .. portions in the file as well.
+        // dont' need to do the second phase, because it's only one string[]
+        const { optimizationLevel = 1 } = this.options;
+        if (optimizationLevel >= 2) {
+            file = this.levelTwoFileOptimize(file);
+        }
+        this.debug('matchOne', this, { file, pattern });
+        this.debug('matchOne', file.length, pattern.length);
+        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
+            this.debug('matchOne loop');
+            var p = pattern[pi];
+            var f = file[fi];
+            this.debug(pattern, p, f);
+            // should be impossible.
+            // some invalid regexp stuff in the set.
+            /* c8 ignore start */
+            if (p === false) {
+                return false;
+            }
+            /* c8 ignore stop */
+            if (p === GLOBSTAR) {
+                this.debug('GLOBSTAR', [pattern, p, f]);
+                // "**"
+                // a/**/b/**/c would match the following:
+                // a/b/x/y/z/c
+                // a/x/y/z/b/c
+                // a/b/x/b/x/c
+                // a/b/c
+                // To do this, take the rest of the pattern after
+                // the **, and see if it would match the file remainder.
+                // If so, return success.
+                // If not, the ** "swallows" a segment, and try again.
+                // This is recursively awful.
+                //
+                // a/**/b/**/c matching a/b/x/y/z/c
+                // - a matches a
+                // - doublestar
+                //   - matchOne(b/x/y/z/c, b/**/c)
+                //     - b matches b
+                //     - doublestar
+                //       - matchOne(x/y/z/c, c) -> no
+                //       - matchOne(y/z/c, c) -> no
+                //       - matchOne(z/c, c) -> no
+                //       - matchOne(c, c) yes, hit
+                var fr = fi;
+                var pr = pi + 1;
+                if (pr === pl) {
+                    this.debug('** at the end');
+                    // a ** at the end will just swallow the rest.
+                    // We have found a match.
+                    // however, it will not swallow /.x, unless
+                    // options.dot is set.
+                    // . and .. are *never* matched by **, for explosively
+                    // exponential reasons.
+                    for (; fi < fl; fi++) {
+                        if (file[fi] === '.' ||
+                            file[fi] === '..' ||
+                            (!options.dot && file[fi].charAt(0) === '.'))
+                            return false;
+                    }
+                    return true;
+                }
+                // ok, let's see if we can swallow whatever we can.
+                while (fr < fl) {
+                    var swallowee = file[fr];
+                    this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
+                    // XXX remove this slice.  Just pass the start index.
+                    if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
+                        this.debug('globstar found match!', fr, fl, swallowee);
+                        // found a match.
+                        return true;
+                    }
+                    else {
+                        // can't swallow "." or ".." ever.
+                        // can only swallow ".foo" when explicitly asked.
+                        if (swallowee === '.' ||
+                            swallowee === '..' ||
+                            (!options.dot && swallowee.charAt(0) === '.')) {
+                            this.debug('dot detected!', file, fr, pattern, pr);
+                            break;
+                        }
+                        // ** swallows a segment, and continue.
+                        this.debug('globstar swallow a segment, and continue');
+                        fr++;
+                    }
+                }
+                // no match was found.
+                // However, in partial mode, we can't say this is necessarily over.
+                /* c8 ignore start */
+                if (partial) {
+                    // ran out of file
+                    this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
+                    if (fr === fl) {
+                        return true;
+                    }
+                }
+                /* c8 ignore stop */
+                return false;
+            }
+            // something other than **
+            // non-magic patterns just have to match exactly
+            // patterns with magic have been turned into regexps.
+            let hit;
+            if (typeof p === 'string') {
+                hit = f === p;
+                this.debug('string match', p, f, hit);
+            }
+            else {
+                hit = p.test(f);
+                this.debug('pattern match', p, f, hit);
+            }
+            if (!hit)
+                return false;
+        }
+        // Note: ending in / means that we'll get a final ""
+        // at the end of the pattern.  This can only match a
+        // corresponding "" at the end of the file.
+        // If the file ends in /, then it can only match a
+        // a pattern that ends in /, unless the pattern just
+        // doesn't have any more for it. But, a/b/ should *not*
+        // match "a/b/*", even though "" matches against the
+        // [^/]*? pattern, except in partial mode, where it might
+        // simply not be reached yet.
+        // However, a/b/ should still satisfy a/*
+        // now either we fell off the end of the pattern, or we're done.
+        if (fi === fl && pi === pl) {
+            // ran out of pattern and filename at the same time.
+            // an exact hit!
+            return true;
+        }
+        else if (fi === fl) {
+            // ran out of file, but still had pattern left.
+            // this is ok if we're doing the match as part of
+            // a glob fs traversal.
+            return partial;
+        }
+        else if (pi === pl) {
+            // ran out of pattern, still have file left.
+            // this is only acceptable if we're on the very last
+            // empty segment of a file with a trailing slash.
+            // a/* should match a/b/
+            return fi === fl - 1 && file[fi] === '';
+            /* c8 ignore start */
+        }
+        else {
+            // should be unreachable.
+            throw new Error('wtf?');
+        }
+        /* c8 ignore stop */
+    }
+    braceExpand() {
+        return braceExpand(this.pattern, this.options);
+    }
+    parse(pattern) {
+        assertValidPattern(pattern);
+        const options = this.options;
+        // shortcuts
+        if (pattern === '**')
+            return GLOBSTAR;
+        if (pattern === '')
+            return '';
+        // far and away, the most common glob pattern parts are
+        // *, *.*, and *.  Add a fast check method for those.
+        let m;
+        let fastTest = null;
+        if ((m = pattern.match(starRE))) {
+            fastTest = options.dot ? starTestDot : starTest;
+        }
+        else if ((m = pattern.match(starDotExtRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? starDotExtTestNocaseDot
+                    : starDotExtTestNocase
+                : options.dot
+                    ? starDotExtTestDot
+                    : starDotExtTest)(m[1]);
+        }
+        else if ((m = pattern.match(qmarksRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? qmarksTestNocaseDot
+                    : qmarksTestNocase
+                : options.dot
+                    ? qmarksTestDot
+                    : qmarksTest)(m);
+        }
+        else if ((m = pattern.match(starDotStarRE))) {
+            fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
+        }
+        else if ((m = pattern.match(dotStarRE))) {
+            fastTest = dotStarTest;
+        }
+        const re = AST.fromGlob(pattern, this.options).toMMPattern();
+        if (fastTest && typeof re === 'object') {
+            // Avoids overriding in frozen environments
+            Reflect.defineProperty(re, 'test', { value: fastTest });
+        }
+        return re;
+    }
+    makeRe() {
+        if (this.regexp || this.regexp === false)
+            return this.regexp;
+        // at this point, this.set is a 2d array of partial
+        // pattern strings, or "**".
+        //
+        // It's better to use .match().  This function shouldn't
+        // be used, really, but it's pretty convenient sometimes,
+        // when you just want to work with a regex.
+        const set = this.set;
+        if (!set.length) {
+            this.regexp = false;
+            return this.regexp;
+        }
+        const options = this.options;
+        const twoStar = options.noglobstar
+            ? star
+            : options.dot
+                ? twoStarDot
+                : twoStarNoDot;
+        const flags = new Set(options.nocase ? ['i'] : []);
+        // regexpify non-globstar patterns
+        // if ** is only item, then we just do one twoStar
+        // if ** is first, and there are more, prepend (\/|twoStar\/)? to next
+        // if ** is last, append (\/twoStar|) to previous
+        // if ** is in the middle, append (\/|\/twoStar\/) to previous
+        // then filter out GLOBSTAR symbols
+        let re = set
+            .map(pattern => {
+            const pp = pattern.map(p => {
+                if (p instanceof RegExp) {
+                    for (const f of p.flags.split(''))
+                        flags.add(f);
+                }
+                return typeof p === 'string'
+                    ? regExpEscape(p)
+                    : p === GLOBSTAR
+                        ? GLOBSTAR
+                        : p._src;
+            });
+            pp.forEach((p, i) => {
+                const next = pp[i + 1];
+                const prev = pp[i - 1];
+                if (p !== GLOBSTAR || prev === GLOBSTAR) {
+                    return;
+                }
+                if (prev === undefined) {
+                    if (next !== undefined && next !== GLOBSTAR) {
+                        pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next;
+                    }
+                    else {
+                        pp[i] = twoStar;
+                    }
+                }
+                else if (next === undefined) {
+                    pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
+                }
+                else if (next !== GLOBSTAR) {
+                    pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
+                    pp[i + 1] = GLOBSTAR;
+                }
+            });
+            return pp.filter(p => p !== GLOBSTAR).join('/');
+        })
+            .join('|');
+        // need to wrap in parens if we had more than one thing with |,
+        // otherwise only the first will be anchored to ^ and the last to $
+        const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
+        // must match entire pattern
+        // ending in a * or ** will make it less strict.
+        re = '^' + open + re + close + '$';
+        // can match anything, as long as it's not this.
+        if (this.negate)
+            re = '^(?!' + re + ').+$';
+        try {
+            this.regexp = new RegExp(re, [...flags].join(''));
+            /* c8 ignore start */
+        }
+        catch (ex) {
+            // should be impossible
+            this.regexp = false;
+        }
+        /* c8 ignore stop */
+        return this.regexp;
+    }
+    slashSplit(p) {
+        // if p starts with // on windows, we preserve that
+        // so that UNC paths aren't broken.  Otherwise, any number of
+        // / characters are coalesced into one, unless
+        // preserveMultipleSlashes is set to true.
+        if (this.preserveMultipleSlashes) {
+            return p.split('/');
+        }
+        else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
+            // add an extra '' for the one we lose
+            return ['', ...p.split(/\/+/)];
+        }
+        else {
+            return p.split(/\/+/);
+        }
+    }
+    match(f, partial = this.partial) {
+        this.debug('match', f, this.pattern);
+        // short-circuit in the case of busted things.
+        // comments, etc.
+        if (this.comment) {
+            return false;
+        }
+        if (this.empty) {
+            return f === '';
+        }
+        if (f === '/' && partial) {
+            return true;
+        }
+        const options = this.options;
+        // windows: need to use /, not \
+        if (this.isWindows) {
+            f = f.split('\\').join('/');
+        }
+        // treat the test path as a set of pathparts.
+        const ff = this.slashSplit(f);
+        this.debug(this.pattern, 'split', ff);
+        // just ONE of the pattern sets in this.set needs to match
+        // in order for it to be valid.  If negating, then just one
+        // match means that we have failed.
+        // Either way, return on the first hit.
+        const set = this.set;
+        this.debug(this.pattern, 'set', set);
+        // Find the basename of the path by looking for the last non-empty segment
+        let filename = ff[ff.length - 1];
+        if (!filename) {
+            for (let i = ff.length - 2; !filename && i >= 0; i--) {
+                filename = ff[i];
+            }
+        }
+        for (let i = 0; i < set.length; i++) {
+            const pattern = set[i];
+            let file = ff;
+            if (options.matchBase && pattern.length === 1) {
+                file = [filename];
+            }
+            const hit = this.matchOne(file, pattern, partial);
+            if (hit) {
+                if (options.flipNegate) {
+                    return true;
+                }
+                return !this.negate;
+            }
+        }
+        // didn't get any hits.  this is success if it's a negative
+        // pattern, failure otherwise.
+        if (options.flipNegate) {
+            return false;
+        }
+        return this.negate;
+    }
+    static defaults(def) {
+        return minimatch.defaults(def).Minimatch;
+    }
+}
+/* c8 ignore start */
+export { AST } from './ast.js';
+export { escape } from './escape.js';
+export { unescape } from './unescape.js';
+/* c8 ignore stop */
+minimatch.AST = AST;
+minimatch.Minimatch = Minimatch;
+minimatch.escape = escape;
+minimatch.unescape = unescape;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.js.map b/backend/node_modules/minimatch/dist/esm/index.js.map
new file mode 100644
index 00000000..ff82a0d3
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import expand from 'brace-expansion'\nimport { assertValidPattern } from './assert-valid-pattern.js'\nimport { AST, ExtglobType } from './ast.js'\nimport { escape } from './escape.js'\nimport { unescape } from './unescape.js'\n\ntype Platform =\n  | 'aix'\n  | 'android'\n  | 'darwin'\n  | 'freebsd'\n  | 'haiku'\n  | 'linux'\n  | 'openbsd'\n  | 'sunos'\n  | 'win32'\n  | 'cygwin'\n  | 'netbsd'\n\nexport interface MinimatchOptions {\n  nobrace?: boolean\n  nocomment?: boolean\n  nonegate?: boolean\n  debug?: boolean\n  noglobstar?: boolean\n  noext?: boolean\n  nonull?: boolean\n  windowsPathsNoEscape?: boolean\n  allowWindowsEscape?: boolean\n  partial?: boolean\n  dot?: boolean\n  nocase?: boolean\n  nocaseMagicOnly?: boolean\n  magicalBraces?: boolean\n  matchBase?: boolean\n  flipNegate?: boolean\n  preserveMultipleSlashes?: boolean\n  optimizationLevel?: number\n  platform?: Platform\n  windowsNoMagicRoot?: boolean\n}\n\nexport const minimatch = (\n  p: string,\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // shortcut: comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    return false\n  }\n\n  return new Minimatch(pattern, options).match(p)\n}\n\n// Optimized checking for the most common glob patterns.\nconst starDotExtRE = /^\\*+([^+@!?\\*\\[\\(]*)$/\nconst starDotExtTest = (ext: string) => (f: string) =>\n  !f.startsWith('.') && f.endsWith(ext)\nconst starDotExtTestDot = (ext: string) => (f: string) => f.endsWith(ext)\nconst starDotExtTestNocase = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => !f.startsWith('.') && f.toLowerCase().endsWith(ext)\n}\nconst starDotExtTestNocaseDot = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => f.toLowerCase().endsWith(ext)\n}\nconst starDotStarRE = /^\\*+\\.\\*+$/\nconst starDotStarTest = (f: string) => !f.startsWith('.') && f.includes('.')\nconst starDotStarTestDot = (f: string) =>\n  f !== '.' && f !== '..' && f.includes('.')\nconst dotStarRE = /^\\.\\*+$/\nconst dotStarTest = (f: string) => f !== '.' && f !== '..' && f.startsWith('.')\nconst starRE = /^\\*+$/\nconst starTest = (f: string) => f.length !== 0 && !f.startsWith('.')\nconst starTestDot = (f: string) => f.length !== 0 && f !== '.' && f !== '..'\nconst qmarksRE = /^\\?+([^+@!?\\*\\[\\(]*)?$/\nconst qmarksTestNocase = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestNocaseDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTest = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTestNoExt = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && !f.startsWith('.')\n}\nconst qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && f !== '.' && f !== '..'\n}\n\n/* c8 ignore start */\nconst defaultPlatform: Platform = (\n  typeof process === 'object' && process\n    ? (typeof process.env === 'object' &&\n        process.env &&\n        process.env.__MINIMATCH_TESTING_PLATFORM__) ||\n      process.platform\n    : 'posix'\n) as Platform\ntype Sep = '\\\\' | '/'\nconst path: { [k: string]: { sep: Sep } } = {\n  win32: { sep: '\\\\' },\n  posix: { sep: '/' },\n}\n/* c8 ignore stop */\n\nexport const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep\nminimatch.sep = sep\n\nexport const GLOBSTAR = Symbol('globstar **')\nminimatch.GLOBSTAR = GLOBSTAR\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n\n// ** when dots are allowed.  Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nconst twoStarDot = '(?:(?!(?:\\\\/|^)(?:\\\\.{1,2})($|\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nconst twoStarNoDot = '(?:(?!(?:\\\\/|^)\\\\.).)*?'\n\nexport const filter =\n  (pattern: string, options: MinimatchOptions = {}) =>\n  (p: string) =>\n    minimatch(p, pattern, options)\nminimatch.filter = filter\n\nconst ext = (a: MinimatchOptions, b: MinimatchOptions = {}) =>\n  Object.assign({}, a, b)\n\nexport const defaults = (def: MinimatchOptions): typeof minimatch => {\n  if (!def || typeof def !== 'object' || !Object.keys(def).length) {\n    return minimatch\n  }\n\n  const orig = minimatch\n\n  const m = (p: string, pattern: string, options: MinimatchOptions = {}) =>\n    orig(p, pattern, ext(def, options))\n\n  return Object.assign(m, {\n    Minimatch: class Minimatch extends orig.Minimatch {\n      constructor(pattern: string, options: MinimatchOptions = {}) {\n        super(pattern, ext(def, options))\n      }\n      static defaults(options: MinimatchOptions) {\n        return orig.defaults(ext(def, options)).Minimatch\n      }\n    },\n\n    AST: class AST extends orig.AST {\n      /* c8 ignore start */\n      constructor(\n        type: ExtglobType | null,\n        parent?: AST,\n        options: MinimatchOptions = {}\n      ) {\n        super(type, parent, ext(def, options))\n      }\n      /* c8 ignore stop */\n\n      static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n        return orig.AST.fromGlob(pattern, ext(def, options))\n      }\n    },\n\n    unescape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.unescape(s, ext(def, options)),\n\n    escape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.escape(s, ext(def, options)),\n\n    filter: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.filter(pattern, ext(def, options)),\n\n    defaults: (options: MinimatchOptions) => orig.defaults(ext(def, options)),\n\n    makeRe: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.makeRe(pattern, ext(def, options)),\n\n    braceExpand: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.braceExpand(pattern, ext(def, options)),\n\n    match: (list: string[], pattern: string, options: MinimatchOptions = {}) =>\n      orig.match(list, pattern, ext(def, options)),\n\n    sep: orig.sep,\n    GLOBSTAR: GLOBSTAR as typeof GLOBSTAR,\n  })\n}\nminimatch.defaults = defaults\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nexport const braceExpand = (\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // Thanks to Yeting Li  for\n  // improving this regexp to avoid a ReDOS vulnerability.\n  if (options.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(pattern)) {\n    // shortcut. no need to expand.\n    return [pattern]\n  }\n\n  return expand(pattern)\n}\nminimatch.braceExpand = braceExpand\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion.  Otherwise, any series\n// of * is equivalent to a single *.  Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\n\nexport const makeRe = (pattern: string, options: MinimatchOptions = {}) =>\n  new Minimatch(pattern, options).makeRe()\nminimatch.makeRe = makeRe\n\nexport const match = (\n  list: string[],\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  const mm = new Minimatch(pattern, options)\n  list = list.filter(f => mm.match(f))\n  if (mm.options.nonull && !list.length) {\n    list.push(pattern)\n  }\n  return list\n}\nminimatch.match = match\n\n// replace stuff like \\* with *\nconst globMagic = /[?*]|[+@!]\\(.*?\\)|\\[|\\]/\nconst regExpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\nexport type MMRegExp = RegExp & {\n  _src?: string\n  _glob?: string\n}\n\nexport type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR\nexport type ParseReturn = ParseReturnFiltered | false\n\nexport class Minimatch {\n  options: MinimatchOptions\n  set: ParseReturnFiltered[][]\n  pattern: string\n\n  windowsPathsNoEscape: boolean\n  nonegate: boolean\n  negate: boolean\n  comment: boolean\n  empty: boolean\n  preserveMultipleSlashes: boolean\n  partial: boolean\n  globSet: string[]\n  globParts: string[][]\n  nocase: boolean\n\n  isWindows: boolean\n  platform: Platform\n  windowsNoMagicRoot: boolean\n\n  regexp: false | null | MMRegExp\n  constructor(pattern: string, options: MinimatchOptions = {}) {\n    assertValidPattern(pattern)\n\n    options = options || {}\n    this.options = options\n    this.pattern = pattern\n    this.platform = options.platform || defaultPlatform\n    this.isWindows = this.platform === 'win32'\n    this.windowsPathsNoEscape =\n      !!options.windowsPathsNoEscape || options.allowWindowsEscape === false\n    if (this.windowsPathsNoEscape) {\n      this.pattern = this.pattern.replace(/\\\\/g, '/')\n    }\n    this.preserveMultipleSlashes = !!options.preserveMultipleSlashes\n    this.regexp = null\n    this.negate = false\n    this.nonegate = !!options.nonegate\n    this.comment = false\n    this.empty = false\n    this.partial = !!options.partial\n    this.nocase = !!this.options.nocase\n    this.windowsNoMagicRoot =\n      options.windowsNoMagicRoot !== undefined\n        ? options.windowsNoMagicRoot\n        : !!(this.isWindows && this.nocase)\n\n    this.globSet = []\n    this.globParts = []\n    this.set = []\n\n    // make the set of regexps etc.\n    this.make()\n  }\n\n  hasMagic(): boolean {\n    if (this.options.magicalBraces && this.set.length > 1) {\n      return true\n    }\n    for (const pattern of this.set) {\n      for (const part of pattern) {\n        if (typeof part !== 'string') return true\n      }\n    }\n    return false\n  }\n\n  debug(..._: any[]) {}\n\n  make() {\n    const pattern = this.pattern\n    const options = this.options\n\n    // empty patterns and comments match nothing.\n    if (!options.nocomment && pattern.charAt(0) === '#') {\n      this.comment = true\n      return\n    }\n\n    if (!pattern) {\n      this.empty = true\n      return\n    }\n\n    // step 1: figure out negation, etc.\n    this.parseNegate()\n\n    // step 2: expand braces\n    this.globSet = [...new Set(this.braceExpand())]\n\n    if (options.debug) {\n      this.debug = (...args: any[]) => console.error(...args)\n    }\n\n    this.debug(this.pattern, this.globSet)\n\n    // step 3: now we have a set, so turn each one into a series of\n    // path-portion matching patterns.\n    // These will be regexps, except in the case of \"**\", which is\n    // set to the GLOBSTAR object for globstar behavior,\n    // and will not contain any / characters\n    //\n    // First, we preprocess to make the glob pattern sets a bit simpler\n    // and deduped.  There are some perf-killing patterns that can cause\n    // problems with a glob walk, but we can simplify them down a bit.\n    const rawGlobParts = this.globSet.map(s => this.slashSplit(s))\n    this.globParts = this.preprocess(rawGlobParts)\n    this.debug(this.pattern, this.globParts)\n\n    // glob --> regexps\n    let set = this.globParts.map((s, _, __) => {\n      if (this.isWindows && this.windowsNoMagicRoot) {\n        // check if it's a drive or unc path.\n        const isUNC =\n          s[0] === '' &&\n          s[1] === '' &&\n          (s[2] === '?' || !globMagic.test(s[2])) &&\n          !globMagic.test(s[3])\n        const isDrive = /^[a-z]:/i.test(s[0])\n        if (isUNC) {\n          return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]\n        } else if (isDrive) {\n          return [s[0], ...s.slice(1).map(ss => this.parse(ss))]\n        }\n      }\n      return s.map(ss => this.parse(ss))\n    })\n\n    this.debug(this.pattern, set)\n\n    // filter out everything that didn't compile properly.\n    this.set = set.filter(\n      s => s.indexOf(false) === -1\n    ) as ParseReturnFiltered[][]\n\n    // do not treat the ? in UNC paths as magic\n    if (this.isWindows) {\n      for (let i = 0; i < this.set.length; i++) {\n        const p = this.set[i]\n        if (\n          p[0] === '' &&\n          p[1] === '' &&\n          this.globParts[i][2] === '?' &&\n          typeof p[3] === 'string' &&\n          /^[a-z]:$/i.test(p[3])\n        ) {\n          p[2] = '?'\n        }\n      }\n    }\n\n    this.debug(this.pattern, this.set)\n  }\n\n  // various transforms to equivalent pattern sets that are\n  // faster to process in a filesystem walk.  The goal is to\n  // eliminate what we can, and push all ** patterns as far\n  // to the right as possible, even if it increases the number\n  // of patterns that we have to process.\n  preprocess(globParts: string[][]) {\n    // if we're not in globstar mode, then turn all ** into *\n    if (this.options.noglobstar) {\n      for (let i = 0; i < globParts.length; i++) {\n        for (let j = 0; j < globParts[i].length; j++) {\n          if (globParts[i][j] === '**') {\n            globParts[i][j] = '*'\n          }\n        }\n      }\n    }\n\n    const { optimizationLevel = 1 } = this.options\n\n    if (optimizationLevel >= 2) {\n      // aggressive optimization for the purpose of fs walking\n      globParts = this.firstPhasePreProcess(globParts)\n      globParts = this.secondPhasePreProcess(globParts)\n    } else if (optimizationLevel >= 1) {\n      // just basic optimizations to remove some .. parts\n      globParts = this.levelOneOptimize(globParts)\n    } else {\n      // just collapse multiple ** portions into one\n      globParts = this.adjascentGlobstarOptimize(globParts)\n    }\n\n    return globParts\n  }\n\n  // just get rid of adjascent ** portions\n  adjascentGlobstarOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      let gs: number = -1\n      while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n        let i = gs\n        while (parts[i + 1] === '**') {\n          i++\n        }\n        if (i !== gs) {\n          parts.splice(gs, i - gs)\n        }\n      }\n      return parts\n    })\n  }\n\n  // get rid of adjascent ** and resolve .. portions\n  levelOneOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      parts = parts.reduce((set: string[], part) => {\n        const prev = set[set.length - 1]\n        if (part === '**' && prev === '**') {\n          return set\n        }\n        if (part === '..') {\n          if (prev && prev !== '..' && prev !== '.' && prev !== '**') {\n            set.pop()\n            return set\n          }\n        }\n        set.push(part)\n        return set\n      }, [])\n      return parts.length === 0 ? [''] : parts\n    })\n  }\n\n  levelTwoFileOptimize(parts: string | string[]) {\n    if (!Array.isArray(parts)) {\n      parts = this.slashSplit(parts)\n    }\n    let didSomething: boolean = false\n    do {\n      didSomething = false\n      // 
// -> 
/\n      if (!this.preserveMultipleSlashes) {\n        for (let i = 1; i < parts.length - 1; i++) {\n          const p = parts[i]\n          // don't squeeze out UNC patterns\n          if (i === 1 && p === '' && parts[0] === '') continue\n          if (p === '.' || p === '') {\n            didSomething = true\n            parts.splice(i, 1)\n            i--\n          }\n        }\n        if (\n          parts[0] === '.' &&\n          parts.length === 2 &&\n          (parts[1] === '.' || parts[1] === '')\n        ) {\n          didSomething = true\n          parts.pop()\n        }\n      }\n\n      // 
/

/../ ->

/\n      let dd: number = 0\n      while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n        const p = parts[dd - 1]\n        if (p && p !== '.' && p !== '..' && p !== '**') {\n          didSomething = true\n          parts.splice(dd - 1, 2)\n          dd -= 2\n        }\n      }\n    } while (didSomething)\n    return parts.length === 0 ? [''] : parts\n  }\n\n  // First phase: single-pattern processing\n  // 
 is 1 or more portions\n  //  is 1 or more portions\n  // 

is any portion other than ., .., '', or **\n // is . or ''\n //\n // **/.. is *brutal* for filesystem walking performance, because\n // it effectively resets the recursive walk each time it occurs,\n // and ** cannot be reduced out by a .. pattern part like a regexp\n // or most strings (other than .., ., and '') can be.\n //\n //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n //

// -> 
/\n  // 
/

/../ ->

/\n  // **/**/ -> **/\n  //\n  // **/*/ -> */**/ <== not valid because ** doesn't follow\n  // this WOULD be allowed if ** did follow symlinks, or * didn't\n  firstPhasePreProcess(globParts: string[][]) {\n    let didSomething = false\n    do {\n      didSomething = false\n      // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n for (let parts of globParts) {\n let gs: number = -1\n while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n let gss: number = gs\n while (parts[gss + 1] === '**') {\n //

/**/**/ -> 
/**/\n            gss++\n          }\n          // eg, if gs is 2 and gss is 4, that means we have 3 **\n          // parts, and can remove 2 of them.\n          if (gss > gs) {\n            parts.splice(gs + 1, gss - gs)\n          }\n\n          let next = parts[gs + 1]\n          const p = parts[gs + 2]\n          const p2 = parts[gs + 3]\n          if (next !== '..') continue\n          if (\n            !p ||\n            p === '.' ||\n            p === '..' ||\n            !p2 ||\n            p2 === '.' ||\n            p2 === '..'\n          ) {\n            continue\n          }\n          didSomething = true\n          // edit parts in place, and push the new one\n          parts.splice(gs, 1)\n          const other = parts.slice(0)\n          other[gs] = '**'\n          globParts.push(other)\n          gs--\n        }\n\n        // 
// -> 
/\n        if (!this.preserveMultipleSlashes) {\n          for (let i = 1; i < parts.length - 1; i++) {\n            const p = parts[i]\n            // don't squeeze out UNC patterns\n            if (i === 1 && p === '' && parts[0] === '') continue\n            if (p === '.' || p === '') {\n              didSomething = true\n              parts.splice(i, 1)\n              i--\n            }\n          }\n          if (\n            parts[0] === '.' &&\n            parts.length === 2 &&\n            (parts[1] === '.' || parts[1] === '')\n          ) {\n            didSomething = true\n            parts.pop()\n          }\n        }\n\n        // 
/

/../ ->

/\n        let dd: number = 0\n        while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n          const p = parts[dd - 1]\n          if (p && p !== '.' && p !== '..' && p !== '**') {\n            didSomething = true\n            const needDot = dd === 1 && parts[dd + 1] === '**'\n            const splin = needDot ? ['.'] : []\n            parts.splice(dd - 1, 2, ...splin)\n            if (parts.length === 0) parts.push('')\n            dd -= 2\n          }\n        }\n      }\n    } while (didSomething)\n\n    return globParts\n  }\n\n  // second phase: multi-pattern dedupes\n  // {
/*/,
/

/} ->

/*/\n  // {
/,
/} -> 
/\n  // {
/**/,
/} -> 
/**/\n  //\n  // {
/**/,
/**/

/} ->

/**/\n  // ^-- not valid because ** doens't follow symlinks\n  secondPhasePreProcess(globParts: string[][]): string[][] {\n    for (let i = 0; i < globParts.length - 1; i++) {\n      for (let j = i + 1; j < globParts.length; j++) {\n        const matched = this.partsMatch(\n          globParts[i],\n          globParts[j],\n          !this.preserveMultipleSlashes\n        )\n        if (matched) {\n          globParts[i] = []\n          globParts[j] = matched\n          break\n        }\n      }\n    }\n    return globParts.filter(gs => gs.length)\n  }\n\n  partsMatch(\n    a: string[],\n    b: string[],\n    emptyGSMatch: boolean = false\n  ): false | string[] {\n    let ai = 0\n    let bi = 0\n    let result: string[] = []\n    let which: string = ''\n    while (ai < a.length && bi < b.length) {\n      if (a[ai] === b[bi]) {\n        result.push(which === 'b' ? b[bi] : a[ai])\n        ai++\n        bi++\n      } else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {\n        result.push(a[ai])\n        ai++\n      } else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {\n        result.push(b[bi])\n        bi++\n      } else if (\n        a[ai] === '*' &&\n        b[bi] &&\n        (this.options.dot || !b[bi].startsWith('.')) &&\n        b[bi] !== '**'\n      ) {\n        if (which === 'b') return false\n        which = 'a'\n        result.push(a[ai])\n        ai++\n        bi++\n      } else if (\n        b[bi] === '*' &&\n        a[ai] &&\n        (this.options.dot || !a[ai].startsWith('.')) &&\n        a[ai] !== '**'\n      ) {\n        if (which === 'a') return false\n        which = 'b'\n        result.push(b[bi])\n        ai++\n        bi++\n      } else {\n        return false\n      }\n    }\n    // if we fall out of the loop, it means they two are identical\n    // as long as their lengths match\n    return a.length === b.length && result\n  }\n\n  parseNegate() {\n    if (this.nonegate) return\n\n    const pattern = this.pattern\n    let negate = false\n    let negateOffset = 0\n\n    for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {\n      negate = !negate\n      negateOffset++\n    }\n\n    if (negateOffset) this.pattern = pattern.slice(negateOffset)\n    this.negate = negate\n  }\n\n  // set partial to true to test if, for example,\n  // \"/a/b\" matches the start of \"/*/b/*/d\"\n  // Partial means, if you run out of file before you run\n  // out of pattern, then that's fine, as long as all\n  // the parts match.\n  matchOne(file: string[], pattern: ParseReturn[], partial: boolean = false) {\n    const options = this.options\n\n    // UNC paths like //?/X:/... can match X:/... and vice versa\n    // Drive letters in absolute drive or unc paths are always compared\n    // case-insensitively.\n    if (this.isWindows) {\n      const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0])\n      const fileUNC =\n        !fileDrive &&\n        file[0] === '' &&\n        file[1] === '' &&\n        file[2] === '?' &&\n        /^[a-z]:$/i.test(file[3])\n\n      const patternDrive =\n        typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0])\n      const patternUNC =\n        !patternDrive &&\n        pattern[0] === '' &&\n        pattern[1] === '' &&\n        pattern[2] === '?' &&\n        typeof pattern[3] === 'string' &&\n        /^[a-z]:$/i.test(pattern[3])\n\n      const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined\n      const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined\n      if (typeof fdi === 'number' && typeof pdi === 'number') {\n        const [fd, pd]: [string, string] = [file[fdi], pattern[pdi] as string]\n        if (fd.toLowerCase() === pd.toLowerCase()) {\n          pattern[pdi] = fd\n          if (pdi > fdi) {\n            pattern = pattern.slice(pdi)\n          } else if (fdi > pdi) {\n            file = file.slice(fdi)\n          }\n        }\n      }\n    }\n\n    // resolve and reduce . and .. portions in the file as well.\n    // dont' need to do the second phase, because it's only one string[]\n    const { optimizationLevel = 1 } = this.options\n    if (optimizationLevel >= 2) {\n      file = this.levelTwoFileOptimize(file)\n    }\n\n    this.debug('matchOne', this, { file, pattern })\n    this.debug('matchOne', file.length, pattern.length)\n\n    for (\n      var fi = 0, pi = 0, fl = file.length, pl = pattern.length;\n      fi < fl && pi < pl;\n      fi++, pi++\n    ) {\n      this.debug('matchOne loop')\n      var p = pattern[pi]\n      var f = file[fi]\n\n      this.debug(pattern, p, f)\n\n      // should be impossible.\n      // some invalid regexp stuff in the set.\n      /* c8 ignore start */\n      if (p === false) {\n        return false\n      }\n      /* c8 ignore stop */\n\n      if (p === GLOBSTAR) {\n        this.debug('GLOBSTAR', [pattern, p, f])\n\n        // \"**\"\n        // a/**/b/**/c would match the following:\n        // a/b/x/y/z/c\n        // a/x/y/z/b/c\n        // a/b/x/b/x/c\n        // a/b/c\n        // To do this, take the rest of the pattern after\n        // the **, and see if it would match the file remainder.\n        // If so, return success.\n        // If not, the ** \"swallows\" a segment, and try again.\n        // This is recursively awful.\n        //\n        // a/**/b/**/c matching a/b/x/y/z/c\n        // - a matches a\n        // - doublestar\n        //   - matchOne(b/x/y/z/c, b/**/c)\n        //     - b matches b\n        //     - doublestar\n        //       - matchOne(x/y/z/c, c) -> no\n        //       - matchOne(y/z/c, c) -> no\n        //       - matchOne(z/c, c) -> no\n        //       - matchOne(c, c) yes, hit\n        var fr = fi\n        var pr = pi + 1\n        if (pr === pl) {\n          this.debug('** at the end')\n          // a ** at the end will just swallow the rest.\n          // We have found a match.\n          // however, it will not swallow /.x, unless\n          // options.dot is set.\n          // . and .. are *never* matched by **, for explosively\n          // exponential reasons.\n          for (; fi < fl; fi++) {\n            if (\n              file[fi] === '.' ||\n              file[fi] === '..' ||\n              (!options.dot && file[fi].charAt(0) === '.')\n            )\n              return false\n          }\n          return true\n        }\n\n        // ok, let's see if we can swallow whatever we can.\n        while (fr < fl) {\n          var swallowee = file[fr]\n\n          this.debug('\\nglobstar while', file, fr, pattern, pr, swallowee)\n\n          // XXX remove this slice.  Just pass the start index.\n          if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {\n            this.debug('globstar found match!', fr, fl, swallowee)\n            // found a match.\n            return true\n          } else {\n            // can't swallow \".\" or \"..\" ever.\n            // can only swallow \".foo\" when explicitly asked.\n            if (\n              swallowee === '.' ||\n              swallowee === '..' ||\n              (!options.dot && swallowee.charAt(0) === '.')\n            ) {\n              this.debug('dot detected!', file, fr, pattern, pr)\n              break\n            }\n\n            // ** swallows a segment, and continue.\n            this.debug('globstar swallow a segment, and continue')\n            fr++\n          }\n        }\n\n        // no match was found.\n        // However, in partial mode, we can't say this is necessarily over.\n        /* c8 ignore start */\n        if (partial) {\n          // ran out of file\n          this.debug('\\n>>> no match, partial?', file, fr, pattern, pr)\n          if (fr === fl) {\n            return true\n          }\n        }\n        /* c8 ignore stop */\n        return false\n      }\n\n      // something other than **\n      // non-magic patterns just have to match exactly\n      // patterns with magic have been turned into regexps.\n      let hit: boolean\n      if (typeof p === 'string') {\n        hit = f === p\n        this.debug('string match', p, f, hit)\n      } else {\n        hit = p.test(f)\n        this.debug('pattern match', p, f, hit)\n      }\n\n      if (!hit) return false\n    }\n\n    // Note: ending in / means that we'll get a final \"\"\n    // at the end of the pattern.  This can only match a\n    // corresponding \"\" at the end of the file.\n    // If the file ends in /, then it can only match a\n    // a pattern that ends in /, unless the pattern just\n    // doesn't have any more for it. But, a/b/ should *not*\n    // match \"a/b/*\", even though \"\" matches against the\n    // [^/]*? pattern, except in partial mode, where it might\n    // simply not be reached yet.\n    // However, a/b/ should still satisfy a/*\n\n    // now either we fell off the end of the pattern, or we're done.\n    if (fi === fl && pi === pl) {\n      // ran out of pattern and filename at the same time.\n      // an exact hit!\n      return true\n    } else if (fi === fl) {\n      // ran out of file, but still had pattern left.\n      // this is ok if we're doing the match as part of\n      // a glob fs traversal.\n      return partial\n    } else if (pi === pl) {\n      // ran out of pattern, still have file left.\n      // this is only acceptable if we're on the very last\n      // empty segment of a file with a trailing slash.\n      // a/* should match a/b/\n      return fi === fl - 1 && file[fi] === ''\n\n      /* c8 ignore start */\n    } else {\n      // should be unreachable.\n      throw new Error('wtf?')\n    }\n    /* c8 ignore stop */\n  }\n\n  braceExpand() {\n    return braceExpand(this.pattern, this.options)\n  }\n\n  parse(pattern: string): ParseReturn {\n    assertValidPattern(pattern)\n\n    const options = this.options\n\n    // shortcuts\n    if (pattern === '**') return GLOBSTAR\n    if (pattern === '') return ''\n\n    // far and away, the most common glob pattern parts are\n    // *, *.*, and *.  Add a fast check method for those.\n    let m: RegExpMatchArray | null\n    let fastTest: null | ((f: string) => boolean) = null\n    if ((m = pattern.match(starRE))) {\n      fastTest = options.dot ? starTestDot : starTest\n    } else if ((m = pattern.match(starDotExtRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? starDotExtTestNocaseDot\n            : starDotExtTestNocase\n          : options.dot\n          ? starDotExtTestDot\n          : starDotExtTest\n      )(m[1])\n    } else if ((m = pattern.match(qmarksRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? qmarksTestNocaseDot\n            : qmarksTestNocase\n          : options.dot\n          ? qmarksTestDot\n          : qmarksTest\n      )(m)\n    } else if ((m = pattern.match(starDotStarRE))) {\n      fastTest = options.dot ? starDotStarTestDot : starDotStarTest\n    } else if ((m = pattern.match(dotStarRE))) {\n      fastTest = dotStarTest\n    }\n\n    const re = AST.fromGlob(pattern, this.options).toMMPattern()\n    if (fastTest && typeof re === 'object') {\n      // Avoids overriding in frozen environments\n      Reflect.defineProperty(re, 'test', { value: fastTest })\n    }\n    return re\n  }\n\n  makeRe() {\n    if (this.regexp || this.regexp === false) return this.regexp\n\n    // at this point, this.set is a 2d array of partial\n    // pattern strings, or \"**\".\n    //\n    // It's better to use .match().  This function shouldn't\n    // be used, really, but it's pretty convenient sometimes,\n    // when you just want to work with a regex.\n    const set = this.set\n\n    if (!set.length) {\n      this.regexp = false\n      return this.regexp\n    }\n    const options = this.options\n\n    const twoStar = options.noglobstar\n      ? star\n      : options.dot\n      ? twoStarDot\n      : twoStarNoDot\n    const flags = new Set(options.nocase ? ['i'] : [])\n\n    // regexpify non-globstar patterns\n    // if ** is only item, then we just do one twoStar\n    // if ** is first, and there are more, prepend (\\/|twoStar\\/)? to next\n    // if ** is last, append (\\/twoStar|) to previous\n    // if ** is in the middle, append (\\/|\\/twoStar\\/) to previous\n    // then filter out GLOBSTAR symbols\n    let re = set\n      .map(pattern => {\n        const pp: (string | typeof GLOBSTAR)[] = pattern.map(p => {\n          if (p instanceof RegExp) {\n            for (const f of p.flags.split('')) flags.add(f)\n          }\n          return typeof p === 'string'\n            ? regExpEscape(p)\n            : p === GLOBSTAR\n            ? GLOBSTAR\n            : p._src\n        }) as (string | typeof GLOBSTAR)[]\n        pp.forEach((p, i) => {\n          const next = pp[i + 1]\n          const prev = pp[i - 1]\n          if (p !== GLOBSTAR || prev === GLOBSTAR) {\n            return\n          }\n          if (prev === undefined) {\n            if (next !== undefined && next !== GLOBSTAR) {\n              pp[i + 1] = '(?:\\\\/|' + twoStar + '\\\\/)?' + next\n            } else {\n              pp[i] = twoStar\n            }\n          } else if (next === undefined) {\n            pp[i - 1] = prev + '(?:\\\\/|' + twoStar + ')?'\n          } else if (next !== GLOBSTAR) {\n            pp[i - 1] = prev + '(?:\\\\/|\\\\/' + twoStar + '\\\\/)' + next\n            pp[i + 1] = GLOBSTAR\n          }\n        })\n        return pp.filter(p => p !== GLOBSTAR).join('/')\n      })\n      .join('|')\n\n    // need to wrap in parens if we had more than one thing with |,\n    // otherwise only the first will be anchored to ^ and the last to $\n    const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']\n    // must match entire pattern\n    // ending in a * or ** will make it less strict.\n    re = '^' + open + re + close + '$'\n\n    // can match anything, as long as it's not this.\n    if (this.negate) re = '^(?!' + re + ').+$'\n\n    try {\n      this.regexp = new RegExp(re, [...flags].join(''))\n      /* c8 ignore start */\n    } catch (ex) {\n      // should be impossible\n      this.regexp = false\n    }\n    /* c8 ignore stop */\n    return this.regexp\n  }\n\n  slashSplit(p: string) {\n    // if p starts with // on windows, we preserve that\n    // so that UNC paths aren't broken.  Otherwise, any number of\n    // / characters are coalesced into one, unless\n    // preserveMultipleSlashes is set to true.\n    if (this.preserveMultipleSlashes) {\n      return p.split('/')\n    } else if (this.isWindows && /^\\/\\/[^\\/]+/.test(p)) {\n      // add an extra '' for the one we lose\n      return ['', ...p.split(/\\/+/)]\n    } else {\n      return p.split(/\\/+/)\n    }\n  }\n\n  match(f: string, partial = this.partial) {\n    this.debug('match', f, this.pattern)\n    // short-circuit in the case of busted things.\n    // comments, etc.\n    if (this.comment) {\n      return false\n    }\n    if (this.empty) {\n      return f === ''\n    }\n\n    if (f === '/' && partial) {\n      return true\n    }\n\n    const options = this.options\n\n    // windows: need to use /, not \\\n    if (this.isWindows) {\n      f = f.split('\\\\').join('/')\n    }\n\n    // treat the test path as a set of pathparts.\n    const ff = this.slashSplit(f)\n    this.debug(this.pattern, 'split', ff)\n\n    // just ONE of the pattern sets in this.set needs to match\n    // in order for it to be valid.  If negating, then just one\n    // match means that we have failed.\n    // Either way, return on the first hit.\n\n    const set = this.set\n    this.debug(this.pattern, 'set', set)\n\n    // Find the basename of the path by looking for the last non-empty segment\n    let filename: string = ff[ff.length - 1]\n    if (!filename) {\n      for (let i = ff.length - 2; !filename && i >= 0; i--) {\n        filename = ff[i]\n      }\n    }\n\n    for (let i = 0; i < set.length; i++) {\n      const pattern = set[i]\n      let file = ff\n      if (options.matchBase && pattern.length === 1) {\n        file = [filename]\n      }\n      const hit = this.matchOne(file, pattern, partial)\n      if (hit) {\n        if (options.flipNegate) {\n          return true\n        }\n        return !this.negate\n      }\n    }\n\n    // didn't get any hits.  this is success if it's a negative\n    // pattern, failure otherwise.\n    if (options.flipNegate) {\n      return false\n    }\n    return this.negate\n  }\n\n  static defaults(def: MinimatchOptions) {\n    return minimatch.defaults(def).Minimatch\n  }\n}\n/* c8 ignore start */\nexport { AST } from './ast.js'\nexport { escape } from './escape.js'\nexport { unescape } from './unescape.js'\n/* c8 ignore stop */\nminimatch.AST = AST\nminimatch.Minimatch = Minimatch\nminimatch.escape = escape\nminimatch.unescape = unescape\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/package.json b/backend/node_modules/minimatch/dist/esm/package.json
new file mode 100644
index 00000000..3dbc1ca5
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "module"
+}
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.d.ts b/backend/node_modules/minimatch/dist/esm/unescape.d.ts
new file mode 100644
index 00000000..23a7b387
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/unescape.d.ts
@@ -0,0 +1,17 @@
+import { MinimatchOptions } from './index.js';
+/**
+ * Un-escape a string that has been escaped with {@link escape}.
+ *
+ * If the {@link windowsPathsNoEscape} option is used, then square-brace
+ * escapes are removed, but not backslash escapes.  For example, it will turn
+ * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
+ * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
+ *
+ * When `windowsPathsNoEscape` is not set, then both brace escapes and
+ * backslash escapes are removed.
+ *
+ * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
+ * or unescaped.
+ */
+export declare const unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
+//# sourceMappingURL=unescape.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.d.ts.map b/backend/node_modules/minimatch/dist/esm/unescape.d.ts.map
new file mode 100644
index 00000000..7ace0701
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/unescape.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,MAChB,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAKlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.js b/backend/node_modules/minimatch/dist/esm/unescape.js
new file mode 100644
index 00000000..0faf9a2b
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/unescape.js
@@ -0,0 +1,20 @@
+/**
+ * Un-escape a string that has been escaped with {@link escape}.
+ *
+ * If the {@link windowsPathsNoEscape} option is used, then square-brace
+ * escapes are removed, but not backslash escapes.  For example, it will turn
+ * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
+ * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
+ *
+ * When `windowsPathsNoEscape` is not set, then both brace escapes and
+ * backslash escapes are removed.
+ *
+ * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
+ * or unescaped.
+ */
+export const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
+    return windowsPathsNoEscape
+        ? s.replace(/\[([^\/\\])\]/g, '$1')
+        : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
+};
+//# sourceMappingURL=unescape.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.js.map b/backend/node_modules/minimatch/dist/esm/unescape.js.map
new file mode 100644
index 00000000..eb146c20
--- /dev/null
+++ b/backend/node_modules/minimatch/dist/esm/unescape.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAA","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link windowsPathsNoEscape} option is used, then square-brace\n * escapes are removed, but not backslash escapes.  For example, it will turn\n * the string `'[*]'` into `*`, but it will not turn `'\\\\*'` into `'*'`,\n * becuase `\\` is a path separator in `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both brace escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n */\nexport const unescape = (\n  s: string,\n  {\n    windowsPathsNoEscape = false,\n  }: Pick = {}\n) => {\n  return windowsPathsNoEscape\n    ? s.replace(/\\[([^\\/\\\\])\\]/g, '$1')\n    : s.replace(/((?!\\\\).|^)\\[([^\\/\\\\])\\]/g, '$1$2').replace(/\\\\([^\\/])/g, '$1')\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/package.json b/backend/node_modules/minimatch/package.json
new file mode 100644
index 00000000..01fc48ec
--- /dev/null
+++ b/backend/node_modules/minimatch/package.json
@@ -0,0 +1,82 @@
+{
+  "author": "Isaac Z. Schlueter  (http://blog.izs.me)",
+  "name": "minimatch",
+  "description": "a glob matcher in javascript",
+  "version": "9.0.5",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/minimatch.git"
+  },
+  "main": "./dist/commonjs/index.js",
+  "types": "./dist/commonjs/index.d.ts",
+  "exports": {
+    "./package.json": "./package.json",
+    ".": {
+      "import": {
+        "types": "./dist/esm/index.d.ts",
+        "default": "./dist/esm/index.js"
+      },
+      "require": {
+        "types": "./dist/commonjs/index.d.ts",
+        "default": "./dist/commonjs/index.js"
+      }
+    }
+  },
+  "files": [
+    "dist"
+  ],
+  "scripts": {
+    "preversion": "npm test",
+    "postversion": "npm publish",
+    "prepublishOnly": "git push origin --follow-tags",
+    "prepare": "tshy",
+    "pretest": "npm run prepare",
+    "presnap": "npm run prepare",
+    "test": "tap",
+    "snap": "tap",
+    "format": "prettier --write . --loglevel warn",
+    "benchmark": "node benchmark/index.js",
+    "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts"
+  },
+  "prettier": {
+    "semi": false,
+    "printWidth": 80,
+    "tabWidth": 2,
+    "useTabs": false,
+    "singleQuote": true,
+    "jsxSingleQuote": false,
+    "bracketSameLine": true,
+    "arrowParens": "avoid",
+    "endOfLine": "lf"
+  },
+  "engines": {
+    "node": ">=16 || 14 >=14.17"
+  },
+  "dependencies": {
+    "brace-expansion": "^2.0.1"
+  },
+  "devDependencies": {
+    "@types/brace-expansion": "^1.1.0",
+    "@types/node": "^18.15.11",
+    "@types/tap": "^15.0.8",
+    "eslint-config-prettier": "^8.6.0",
+    "mkdirp": "1",
+    "prettier": "^2.8.2",
+    "tap": "^18.7.2",
+    "ts-node": "^10.9.1",
+    "tshy": "^1.12.0",
+    "typedoc": "^0.23.21",
+    "typescript": "^4.9.3"
+  },
+  "funding": {
+    "url": "https://github.com/sponsors/isaacs"
+  },
+  "license": "ISC",
+  "tshy": {
+    "exports": {
+      "./package.json": "./package.json",
+      ".": "./src/index.ts"
+    }
+  },
+  "type": "module"
+}
diff --git a/backend/node_modules/run/LICENSE b/backend/node_modules/run/LICENSE
new file mode 100644
index 00000000..10457ca6
--- /dev/null
+++ b/backend/node_modules/run/LICENSE
@@ -0,0 +1,18 @@
+Copyright 2011 David Trejo. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/backend/node_modules/run/cli.js b/backend/node_modules/run/cli.js
new file mode 100644
index 00000000..0b5ee4a2
--- /dev/null
+++ b/backend/node_modules/run/cli.js
@@ -0,0 +1,2 @@
+#!/usr/bin/env node
+require('./run.js')
diff --git a/backend/node_modules/run/package.json b/backend/node_modules/run/package.json
new file mode 100644
index 00000000..01cb4ee0
--- /dev/null
+++ b/backend/node_modules/run/package.json
@@ -0,0 +1,26 @@
+{
+  "name": "run",
+  "description": "Reruns the given file whenever a file in the current working dir subtree is changed.",
+  "version": "1.5.0",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/DTrejo/run.js.git"
+  },
+  "author": "David Trejo  (http://dtrejo.com/)",
+  "maintainers": [
+    "David Trejo  (http://dtrejo.com/)"
+  ],
+  "preferGlobal": true,
+  "bin": {
+    "runjs": "./cli.js"
+  },
+  "engines": {
+    "node": ">=v0.9.0"
+  },
+  "dependencies": {
+    "minimatch": "*"
+  },
+  "devDependencies": {},
+  "homepage": "https://github.com/dtrejo/run.js",
+  "optionalDependencies": {}
+}
diff --git a/backend/node_modules/run/readme.md b/backend/node_modules/run/readme.md
new file mode 100644
index 00000000..66ab2323
--- /dev/null
+++ b/backend/node_modules/run/readme.md
@@ -0,0 +1,47 @@
+## Install
+
+`$ npm -g install run`
+
+## Usage
+
+`$ runjs yourcode.js`
+
+# What does it do?
+
+`runjs` will rerun server.js whenever one of the watched files is
+changed. It ignores files in your `.gitignore`.
+
+    $ runjs server.js
+    Watching /Dropbox/dev/server.js and all sub-directories not excluded by your .gitignore
+    Found & ignored file.db ; is dotfile or has ignored extension
+
+    Starting: server.js
+    > Listening on http://localhost:8888/
+
+No more switching to the terminal to rerun your code. Just change a file and
+your code will be rerun.
+
+This is especially nice for web-servers, as you can skip the terminal and
+alt-tab to the browser to see your updated code happily running.
+
+### Features
+- supports globs in .gitignore (e.g. `*.log`)
+- any arguments, including debug arguments, are relayed to your code
+- **stdin is relayed to your code** [not supported by nodemon as of 12/5/11]
+- files and directories in `.gitignore` are not watched, neither are dotfiles.
+- coffeescript is supported: `runjs yourcode.coffee`
+  (by [rockymeza](https://github.com/rockymeza))
+
+Source at [github.com/DTrejo/run.js](https://github.com/DTrejo/run.js)
+
+---
+![Screenshot of runjs](https://github.com/DTrejo/run.js/raw/master/test/screenshot.png)
+
+### Contributors
+Ordered by date of first contribution.
+[Auto-generated](http://github.com/dtrejo/node-authors) on Wed Aug 08 2012 20:27:26 GMT-0700 (PDT).
+
+- [David Trejo aka `DTrejo`](https://github.com/DTrejo)
+- [Rocky Meza aka `rockymeza`](https://github.com/rockymeza)
+- [Shani Elharrar aka `morishani`](https://github.com/morishani)
+- [Andrew Sutherland aka `asuth`](https://github.com/asuth)
diff --git a/backend/node_modules/run/run.js b/backend/node_modules/run/run.js
new file mode 100644
index 00000000..0d3e831b
--- /dev/null
+++ b/backend/node_modules/run/run.js
@@ -0,0 +1,179 @@
+// https://github.com/DTrejo/run.js
+// Used to run code in a directory and rerun it if any files are changed.
+// Usage: ./cli.js servercode.js
+// Where servercode.js is whatever js file you want node to run
+
+// Excludes filetypes in the ignoreExtensions array
+var util = require('util')
+  , fs = require('fs')
+  , path = require('path')
+  , spawn = require('child_process').spawn
+  , { minimatch } = require('minimatch')
+  , child // child process which runs the user's code
+  , ignoreExtensions = ['.dirtydb', '.db', '.styl', '.css']
+  , ignoreFiles = [ 'node_modules' ]
+  // switched out for coffee depending on extension.
+  , node = 'node'
+  , args = process.argv
+  , signal = null
+
+//
+// Tell user the correct usage if they miss-type
+//
+if (args.length <= 2) {
+  console.log('Found ' + (args.length - 2)
+    , 'argument(s). Expected one or more.')
+  console.log(
+    'Usage: \n  runjs [SIGNAL] somecode.js [--args]\n'
+    + 'Ex:  \n  runjs somecode.js --args'
+    + '     \n  runjs SIGUSR2 somecode.js --args\n'
+    )
+  process.exit(1)
+}
+
+//
+// If we define a signal, parse it out and then remove from the array
+//
+if (args[2].match(/^SIG/)) {
+  signal = args.splice(2, 1)[0];
+}
+
+//
+// use `coffee` if the file ends with .coffee
+//
+if (args[2].match(/\.coffee$/)) node = 'coffee'
+
+
+//
+// Exclude files based on .gitignore
+//
+if (fs.existsSync('.gitignore')) {
+  ignoreFiles = ignoreFiles.concat(fs.readFileSync('.gitignore', 'utf8')
+    .split('\n')
+    .filter(function(s) {
+      s = s.trim()
+      return s.indexOf('#') !== 0 && s.length > 0
+    })
+  )
+}
+
+console.log('Watching', path.resolve('./'), 'and all sub-directories not'
+  , 'excluded by your .gitignore. Will not monitor dotfiles.')
+
+watchFiles(parseFolder('.'), restart) // watch all files, restart if problem
+run()
+
+
+process.stdin.setEncoding('utf8')
+
+// executes the command given by the second argument
+;function run() {
+  // run the server
+  var childArgs = args.slice(2) || []
+  child = spawn(node, childArgs)
+
+  // let the child's output escape.
+  child.stdout.on('data', function(data) {
+    process.stdout.write(data)
+  })
+  child.stderr.on('data', function(error) {
+    process.stdout.write(error)
+  })
+
+  // let the user's typing get to the child
+  process.stdin.pipe(child.stdin)
+
+  console.log('\nStarting: ' + childArgs.join(' '))
+}
+
+;function restart() {
+  // kill if running
+  if (child) {
+    if (signal) {
+      child.kill(signal)
+    } else {
+      child.kill()
+      run()
+    }
+  } else {
+    run()
+  }
+}
+
+/**
+* Parses a folder recursively and returns a list of files
+*
+* @param root {String}
+* @return {Array}
+*/
+;function parseFolder(root) {
+  var fileList = []
+    , files = fs.readdirSync(root)
+
+  files.forEach(function(file) {
+    var pathname = path.join(root, file)
+      , stat = fs.lstatSync(pathname)
+
+    if (stat === undefined) return
+
+    // add files to file list
+    if (!stat.isDirectory()) {
+      fileList.push(pathname)
+
+    // recur if directory
+    } else {
+      // don't watch folders matched by .gitignore regexes
+      for (var i = 0, pattern; pattern = ignoreFiles[i]; i++) {
+        if (minimatch(file, pattern)) {
+          console.log('Found & ignored', './' + pathname, '; is listed in .gitignore')
+          return
+        }
+      }
+      fileList = fileList.concat(parseFolder(pathname))
+    }
+  })
+
+  return fileList
+}
+
+
+/**
+* Add change listener to files, which is called whenever one changes.
+* Ignores certain extensions.
+*
+* @param files {Array}
+* @param callback {function}
+*/
+;function watchFiles(files, callback) {
+
+  var config = {  persistent: true, interval: 25 }
+  files.forEach(function (file) {
+
+    // don't watch dotfiles.
+    if (file.indexOf('.') === 0) return
+
+    // don't watch things with ignored extensions
+    var ext = path.extname(file)
+    if (ignoreExtensions.indexOf(ext) !== -1) {
+      console.log('Found & ignored', './' + file, '; has ignored extension')
+      return
+    }
+
+    // don't watch files matched by .gitignore regexes
+    for (var i = 0, pattern; pattern = ignoreFiles[i]; i++) {
+      if (minimatch(file, pattern)) {
+        console.log('Found & ignored', './' + file, '; is listed in .gitignore')
+        return
+      }
+    }
+
+    // if any file changes, run the callback
+    fs.watchFile(file, config, function (curr, prev) {
+
+      if ((curr.mtime + '') != (prev.mtime + '')) {
+        console.log('./' + file + ' changed')
+        if (callback) callback()
+      }
+    })
+  })
+}
diff --git a/backend/node_modules/run/test/runme.js b/backend/node_modules/run/test/runme.js
new file mode 100644
index 00000000..987fd75c
--- /dev/null
+++ b/backend/node_modules/run/test/runme.js
@@ -0,0 +1,28 @@
+var readline = require('readline')
+  , rl = readline.createInterface(process.stdin, process.stdout)
+  , prefix = 'OHAI> '
+
+rl.on('line', function(line) {
+  switch(line.trim()) {
+    case 'hello':
+      console.log('world!')
+      break
+    case 'error':
+        throw new Error('Sample error!')
+      break
+    default:
+      console.log('Say what? I might have heard `' + line.trim() + '`')
+      break
+  }
+  rl.setPrompt(prefix, prefix.length)
+  rl.prompt()
+}).on('close', function() {
+  console.log('Have a great day!')
+  process.exit(0)
+})
+
+console.log(prefix + 'Good to see you. Try typing `hello` or `error`.')
+console.log(prefix + 'My process.argv =', process.argv.join(' '));
+console.log(prefix + 'When you type, this process will get your keystrokes.');
+rl.setPrompt(prefix, prefix.length)
+rl.prompt()
diff --git a/backend/node_modules/run/test/screenshot.png b/backend/node_modules/run/test/screenshot.png
new file mode 100644
index 0000000000000000000000000000000000000000..0405a07cb7641dd378ec87992114fef2d8d2aaf6
GIT binary patch
literal 92481
zcmV)FK)=6x000+PX+uL$Nkc;*
zP;zf(X>4Tx0C)k_d1qJ@%d>aSY+iPkoYRtX&N+i5i4v8ZGfNI4ARs|OKoJ2&K}AFb
zQKBSKP{f0Xf(izLNDvhRf`al6dd~UZ_qq3ed%wK>Jlp%5s_N>RsqUVt8UQ#~yrZJR
zU0A!1>ef(m4!x4M~0NBtsiWUn1Y6GE)G5JT&nGkP_9iLGUdNVD~eh-3$5!@FO
z?_h#pWJN)5l7k$b|Cagc=WqNs9fkvfP0jzvz)Zoh<~wt-AU+oijkMgc0htR{1(qNT
z_=7k=L;46H1FV1%F#fxj0Rg}p;lv}n7!V5HA~+lw5s8e6L@@PlIivqZG5tL*5E=J>
zYor2SL^kf!5Yf8i0ysLvsNcv@%*9ZGhH8Yau)hU<%$Kngjo_aYui6b3lA~WRj*+
z5W?NLcb|W_!0ESi@W0pp%>ocSveLHlj|Bk4`X?g$005)Ns3cl&U{Ea80NJ_z(p2*Z
zUs-9YqP&8_4*UO`wsU6vG4_l7@3RPEd-xw(ByuwvJ7>(n|IoZX0MHhKY*VKH&_vq+
zpjQN7=!9<^E&h)_^v)j!ISuKN70L&{`L4i;N6bGe32cZI}1ge0}LiNx!r~|qM4MC5f=gHv1W+<4b(9gx2IYndK+#ZXsC-lzss?ox)rq=`dW@Pzt)RZ6v1n#A6)l6T(_QF2
zXkTSJA&PWDE~R3ZscJ$GBhuF$tI)Oc~|^rUf&A8OO|H
zzG1OgHmn#{4Z92LiVeZ0U=L$YVH>f1*hkno>>3V-0YqYI`>rz@vxqPs^oL-(D;M3N*Kk@k|}
zNQI<2QXlC#=?j@m7A5PG-N>=zLUKL%Hu)8KgThRarI=IvCM2#&E{NjF%XP7#EpvOrlIC
zOnyvROtnn6ndX>L%tFjY%)ZPAna?o~Fwe7KS;Sb(SwdI}Sgx>)u&lB&u`07Vu_m%s
zvUamhv!U2T+05C(*oxSi*(TV2u=BDTu=}&;v0r5$V_)as=FsQx=g8-1U(7+(+H5cQShY@QAk}VKdg9UIHR4YsuoCJLp%SMgMkQfM70DpUO38;(u#~D)
zu+%B3N75K+4e1E!8tJDpBpCylc$o&78Cf=2E7?rhHrWqy!g6kM#d3G$e#xuIhsmFl
zpHg5_uu#ZU=v4TuD5>bHSgH6#iL7L*bU>+H>65aQvcK|aY-XHqJYvFRvd5&t8hEES&CWTF3c{=UB$ben)90bn%A4J
zTBupE!$p<|Kb)E@CYaeMlm=$-aD)jO>_8#|XcPrJyu>~|S<
z<#G*nZFj@DIk{bMTXQ#YKkh!iS7mR`-idu;`x5sJd2o4zd31ZydwP3b_riENdtLI{
z^0x7=@m}*W_o?z(^)>Q6;rq@{-|v{;lE03BiT^@?PC!Y(VxUf7Y2Z?jUQk)kO0ZFI
zMewJPT_M#W>!CKGb)nl~&S8z=_;9cAjtHiR(1<&ce36NfkD{caa-ycAHKUJ5uhJ}O
z7h<58eKGB^EJ$$pAWl3kJ8mXkH@-4{Bf%-*dLmQ-<1AT
zfz*uDnf(U)&!$0XK56|2gbrjKm`^uLznDSH2+jB_Q$DjK^Xoz9gPmEtS?O7G*=E@d
zIg}h)&eKC$hpKbYxxu+3c}jUF^M2*~<=-!mFDNV6I_!J+{t<;E!zThPZ~M%X=@6UNOGXepTk`*+#a;f+o-u
z*R*`i>)J%KWpn>^_3Kw}h}@`ZVQ$H9g<6wZSKETxrrTZHA9YxC^ml4?w%nAxS=S}d
zRoTtjUDQMD$?DneP3~Rmi|Sjs6?ki|-?M+}w#)4&ckJ$r3|J1_8#Eofeb?Y_?>(J+
zT|=5f9rxAmw+*Wfw?0sL(DIkcUo9i5BdrhB9=4BajCMZKe$+FjH+Ji>@#DcK=1+#l
zcaJ}s*fa6$>E5T)&-|V(J`a2TX)=Ctb1MA>=0*NXhL>fpcwW`KmU!JbtvcO3V?6U<
z)?s#P&UfzJo0vCS^I31nZ_5_=7wQ)k7rT~BmqwS}m*?L_z1v*LdC&O1>Vx=)8z1#Q
zK3H{Go&QApwEg+;7tSwrUzNZ1ui37>`WF6eb3K29bK~N7_3w9oIR9AKOxVJ0mH(9Z
z+4;-z*Ng4&?d>RUn)mNm0EP5$KmY)r>yRA670De&0U%QT&SNgmU0=J+xi9X0zi-jwh3AM@uXm%*Y2PD$$^HQWc7a+!!oif_Zy~Qk
z2gB;ak3>X8Iz*{Ob472_Ud8mq*2ZPW2PBv$N+l7KmXjZ(G^LjB&q_-;5S>oTNY2bZ
zcs8p$`}HA0u6ABjer>_T5n`csQTWl*#Umv@k4YbQFUvpCT0UJtSE*9vc`EO8bM@3&
zbd5}{)42oZFJ5?5w^2{MWYv&*x%tYcM$M+8Yag$>-+0(+)Apo8yEFD?eb{#kpKL4(8CH}p~
z2a}Ids|>4apC&)|d^!6ydoAdj<+|Jk^Tzu37eD$oYqqj}`u{TC7Tn%O{Er1(NOYJ8
z29Su(3OWkChLw=m>kG;gHGxD;FELSA3bqaBkLSWq5~_%SbcQ4yvLhvkKAqtV<1MBo
z7FJecwj}mOj*ncj+%%ppK01CU>Lr0~Ap_wIkzUa)aW#n$$x~9p(w}8n<&@-iDYz>J
zDn%;BMtuRmijZg}6Q$N0KQooTsQ?ydy$APZN^
zT~_MWV!K&w&^BLfXYC%@_c=5BHwD+9GqKT%)CsbukiiCYBaw6weyJkkFBM
zILRYfJ_SyBn%cO(AT9jBo^<03%}kAhI$682U2-B09m+kQcRPQk;MWnJLX9G)qcO!t
zOD>lV9eY~_pWrE1J!w}FURh9e`PAs?Z)XJ0+SVMb?Kt=8f^1#%#T)hO4H}nIuk`u5E`;{!{B>-W$@%=ZO`7kQR4Oy9zAp0S*%
zkU5tnn>B~6fW4HXnzMncox7W-o41Frm%oR4Q=mn#LFkllfk>R_UNL=fK?xu+CD|rb
zAnhbWm06Z;kxQ4iRA5t>QEX6(Q`S=FtiGYqqnWK`sm-K4sZ*mHqNk|0
zr9Ws;Y`D)z(rDfIwn>qxyP25T=UqMK`4&!=0+#QrTCLM}TiLML%-A;A#n@{(zz+8v
zOZK=qQJof?ue!v!YPrE~L+(X;9rm&9d+t%`xzCH&>!tT8pMAbOzLS3C{!RhR0S^NU
zf=q$|vR>jt6+&0S>cV{@cp{!gmPYN4#z)_xCC4bmti+y=^N44Uf0%G6Q7>^LsVO-)
zg_`m__1J#LG|sg71MTU@GLkX_4(`oz&34c6KNOdnomZBBp`i8f;F0md`J%7Is1oK<
z!DI5rHOq`nSd`nHbgl5IjI26vs`T{b>ftjVYeZ_3&W&CWt4q5$aY?2j>+;l9g~r^b
zSIw%|3vRq_Rcbrb{-RUqW`5Ufk9Kc)-?x6p+bsiPgXiwa3=Is2{v|xJGJ1FH+LQW;
zrf0V%U%mvdNd
zZ6W!c9_$0>z?a~M@K+Q!$^aFFI*RH*&7$d$`hgdck+q}WV3;s^m+0c$}{!9}5)!o?yXqNZXZ;w14kiCM`psXNl0GS_9BQeQX^kMyv22+N;Mm5H{CXuEtW`?`u%=s+nEm4*mR;$*_yXS3Y
zZD;J>*uQi5;`q~v;LPqK=BnXl?e4obW#4g+CgeT#-iP9=-(UJ5(TW
z_-dhk(R6WfsmpPl6XquqDhEz;pP|&iwcpQwuKQ5G(y(&nW8>PjpEvNW-0gCm#$B#G
z!F}=lX?M~G_uq@ZANIg&q+qmtYAvUHQ*U1>OlQoF&r2=jE-kE>eYo_A;Y-Te
z`;CAf3qPZNpC9x<7T6)xs0z>v-avFnHNYLpLNfkg=p&NdYr3M-4&IM
zx`ujYnr>1XBRJ;x1aAIzbTbOoe-!Ij1e*w<`do!nGkIgJ0pHVqFAy}s!+N_rb70D
zT#NiYg;$E}%B(7ys=jK4>fIV2wM4W%bt-kI^!W_@3>%F$O-xJ+%!bV|7HXD0Ryo!e
zcHgp@v|Y7FJFq!Q?$LL0b&hc0I*#w~OfdrUuU|3|DVA
zB{s`lUu>ys3+|BV{M^;qli6q0&whJupy_Vvki{_PgVB*a59b~wKjwQfGEwl%VN&!3
z^m6v~;7r3@(L8OzVTpUWdPVI0wU4^1BcDCLd|XRkr{6gFgKx9?C)cl{-~ML@1|SNl
z96bcvi0=cSlh6S41r~(uks3}Lyn@tfT#)@fghnAX#AI|EdJUt3iN|zfF<2XHC3YF7
zg*%E{#2e$!5%7d4!V97mv5!s-@w6f70oj$jOi80>rEg-eVfe&Y#-z)%#C(dyftAd9
zpDmBwii3$`lJh(ljoW~SndcqvAm2Iu9BQb5qo9G1qOh0W40QrcT4
zRklK|TmFqAMM+zkrgByFqq>SlhUS>IxK5VtTYW2oHX|wHbEX1jwdN8QEmp?X&upUX
zNcK&R?#O=ac8zye-n-$^=XJ!#!%sDU6!<*2BGf!=DIzIyD>{}oA8Q+TJ%KTimh>b=
zGxcm5-GRjPg-n-&53&t&I&+otS_^az4;8u=y(>;DWjt0>CU>Iaq;5rTmG-IDYRnm{
zv&U;*pOZYFaADvgYkk0_&dZc5epkDiSg%Dj58n_+GN1SDb{%au`MPqtKlD2H-RhUR
zef-Y$V94DkL;Cj{9=6+7Fv4Bbd000Sa
zNLh0L01FcU01FcV0GgZ_001BWNklEjwMk8Y9eX`MWfh(SW!VyEPxpOvtCNZZ
z^2*fVrK(Q^O|&xgd)0H&2vj*jG^Z9Tpp@vPD_Ru(4n+yMQy-!=859yKAc3ybL>jX%
z5lBXjd@@^kHS)5tdetA+BTzjAsI%GowaHRFN9v##nY=7TyhIj{riUtIs%Rows$|gA
zn0kJV5MbfYI#eM_*TBF)MRR>q9UxGRw22^^VA_jVP&}Owvoco`SS$
z7{juGbqHW`DKxPf>Uc-z{U`E*@cx^vMGLi#04?y}5=H9RNjs%QUK1!(sH=%sP5ah{Yns~dPWaW>F%?S}&FIv+Jo#E$ZCWUn
zu3ItK*CaDOIakYS`0W=j-#og%Tg8d<8C9wyF$!$-TB9@#DEY0*lCGvz^IlseY0B2{
z$7Nv1iR}~m+7cUsu6$*m_(a`d$+v^EWC2mA!1!E99AuF
z)~CIhVQ$XdOl~I=S+Fhgw?r+CM8yRths#i#6bk2l_QeF}+SH^C+5B;?4awS)5f~D?
zV`4u$E#p~b#8%0mE&qh%fB|aSpeCD;qI&xKgFwxf$M?sV_sSBXIU+=78m|ry&94zN
z-K#b#?~f(wdsjo7tKKpF@#iUH+m!$M)O2xlFKdNe1({EeY}@O=*h#($f6jvdzN
zQOVV%Q8mhcxy!+(U#5cn2UDUVm^KD>n?9zq=x)i}RhO7#HS5fL5#*0^so0;qm&hju
z)NoW(n=zoLe`gN|nXx-s8mF2QT3ZISUOcIRy>SK9AEfA3$d?vE4jH?tgEOy5qZUmMb}8BM;nry0X0?eS3#ScrEmbW?K2KS3uC|I=Wh9Y9;b|{3
zsy?2)MyiNdUj8~JYPu8vKX;qs@^2BUA
zzTeI#>yNX4zqOdX>?#k#qiIcP+TTOldNUBWybNZbP`Ks%`MAaac*6g
z1#muyajst0jV^QGWzyx)X@CG~&)C^BS1;P#d
z^Fo+k(-x+Ddg3sNnhLDv|6fLc4x#rM1QOow%2cA4cZ$&_@wUFtkgB!~{Q58RNVUJv
zsyZ>1ZkppJDtq#E;C>_t2kwHjo5Mfc4waD+-~TksKKPRfGh%*$L#-5jECtd1{HJWmHumlIZf1JrL+vTGb+SNL#NyEA4iE-gc-yk_6F
z)RDuOryAK;$ILaxvySckUsFd&gEbAa(CALB5XlYNV7EBz0_R4b^EB)x=X3
zr>z!)Wr%nz0}HwJ66F8tA~?=J}Tj!7ILZDR%$QE|@kEqjMAibs-hH}*>JuGxOuZ%}w&
z2P1?sZzK$ntS4D$S*i7cec#Py(|P2CZu)llz=p4q&Wii|4D!YE<{g?NF1{Ko4%`KY
zq!9Zrua#e92V&sD*-JuwTH1iuy6~?+!MSkPiWvi1ndw2Am47~BPtRGohi^{v*H8b{
zZP8u@PtfWmncNX^)TZo&#chXmGB(Cn;mcBv
zJ)OBG6KwOEApUZQ==b&6Ze#7d?Lm
ztRN?X{}jI!fWKtvm%BrqXq<2F*e35A81m<`o}HWHc!pB)ABD1VfH0Yu1Gy_
z^e@=?_4NKN+4d7_IG9_?vxpB)8@V*e3!Nz;i(&z-Q!YggbQK6!~>AgjO4m0j@
zR}-6QX|(+6NvjXe>fu)3OCtn?6H`gpfBIM`OPj4*#QS>}zK=h6+NL9TsgPCZtf)&IJQt(j?yMN|7i{`&A)
zj;+02yMTlHQe8LV%~H?FVV*4d$O2l<*);ub1Ko(6e&Mkb22S$s)HiW+s$aPMZ;O2G
zQ10fKwm)#y%BYW4~R-9}cX*29C_!Tk{r9^N;$6Srx%
zBBJN-p|O=Nuxh!lpTDpyD=bI)79MRZUz$S}fy>&3g92LUKE9s(_q{?Z2S-mQJqwEd
zK_?T~&is4#9mqK8Vrryk(af?dk`voMpVUM~58QYrm_d*Z*`^@SFH=&k4y7RWo
z)VP(S$gBx|mDsHDO+4)?UZxf#KQ1@7HEz*JWFnKzn(q?S46dz1>Z#LVLbDE(g6FZa
z(ciutz0`MXM;%dq;n~Y&tvj20^mqFD@tZFW7MPmpnHlSk{>&b%dUU76(#6mMGGIoz
zw*JvoiHnb;S!fFs`5;&CR#{nRoeDGKf@y6G0t@uNy@!~dFglVde;iuq0sh4btPq92
zp;JR-p@;DwIvCdV>=HD|LCxjDEIY?mvWrlTU%sV;H(hJ4+{o%Zm#p>M#{ze
zMV9ssG|r@z_4&iLFT&jA-t}2Hr4QAdzE|cE9uM(`XV&W{(WhQ{1$uRyIPt)}yTdo8
z)AE_)$duEUnl&IPZBK=Giu^_nh(m~T<~-E^2ONhK4#S4DRmS0%iCIH;pFya+ptzz@
z*TBW_Ev~r2)X`;v1U;L!32S`)e*0pz3)VVis7bFRl%dF&4P((#P=Uqqr$!a
zStTGbIWe`cOZ!Gr2|6R^$lfw$>f9LTxZH1S^z!svW}iiY(_ilHVkh`kM>F`GE-$%Q_UxFPYl>5!G?KL~M}
z54&ZuuG6xQNhKkDhJBF`daSS4&_L;|#5jaJ77pxUC3_YdOT!VlrYGRD>$7iZm5Ncx
z{xRfZz~Nl}YA-!Kln2=xF7hDGBS)}XD6ibuy{&V2EE0!jUg%-x-b~TV^EYnQ8Xuxw
z9F}>3q&mRn@9F@9_~!3@+b3*DgJVUMST(m1!NuehY7bUn8zRpVJvjIv!L8+35A^2B
z<4^B2-a1;(#J)vXH(gPA(e7zU5velNqUGT&4UM6jtbwx)NG(e_`DocedW#u7+xQ^W
zN#B3CV`saH8wWB@XCb`VmiiL4XdVn%X<@VmgGT7!LpY*J$&n>D
z)+d;5JmKC@7c69!*J-bikEO0{6PYZvL9wr{-pf3LeHBF$tV*0sOE$WjtWH7H-Xh(H
z_KT*#5HsVD##zpwfSsn_-1Aewl#_t}(}ZpW|M=BEv|mlJi^HBK^ioLncd>`89pgN4
zW4eMU`1hy(Y)NWm(Q9VNfad7zy1fT85d>RSQar@lRLDy6AB=YX0*{Pj`pf7pT}Spt
z8*lQ;f5Wn`zzMv8Q2@fiK~{M#BF;;+&(+sThT7Z^Fq`w>fov9
z#q(DY@R~L8a4Y5xZMh1`yxsprMB*cHkXdKBK$=*9z+s&s!?cZM2Fuj<$tn>s8-!tJyVsotY{G)3%?xES||JL@yU!-k8Y(ZVsB>?
zQE~Q_cscp(s+Ck;n6~MQ{R_T37Z}h4_TDb+`%B&&nQ*IEBr-OF?J`KCvMxm9tQ1O2
z63}&RZDHezmp()x2b{&&u1X;Py
zpXZE_^YZbokatBbIz;us@{q^;IQF8dp}>LK!h05_f1?s0Yb8bj=K5>$dC>!L3rDNL2oI
z`<5(ILr4lsexLu$!VG7JdhN^shbL#B;j9#jg$S}Rs$?ZxE`j!LAA7|9?!9qE%b*sR
zoO=C5baX~0&QvQhECA6a!^A3NqvZIwh{)))JTSW?H8v)4W6Xw)F?%5#
z6!8|BvGdi7T`v!HmB$;p6mt^pre(_)ltU?}a%$6@D-rbafn4&
zV>T)dbwy=qUoX65VFGvWWN#aCv?0C>f{I(n=L^SvxpXXqDm>bh@g)92+~z*rTqT}7
z(rS$a=WBe5P9jfFfwwHb+57Zd{IX-KG|@Jbkj`y%+pu!%#&bgXk*S?(F#-J(+O|X
z#^0dw%~TyoObfE)M1+j>A=81=G(vEq%SgIQn334o(NI?W&)vO9Zyg^!OAjZw`LELC
z{K(iqPef;Mo=#S9UWd}eOB{p_QJaHsMC{L??T0~a<_P%`%1(cYxuIAX!v$J+D#fFL
zAxOx7aQkG^Tlftu;Dl8>KkYtz&fIeS!*%`v9}X1X((7R-%fFtmAenTQZkY|wJY_85
zdFF|Y1Cn$hedMPZ3q5e3PC!fF${+S3JiLQJnz*0z#Mlrz=ghfr%O?7F^=jnXQ|jBZ
zeb-q_CjOiUT12|KcI=*THj+_0pCVLJ0>fZRF^J0XS;{~UMvW>q`jAjUk_hGC@~hWw
zHvg!3ZK(=h?YOOhC2fP
z$zPvP;*~yJn__q#B;kZr|8cXDmL`Qq#YTrSb-%bT`rTEgNS2lQC><2uk4qz`+Pxco
z#VwKmrFLcf%L?IJPGwPzKf!tF1ivorY}4IePe
z7c|WksoA4SdzcKhZHziLGwo4_UmYIss~TeIF7E>@>bO}G9&lEDH#K6Wts=c>RB1X?
zXrlTyFuQA7ub%yyYIz^{dCtZ7nI1#gm93S}Jkf@hD&DUYx@nNuP?moK5=s<^n|0+U
zE(L4+)mKy7*?0YLFp4^iX_8ir^<=W5vNu%LP>SA?5nZ^Vqb)rD^fVVP83PxW9{-p}
z4k{|o2kwwLYbG{F`5B2%8~C*mZ$3RCy2md-2K#-C(B&=onI}4Ks0~@vpebmBB0lu3
zA9xOlY09N%Z%|t^=L>E)I7fdEdx&fB+^5Lhd2C8^_9!Nv}rfU=M**$
zz(A#Ug;Yp&_;Xzsd|p>{WA1z^X!5_}z@QQax}6Xw+DhxkSZ
zgeENZ9@|CV2k!ESE&z{6>M6^w{ECvAQur2`ni`ZZ{_-~It2|>x@LrBm9xd#MDq9r~C9}bf{ACCN?)N9P{ByS_NGZlFyX`&XPFi
zou}OS2r5V%Qo8&}9IAj7C1;fkOjxR9W-?UisTPf7>V1dxDqXHs+c=4-;+dyu
z^Afp=OvT3*AEo%cDJNQf8%}`P5qG0?wDqeaFDo>p_qNQZS`CZnBZW|1p{DDGF(B*X<
z%~9dOPd=FtB|ZCenzwJiOPf;t_qHL=Jc0d8WMeL*7lk@F_8Sqm-_yL4mx~qN8pLUK
ze8j%%-6nZ?zqq-0+s#9nz2I6ZT()bkKiFNMnysJrXpXVcI8@y?mmr+Epy$@I3o9Rhsxn;+`Y1G!nLoa9C+|*O|ZG&1_
z9^K&<{b#=7E2lRv2YmEU*#>;X93WUST1*gk#;*}5jD-z4s_1@p!z93|WKzR2
z@=kzM9`J9|*PF(lsTvDo;m?&HIQ{AFE?HM@{*~~6g)^6zrri7|8@V?g
z^4;ez_T6#l+_8hfP4B>n{Wqjx?YuItFZyX$3dEbVpC80qzRZRP!oAI*@X4fw1qntxD=wJCZ-C>tfBS9B=v~mBx}^tHN2j{ud6}iRr#g@Mr^m=83c6fnUjp%xpS!
zvVp$^nU4>AvtdCz4H0#bo<72rU)xQ#`Db1CwgdaN#fP$ce?mq9^YQS0S`>VhI^N~i2d!X
zBNsFYU5-;#s>t9~P*5o;tB{q`S+Y!Y=bwYu+mH0pYuC{X9)bFE^DD>kj;@9}DB(?7
zmbII!#Q;}%&Qkc|&4GjRJ0hZ&KbCql_i?fq8;Vp=*1OWl9Ss%u%arj~@q-H}=I-sxj(+XiPHf+nXnp(S&W4R=xfU=fkzv0D
zcbqJ3)9$lHcyzKZ+4W?0x%Re&pksir7GleuUY^>kjd<1~`Fz3l
zYg#a#otSt++*XOFrb^W0f6q@U#Ju-8hfoJ++J4n&(`@R?pf+h8?EzqZY&W2kH5
z4sU?*66@Hhf2lfvt|r4#J+DQkrl!oE)0c)e$xT|Qjo%t2&WsA}ZDWESojDOrPN9}{E?0g!OUyXi|%4C9i3#(op#+C-6+|1nA1o}<{Ig@ulBL{1p*H1FfDRw%cp=CfL
zw%c<-m6TRavQA{>MCKX?`
zF7nqgy!l-BGx>K0y0bbJCjKmbVXF|}d~~wYt)DmY;=DITb&6c6M;a(?)yVMqy+5NX
zzsMoapl<%o2BNH7rFdhEBUip;fCS{cxPJoV%vcr%^HeC#D|IW^RN$b@SoIOi7asfZ
zo@r396aS@r!1LJ0O#x58SqdOj`m5Rq6$3|iREGzc)nuc^)_sLFZEJ3T76r1<1Ia+q
zqWqdWtC0j=cZh`AcB+Q*YuH^Ql1$dO-7^=GeBd!k6zK9eohGM!wm}
z?4o|17B1999lw-#yjn%CYJeY1L*;kQJfHS8m6gJgSF5)x@ofoo(J3r6`t&w>KohiC
zVVERdyKjI|dK%z7VziH);hSHACh_8|k$PU-zxHV!{N1zZ-HNYXF=#C6iO*-^yFV=(m5TKMKM(p99-5Jc7Nq(5{
zrm364001BWNkl}dMtarJ>`3C9Zf3Sm-UYfHkFBuDlBzGx3a&T8sn
zx=Ch=njQbU*qC^h)C5l^ES2%Yq$=0d;h}pl0)XcZY?`euE3`@4QmPRkHBqW{%WGoH
zzooAhLDQlr)#%ZRcteYBRV}0@t)PNebxmZ}urF;-9k|ajwI*oPy|pakS%+2Zn7(i3
z66=Xo5CNK+2mIBJ8)jb?h^oz?HL`laA*)HX9I?c|t%J1*D!v%Sz7+vPsqV{FEkx0Z
z9F||ax`cRy=)6L-P6X|Mv!}fk3uk}@nlu7OQ+{pvLK`V$0MJ1f%|`UnL{ia~F(8K*
z&l<{C$4GT}gv?OUmqY^T$ik2-O@$nqxk@24r}~xJkg2}*I_9LE1+?ip%LclMj0j;<
zXLML{YIsPSN83|Ffpm9}OuIvCp?M6
zS8r{POATREm6*N{rn77Sh*=bk{I5x0t|B$1@rDIc8evdV8gyg|RKFKfBe$+CIYctk
zLar|Ld4Q8Ciq}YB5TXmIR!wJWRKdxsR0V&nHr1Xn1YR{UsZ}3|aP{q}iOt-;wTG~F
zLHoDZsTHraS4-Ac37YUO>f
zp;jHNp>UqWRHHDep?VeFwPi*Pkw~1*gv(D9`x|PeXElRDzLOaEp096`KcdU|Ah(U)c
zLap`mdIahbs7Ih4fqDe$5fDNEevV1${Xs%}+N1lgis)2)_2j~hDIk;9uE_bMyZ;*0
z_~E&pp}%QQqktr_^#4NaGfwP{;Cr@Rpbwj@Fq=)UJQhpWf8zb(#G$28X_{t8l|p!H
z{Pv5NZ|-SuKVh!G3$u77@e{?;MI-H0;8R0)NOuT;N;!ccu?ziP#2gv3tOi5EafXgD
zW=o|~IaQ9^JWXGe7C3ZEuoJu$7Jkk(?@GeFjfs$yV&Q>9HxF?n^fy<}1D&Z|3w5z{
z-5jr%v4Hq9w6iMy
zn#N(32E3mPn#Q4~{O_mNT&p;K3B{)noh$NRN#Wp7*IraLPt~wz`l`9X0gX*ci}PN+
z*td9H1b)9K$FI5?M;&E@{ZGBvmwk2u5I6t5D?cw{wFG`mH0)X4zQnaq6D%PMrybZe
zIY_V_H^}pYK>v@1cb+j(0*7)6)k|Iv^c?K#*lBo2)uL4D!HP&x&9-^_wE43Kb@d3#
z$UpE_@&Ai^KWv%nM_UVWm_k^GG#itLU2o<&VPuz~-JIF<8XwE;ho9MD6xjgjj1L1o
z9)(>{v(Q+P3jGQ4zxZTGS7rHC%H$+`f<0)xG)G{s4xK%m1`Q{#ou|pQRRIGkMF)19
zHoDW~5Z_9QdbPk_UB(RSG-h;H_?$e^7u+WZ4Com!D!9X_5d1l5Jb9ObdJ@&-YUVj6
zxI?hCshaF;w!m&vLOM(up)f4abD)pCf3ROo<{euF;~3V5{X0L>g78|llVP%2Rjv7@
zmNv{()3{=ddzE^tbz
z9eVh6ZANwA_*FOK2)bFXi!#VkhRzk4MaG9-gOun4MpgYN}GUAI>u}}zTeI#>yIjaPDwMN0^G!3
z#&BTVbjuV!#3j&+OOBZ}2mctSc+Q!v9m`8g>A^iZ`;&m5F#XgfKbhuYxr*2n<+x(E
zR(*{9)uRoIIkP3k)b`PZYR@~>3On@g+{dlrb>KFk^+9#_%GO%8vr>_IHLdxjo;u*F
zaa<{nd)0cY;;(5OR&7DGIVvhDU_P=|HjoC_G^#CA-ccY91>-@0zour?dVf|vAfoeu
zXHTdLH5|W$;!}vOT@M8D*RC3_G!71gr4H?>YMxRC3ECqGAKuoeG~?z(@k%%ah$Uh~
zu32*Ys+(~HV_Au5T-wtqKK8l|k&7e#Rd-$cR{kEA&U&aM{dPKcIA}^y3A`Y)0{?(I
zwF$*t4pbWAsBwIba*S1c-fvV6ckBnbz}ZysJB{^2iB85!~Y
z&m*0NehP_cq_#9du8$C;0l0X2ijtCQo|`i4Cvxe}Jp86o8eW>rU7hJBz6zF)N}nw2
z&q#X}e01)mAjtm;(OGQFL%Iu?hwI5FCXP74WT?Bk0B-6SfCIQeA>a<*911v(o%@4va&a2Wo6JE=21#Y6))ga>Ynu$MC(*k
zknRX2eKxih=Up-WJ>xRPw=*TDG(1R5-DOlA!L}%B2pXJVA-G%c;4BCp+%34fySux)
zySux)JHg#;VG9;;+55bE-t8a#vq$$R=^C@XIjdTkhwT@v*$gA{FNb}Jfa&z%wjbch
zhp2{Z3*Em~wJZ*D?(+iu_!r|a{DtJ5=Q%h(s;{M=Ip-XTPO0!eO@1HtA#^^XPMeEY?
zgt$ExW8$Vs7PCPL<*m9knt8*%AN9CG=TJK?f!oM7KR2G`heUxdplw$w9OU3^l{F!GT_xi2@lJV
z*+srsl0@HpEG-Y37~IzudW`d?S^cUCB$@!@vpI35>nzgfc%8bAs
zhC?5gZvC)dnUK}}eYuO`eRnzK>qz=zaA4EZZAC$Qn;blr5z%I&$8)}``br%Q9A9e_
z_g(bIPT5;l?{vw^G|E|ha-{7ik;#X$;FF()bI}r;^C0T@)*p}2?6wr%*UV@=81`vp
zegKZ9-@L3l`X_wckygKkAu`*)KsLYm4yfu~YOM8h3F6dFt3EeL9!MdMvSQuBmgqniM3mf
zZHZ5_bgHYP5Pg8_i?;hEIVBO1xa$5RWWI%!KHol&T@2f~elbN<9=QIT1~Ssds+R8F$f_@KiQ8>QO~|$$Xc#SOZ9kqI
zUbwzY&)8(6CR^vKVkQ#_dweh&v+P5EG*=pKu$gZqMcgA)XIk?(qHfC9-%M!j8vi>Q
z26?fot>agx=U()DSZ>+yC}CfK-Oaa;jNNb8etpb8zI7Srkay{Jf3TEDW&|r`YpJ-O
z#|RO0w-GJ&7Lr_5{Toy!6(JpdndNzzw-vYGZ4e&f^0EF02ZTQZyQ_{?U!KS;!zE|U
z25o2e#_sDp=xH>B@
zqgxAmaYuQ6tr@eHY1=2`Qr`Zu&;(5z!tDm%BUPuJROSSf+FB5EHAKco#>`)d8bRgS
z)VuG$ulY`&HbY3N8JeTR=6Ourq+NU6k=AvIY4;sKaRnrq24xISX-PC|_XZc~Sc6N)
zik8kpYKCQTsBw;?%AW~bZ*U${_`RuJ1!&Uj#@AtDFgd@6hDYpzIua6+hjV3XFU>upKgCPCP
z2+Z6$6`K^l>Z*Be3~0hZjHAc2hq_gKEP-wl&?9-2buIYV`!d$S@O21EI~TN!k+e?@
zokQxa227Xjt_3KBt**f2I8J7`{-G#-e59s1Q>c&C5iFK-ym|>9`%yK30IHRuNjhdE
zsbIGGSC+;_JHxoZ>R?KMuS-Yk;S9hH5~BV#$HoOhib2p@wZ`@yRh#BtGFJg6n^R&{-~JzSTB+$eOXclpn%nbG}iXV=Ss
z$1cN}j?6>ECkMz&Rsx?_Oz4dLxG1ZnkRKbQOh%`8jxN+iOhEx=(554G7Y)fm(rmKV
zaYcN_E#wJnaiC9s?odlx)rglV=cCZmxwlb^%ciEl#maaff!NVkf~8hdOaGh3<%!Nr
zs6^AGKgrVw1n
zT@6d~^htr@%PslQ0#tk&d?X~9?jDOee1$wzE&6${dy`?HEDgD2ysu70;9#lKY$zagK@g4gOG4xI_N{N&2^>Jn#W|h|
zV0>U>tGtZ%&-QIp&VDh$Z&gzh;4a->gjGM8-%m<-+361JS{*`+u`&IrcL197dIJY3
ztLwE%&1hce8yTROaA+7YYK2?u}^^*;qaT>^=9-^|Ex!G}c
z1jo7}M!{_4^I4HlBK&
z4w$P&atX$LZB%1H_SX`$&*w|)U-*lYfa%#T$4X|m1
zgtYgysA#$~!e2`(6N)K^mYigIemgVydkZ$6Z*zna&y~DB-DQe-VU*lm$#~lvT3D$)
zK08@XH7bb(STJRivS%kk@)BXIG$&Io_XP~zD1&wj;3ywIr!j?dDVmxrmlq#~ofUP$
zUCglUX&R~#xFC0@3kS1>Ix=lPdF+rQ@6%0xI>lHJhogl|I|ejrm5Gt+}bv}e7n
z4L}(U(%xGIs&)oPupO1)^W|D9!ysefkG)xgd12JRdO|*r&C$HCSRoM~Zm)V8uQB{Y
zUB9wDm(XPi4~>md-NLBoVEW8%{lV;=&rdzk$1pWLlh18lmv%xnRNq<#y`N>^f$-IT
zsk;fs0}{>&ph7%+Gi)pn6?qWJ(LyYm??wVff>mb-O>oZ7Z1MElrh59z
zy;B~t}7IIuCuP27@~3L{F83of0VBF$si9*=0lZ>hpC;z4+wU7h?__p!xMyztIy4S|@pDN}3=!Nb0FZfc!
zd{dL4x622&J=e8Su?VvHjVFi4e^aGQ3%ovPX+RZc3h&)aA_6WpGV%_ry14rv1A(V0
z6`okbyFG4qP?SAgVh-de>H(iXib#kr8!zB;?74%HEXOEZu3W78)GP|Y#p|)^Thkpe
z=(+=>1;&%4pq7!D+~Tyq`vhEp{@0!N4@DC%LhNY{m!=a8u3{KL(_`vHv-F;Uj*E(&
zhas~?Im=ENUMlRmf2X^xo%KNonrR?gc&CS6Rwfa@{_21o7k!cOvnd0tByL|qWDf9-#(>%2PoZ>ty3rN;P
zf5J`|xI`%}+|Pzu-ha;B4P00mlnk_fBsKJ74{PySBN!IJppN{~@ZFbSc>~2wYl+?q
z;xSgILTw8o8em78OuN(_c-zxOpccn`pT(!JTrE)}nwChe4y^ojeMDqc$Wxm=%Qe#j
zJZGU%YmeNLQC!Zz-z;I(CemkBeHlY8c!yt45Z+B28BSPBQCHo`#K#g}E}}A_klx6o
zkkkOKgZ5jiI=z`iXqR9vBV(hT+kFn8QewwsLr&82>jSUZ<$zj~5hd|bM}Ga@Tv2?O
zA(j2=G>{lIs4>&tzAa*b7h!Ze$0lcc6*~XAzb*qXIp09j(`X?y*<#gj(zj=;PECe0
z8?NLT*wj{P*>6wk?pbrp8W5!VhNcGJaC!`nIDVO&T9NyAO__@JPS=Zd+6(Sa!k}8
zH6DV$5e7>PX?ouLp9f21Kkkz~a&}ogI9%Od235rxe*Bo2-m;3mKkZTiJkMPq;qA?4FG9k?E_
z*g;Ey7gtk9U4wM%TBD?cF4V^nj8!DqKDi5z$?X~Hf2kKib>47o;A}`Pd@(%Ze}I{*
zHhApT)NOwGch3G-3R%#A!EOo(gFE94e!5hV`zpFK1F1FYib4dT7Ni*L-n5AdLy1zM
z)$@#YhN_EyKYsvS>2ZO~1k5LDYoP5N8AXePgwm$O?^CB4jTC<=Db0{A5VaC<3q)Ci
zl96E2Lb%^yXtw0qcBZtK^A!GI#LIfC?@B{=_q5dE&omi}aGm>B{PvrIvycezMU-U(
z2E-A(A#Av1KLYF`^@@{HC3+-rlD;>x(?B7ANWD0{&1w5Y3lZJfJFq;$@(~9s1&}%N
z)h~?i@%sgG5g+eO`nY|1Zzdj=4OgU#L2KiaEu*fxKhY3Ab#@l#1MK2gVVUmx*RT;S
zQO;#-g6(x$QXeDVVuwPP0ih$
z?r4ZgWaqd)2Tz$`t0}#sSR6Go_oH~qE=u2o3d%e9;UPl21KTG5jRO30ptq(HaSlzD
zSkdtpC?~&~kDWa`c3-3#$zrOp#Bk=M&O&RGSUBh14HFjqwZyXL&m#1Z7EKP$*KIG!
zVXuk)0N0JTR{_m2sSGjRHAr;Xp`^PRcv
z;~!f-q9_`M{Z%z@;^3aVKbBqgd_@nC3#FXLb#PkT?q_DdZ85ZY5Bn28AhIc*zNwwh
z`%Z(M(?>@7ERI^eX(9~qzpjVrcBB5a_HY-_P!w8g!072G{C-90OC^;5SNYrVj0}DO
zY#j5|mq++JL<^{m`j6<(R!>YV)EI)~Yi`b_zWNsc^%&`bq|WPo1^3SfAC+e=h#3zR
zA!7HKh{?oPE)zbYpPt;?(UDMK_e0CVUZKXedlsRkn<*27c
zxZ6cVZ-Nr0Y6L%50`LjxKHczBiX7k3+4wnBmBM>OaPhwP4h|DsOzCMvzx@gT|3F8FkMaLq
z59<(Ll8DtW@;ctno?kDby?@8yF!)bT-Hh=7ANzR;($ZtqzEH#1qt__3=F3xq25k)9
zdMc~zS`Pzm5YDsWcCw8T{)H^<3oC%CObNqSJ=%t<@&#h5Xi11L8qhjpIM6
z?4KY6KoY006&M+VLL!W&e%8RdU?)07FdEi}BiQR(3X}Dk@JF?F6xiJfcz*cLX*vFD
z+^@Uwe2E*9!II2!{2WaW(~SdgIt}sBZj$U24A-5#fcabAp-|A33|NbBog}v^
zN;amN5761+-R{}%^)vQJZx6|rU%Hzr<@b=X-MCh()AQ+30G2hSND^!1PR#ekPMqk3
zi~AJ&rNo|_UTiDh%xU%>CN^!te8UaE5lV0??We|blt4#z7I=YbB_MFYO1-u(i+m6$
z4mn0=eSgp^E1kqxbzgI)i3a@mj<6a4pRE)1q};Da?M>~s!C5vgQ;s*l7^HR4Lwft>5j{yF@lhSdcqBgo@wY9
z7MA9gmO?__46zQMx%n*91$z+(JCU?&c0+AaL}spxlzKPl=&G350)dE=DF~(&v&;}V
zd84!v5)&i`l9Cd;nRx*zzss5SAn%hBl}_;DVb#^e?bKoTdN>tYrr>ugz428NQ<4(<
z8fm1s>{?nUdw+{H?{|2)2ft(kZ+NFLYiTAzL#pQ7|&*$e@XGhS`
z8V+*m5kN(rTD_Vo+Mnxm74N;lu1wi~zxiS_KnQn!O$qonjuVO(CbSPL?|v_w)ThQf
zHNvXgy%WfX!PTYD4^FMPQRYc{+b}B>)c^_7Ae8TqN=@0+LshZ7xrkHe_ZHRbAo%NS^?QBL38Zw~?u2UzGX(ZgA0w$2c@$5^iUV^3edxM-^|7`5KlD8JWg
z2~zn7zbJ*W4zPh96TrkC|FBtwW)G;#G4`RHhez8~+>EI?CG@UEvkBr6x)MYe!VZzM
z@Z`M)L+Sv^SF68?!XIs3L2T_x#X76MTyzxIGeJdkLlljTpN7Z9JS#aTD4t`T`*^AvgZqByr
z9=qhgtc!=d=3&`q(y)KIGk_b7~R}xy&0(6W?9WW%aNbm?$%@70!?cXO>0l2
z&o_&wFbBvjqW=t;EYJt>?oIPhXd&?gUG@Q(vg3Gi6~an>gV8`6obpywD~zNeuVv%Y
zv0U3xF4$PS(w^(RElsWqWw&!gmSSTq$~)o*3l+&=G^3ATl>ci1KH_FZ_W2!E2ERr-
zxNo3V-;jKc-13J7-CI
z&9m{u0>T)V?`t)y9;3^N^?~4oR=1K
zO!uoc^@qADeD^F=-a$Ah4Hxk6rbBG|S}m#RVJq8iYrC^vK$=a%EMX^!cvNvS5@Qb1
z^mrzBFvahIhjYLWTE^%v(5oS(X
zGa6kp*cchPc;R%iTKUo=g)nw-ir)^BWxq5127bd~%>Ru2Uaj`+6uazHPrVYpgs|Z?
zSa|?@1J7&jH~)2T9lz77@MVo9Hd7szxIw|i06O@^Y_1|vKBAhXyYZ>x-%=4zMf9Sh
z-$VzAZhl=K9O?%hV?e;up>)~KdfAEGPR=&ERZf|2m~OQXjA77QWoBxo_YW&vH8VEr
z)9Qq!IWaiRmnLrtGF&wCIsVgib!F5bm*l$_iyVdOHC;AXO>WZqq^T}A8oBw4K{w$L
z;+!en)UF@$O4-~rg+-1BAT1RsuAYf6HC9MWVnMIQQ|X^F^~1BcMdxF1>gnyVk#fee
z?qY;f%HEut7}~b>PYk(x
z<4txJC;KS(=$+zu9U?TWFaaBOJ-I|ne+BRei=)T655p7A9TBY`H}=b&?t?-~?^ss`blgQ+;2S
z&+Szj*^V-YRI`cZ4zi;k;n_ZHW-W5uC>%s47YMFSAW`tPSz}KP5g=vkhrjL990rQo
zz4<3OJ)t<$jm>aI+yV2z1BMp2HCFe7n%c3z4r;k
ztiw&&cdqf&VXLV%^MQDHC&fCcD!ekHA7kymipo`Eryiq`mR@)7i|*d_seX}~YF%CIM;s^S^;*~Op69;RGS>vb
zl1A`wmF2$eLoEnZSISVcH~l!S9i+#xHk}FsOZg4c2ncpHX9UM&TNz
z>QebkTVmD12T}uv(IHE4TJS{?E>cpN$uqrmRx6N22v`$ZRKe
zHsh)wpGV>{T@X(rrFRbm%#Pd-oxBI(2kyyqm&U)T(vj{)%1X&uf!FGtsjfW`-9g)&
zc3-X3>iGCHicLr^SDK6Dm#=1?w8n98aR*lHHAw}10KnGC@ga-%z1X_0bhg}Tvx|(k
zwY|5P@L0QJ0YFKxc!wKXJ-eUI?;sq(y#AKjba{#zOa?B&GvrV-x$$vfQjO!j08dy{
zU`a4S&zHCxp=x4xMbT&Z#dNF@*4@1-8-6033Jx(chW;U1R{|z-2WoAhBf$@!aifp5uAx5Q?ZZ!jmzwMZnYx4CHPg*Dy=qZvw_}vEsYko40sTJ4
z+tu6SmIt_3mzme#X-g(;G$MJ6WFjww>Q~eor>5zcEoW?$oqw>urr_0Hk1xMOs8}6)
zvl(9*hQ$EdGcpC#1OFqLGoY645;RZ@NZ<)p`;%okv2yV7_c(0$QvxC_;UXUpC*9W|dv0PRAQ43}l8Q&gltimtKm9<=A@X5X)R*;CsBDPOR&GXfeFJMK=iJ%7gjw
zbbo1><$C54NBw<|e5u$>PPZeML8Iz-_DACDaTUh+
zR+Gg)2-op_{7U$e0;qL&tHadIKvJ+v<*c+LKB8>YDQ`#0+IUK^(Hyi}G0qwG7kK#<
z&Fo?muRDr5il+v^#2EM-gimJ2Y3|AKEkp-dr#Ez5w!&jVt?w99}X!XceLH(F{U_q(+KnEp-L8&Gp#H)cp!
z;mylX!+UQQPv)F2WZ3sReFyPppaBu@=2OH|`mg_J^6~8O|5EZ`
z3*w*LCttX3@bO2(iWOz}5Y-+Ve&WDMbZ`hx+U4QqmI<*6-Jh|Eino5!>EWS}36wU9
zgg+xf;VfA}b`QuD@s555H)-DTi3fMe&s1Wt+AL?FVkc
zl3aNnYZ3hcmkbS+NBd~wr3!m{ls@n7ja`%)YXxO>dVdW&Y*7rwTY$MeaLzv_5mjLg6)L6uzGfFp3+?XtPTo)2i#*kV3dbu_4hvM#=j2PsZvaZ
zeIDmizKK-)sks-MOA>u239?=5=&Xu)ufimM3;|9wXPHd!|J8gJ>PVq_qSM+ZSKfVH((5?RVErH7q1b&6r_gBx
zvPNb4NTUK9C}`D`(HHW}lVPX&cL-@>>K7<3L2cie~
z(lB3Or?MA)gj~t47C8Nc;_c1=!p&Hxwxt;C@1Kf1IhZJ3a{hUz6ok2J_CDtzfNyGb
ze}T=^`O#>}t{cjesq-lHV!LOJyD?)HO0HD~
z_T+NzlVvG#FaWBs(WQ$e!Xhl614S4>HFvePDyb43C&$Y7!{%1=ZRm$z<^qlPbh);^
z4c*tre=DRqF8h3{jyk1(2Ndt8j(@ZR79K
zS!v!ZEUr4V817BCp?P7Fv0p-7MTC$|=%(!80_$o_m$TE<@_L1xg+v`Iq3@BLjDa32
z(ANFNOnYYqcu#~l(9icLCkp}QG~<9SgPB2U*H=%GGVr5TE?w251YD^5WA@o!ki2}j
zqDVP!+ry5XfXUzPQqJp(EvWSD9%}J%^Ei}FA|mT3D1iIRi~C_wBSG(oK1K2lkae4;
zy%AIAH28}RUT(A8nEaaw;ER)=?|hNx%P)1Ise3a8jW2GOeu`ykd)H<*k#`M`!c@0+
zr9ua6_14o1o#koltZ~o@J2mAir{W_;4vbm6ZF)ekr^zuc
z;llcS$>Cb-?p&*~azR98rtu&}$M9h$6>W-WrW5;)+ak}nZpcot@XBpWIIBuQfwygU
zXmcXJbqT3H`%u#%;n{AYBw(~%cTLz2eOg6J>B6$L770&Zzf@sbt>#s*M~uO=q({=wJ;hf
z{AFPb38|(%#LhqEf`tL&6LiAv!LW;XVU46M?18-va`R6hwFCih%3_-6lv7IbZ
zh?p_eV!riy=p+8npnQ72pIrAZ`65`2QpwdWuA_I+PNnNid(om=fzSvfWWrSTrb|-n
z>F~V2O$hC23dthGM*m2kHmVi7r6Z7l8>!hkR^;|OE~|@U9xNZ=I~|~Pi+dd|X(vl}
zl@v&D(;atO(094HHRV=xOe{*f#{hLSzxU&
z4``%|QdK1=-C5E|5ndN-S1593psMWD)K9WEg~dW_38$RTV)Av?hnSL8^^HaTt6hIk2h-QUdqk!sEi1#V>wG
z)%p3Ds0d4~r~~n|!nPT0*z+|dyDW%u2e-N0?=UajLiLU-r)i4h#XLSeZzxfvs#-C>
z|NGTsH`^f)-ddOw70NzVIcF8ZKV`zKX6^7IqMl+s%8!gH$YEt>BI5ITeAF91>f%e4
z9JZW{xH<#VXBlj^h|}=IS{86&HEee7TZpj%Kg`%sz47(|vl~dQU}OJD^YoBKhT`0u&g_4c@(fF6-A#XLxNYxKso4
zwY_DK^jI;iu^qbVuFpWFo6AS4BnR1!CQj;N
zR@3eYaJ~n@!?LDbcI6*0-l8*cI+G`{6
zM2L5`vK0tsB_k+x4{($lOm3Zk;?!^5D53>ucc!-xOVG7{M2-WuWcJs%5&LfBO3XRzQyo
zIGc|_{yZAB(!`VLw5+k)F6Ih*2?_VxLxwRRpVEqZ_myxhJO9_8Hwmf4N=ZHDr-{~C
zbfQJF$*8L#o_N7b-_X9Ct4mfL*|>Zn#cOKr(o69@jX<5*W}#LwX+B{IVRQ_V~i#n
zeId+Fro-#HVUE#Uyxo|G2L}Ef!;m}DR@sj71I~>)_gIRB$^Yk_Pp_fxaVqwcqQA)OzFobtg(b`?1CN7R|7q;rj=L$o
z-`!nz-y}4AruOJOp_mFpAx28QG<{;@eZO7$@!K8T&WtgbeZe6;BVN~!+<_>KpwHIO
zCLD``8|!B*DAo|*bp(5wJ|!0u^S@s6XFUBwNrK_&$zE^a3Ja0^_wkdH^&dZL
z3cn3u2cBr~E;br>s?MC1-ey2Fzo9*~)R2f9*=XyTdZcc1o(BT)1dydHrG$yw!YYKr
zg&&Pi%qgnp``NUaVM03>CG2w6?}S!dC2J|ik-;oAt2KDwhslKdx&NFLBdpZN=N
zx8s~+trk4(39YoP_U)ImfWoAg3xWjBdAS{WLd1N2LA3Jd?I&Rd6TRpbR0hBM1&-8rvadNkU$1XsqD{IHk^tQCm*
zB$)eWkqntgaB+)RNF2OTHvbg?C4W;xdu$b3r$|cH|07?Y@x@bem$s?zw_v;88B{1A
zlSc(ZR;Ev8<5|-Z)ZYo|+?PIU6}1J0C8Z4<^G8A9#A6V#KU!Gp1-W1yUu}a$K7vmk
z5(cQUUy<%l@v)tEuCjLV7W%f|6#te#rm)wag_B$ML1cUuwW9%1Lhu;CtG_-yFA^DT
z%XXRQU!R^KbBg)oB!I~ASh9_?QI5tr;maUAQKYP3oVU6iac<16&80a7LRS*Un4%dK
zS?z!Dtb4e;Ir)@Ngcb0rls_-meVp1J-#|;>{nn?&E?hQpCrk%gH)0q>tkxvhdmxMAn3DqdCL`$!a?wxft#nJMA_U%N&-I8R5E
z)aWrT&sEhGW$7;)(9b8x3cg9vWp7Jyr&tqzbvy+Cz@N~s+Tm`AG_|5ZOP&4ZExV#CXEr#LnUsM*KZr8cVOntDZBwO^L3Wd1QnW
zxf=L?IU_QPe@JgE0LL!<(XMW}Z(N&ux?%k}+qQ*K3+%7K>tF4$7+X79g=HTa*Bg79
zG!o>fUozTqjZSX(&dhRdHCfeFv_l$^Z?w&)1GXzDAu9QNAT?`ep
zC&{$Uj`m9PFkGk|x0qdg5HYrA+^k`@{dIyO1z-j$Q&$K(Xg@ghiVML9F_Ic6+fbQA
z1QxQkG8&?Gf5tNRsYsGCP#`^zFlv4|$mft?=6H;7M?CO0d-}OsmXqo`8t1o{k82EF
zFyZ`?migPdwY0+K5O$J8Lq?B;F!-!$r4;Zr>`gYOJly}4)qezhjQ^+`RHyuU$eT*uo(a~UGJ{ElQszzI|r)1TufGTlklVMrQXII!8V0oqVw*M
zSb11md7eK#_VL*eA(YL}Mqqyt|8mqr+;By1m(%Zs
z4y;3zvOS5}k2cF7(>Jz~gs;Z`99osa?o~9$hVa)JIn2O5a?zYKa$GH_z0D=Uq%TOH
zsX80yMuL=ZnWaK8;%O`MDmBqY&v3WG@1Ifz-|*q?pU#sTdl*;q16X?uJ8TVZ3kSnv
z7Sei|zCGKQKMcIF1r{__0SX$N8}r_}njCl}D=}Us>gcZ!7XN$*i2+x{U2VHy_t=!lF_SRH|LdRb_m!wqGJpRu7e>##inVcLFV
zXL|~%Nz1Yr(eK0Ji0NsLnk!Ro&%=MUkXL@X80?#_qw8lKgZ5pWSv2*2J(KR2VYpRQ
zHnYtSh9ecr)ZBn|47UHQzGb*>~e(0#yVT!?7LHS4w1XhFVo;0IxjGdRG
zCfEQL2=-y!m6}j;f69J^*(eEWmmsRMXLkbcVYb{@q}K5R%)*Odmulns;=U6pkj!I1
zxdSb^#j5W5c@?GqzWfbXu5s6m>=Bd{ot=x;pp3M0!M-q*pL`Aof%C@2z}#q5`29NT
z`}p1`%BoId$^^@V4uN@W^h&pySI5V_{NBK7t&ojGR_D_NAZOS@64=6MA0Vu+DZ1vb
zLBAk*JzDxf2%p26#zC~3K#py4Czu&_ptU8Fj7p*EmMB86a7ej@KB@9e0gGx56K=sX
zlyCS=WOr}%NiiA;JVX4U5=HmYg#2i6jtA~bDK}#rTbgs(!;z}CbD7|$%Xg8P7
zHaM`_@+yxQ_*Al)_j*ep9hZu5a9fU)jBVkHS9Mn(sRXQj%QQlv{V9E)+Dzg$QIzEw
z$v>Usws_`2s>_xR#?)b%==7G?nS;Uxon0W$zQze-5*;N|l4_9Hy=m?mi$@F^GWj*{
z8tX{6I(;XQype5Lr<4@8Y8e8%83jy+cVv~_lyPk1JJY--aF8ndmomh-#B*sL`I>)|
zP0cc=gylIpI>Jox@w7iI!|ffm>E73O<|TUg<=iq<7Ibl|=t+y22N%l6-6u2u&HEzx
zhOB%~W$H8a-z1}ycuY#gRy3ukYuWtNw&4)=E$Kh)yGZE&>Y_?+O)(y_h;@;J&mxh<
zDzEnEIA+tM@0Y#v=q3M-MIKrj1F-)_y_;K3SivfD7Y;DVS)3RXQBeHhTeC`;A9Hg1
z!7(Zs=k@fwdH3$rm2!cXc)yI=xIP{HrZ+4r`8!XXk7SUU?TYabDw9k-ld1;XgE~-A
z?g96G=O=d$O4j)IxmJnumJa4H*I880)pH@jHa=qcci*m10_#Lw;&+NV1#E~rfp#4w
zVXM3Ajkgah0F16=D*97Jp!82eZ0MixU<&xqO;iU2@)&?81!cMOpPYgUtrpG3ORjr*
z4pA4qe^=zi=;>@{Pt&5u&JP1%b1vMC><4@|4hGPPw6qjkOf4VHxmTvfuPPlBKedDk
zTb8kyD<&x`rxh(=l{atsgWdj~35n1M(^tg%N$CU23bz{dH)bH|+aJWz`La3w
zE6C(wcG}O06-6ms?7-bQ+FvszxqIkdb*D6ZtGOB{8|3`p`Ge_^ljdmK?FZLwtE~;j
z=tI}e15SBt-P65#mw7ztxkArwMw`9z{o_MdAAkS;*F)JGT!k+86w`7OC{^glHaow6
zN(ELmHpeY@mV}Far6!llUD1_}o9Wgo2DW${#V7jnTjawYVXaZUI+~_q8fdk|x}VDmUl>S2
z$UPj1_hTZPz;wkB1!qzf*_N(>N2GoD$#JA-Yk&V5m~H>d;W&y3ELu~mPhJw`G_
zz3eW&?qhz#=mK{@Lj6tlaXy_4guZTb{z0
z*hK%pyLbG}yPTLkNtx64I=fA|+0XZJLVwTUb=(Z`R>AA;2@Nv%%eb1Ay|4N2_-*Dj
zI>zcyL;2}A$fLcHJP98EVBd=#{0yX2ZrdKL`?Z(PPmD1;7uqN_LEcEdPKHtgk
zo+j~nEkrC-NOl}#oL4#&Tmp^VRSHjTx{xl;2W+*vKA^8h(`%`>@A7lKz1aa)KPddh
zJF+s5)^4#BPDx>p1^aTIeW=JI|1-Odm_o?pG9SePspBsj&8=E;|5jhNc=!DXz^cl(
zxNe`6|Kn%9*zdLr4ICT>33?d>vO2ghg5*KMAE;}L%^{K<&7Wrk+L1&&YA+|2odVqL
zYvuy{)0G%H??${v-`qKv0oy3jXGvb~K-3;A3)KCkh$zsc^r`%|OiFg^W0tTZKm-6L
zPF;?<;@}A+jzjC7q`kuZ~T^%x#|9
zSk=~wVKmHL=K7g7>O4n%O^S#Zu4Q+T(#dC?U3K@J{Z!P$8aO$wkzpWC6Tj^@Eene$
zX55(qX5Rajd@_f(9qYUvN~2n=lfStsRiyj4as4wzbVfd3$&?+13rpVRUr)^Hls^v?
z;ElM!{I(>=`BPc6Kc~6KolrB5RzSVzu3WC0Wq|jOco#_>T!LW1hzWzuSm7nZu5oi>
zOd!_ugj%}l3c5K_WofX^a*tTukww;c>;^fVJKYKrWjBk9u
z*6*rXbyZz8k9p2UA43mcR1z+I1)BbyR@y8T$#Xv@0Hy~+1GRnfpW)Y=zqN^py`^RF
zs>`KDkJr-r?}QPK-yzl`v5!gE&&**Rhn6Aic?Q8r1w^!7Mefv|dLVPz
zDCAs(0(D?g*-Cn;Ykn@EFje=Q+b-PWFJ*Qk)%{eaf$UHL54V>J@&Jqm?Ez^dX=<2+
z3D!@Y(Ogp5e7vk$_dR6rcvDZ7a&(ey+)lV$A7c3h#e2kgJKM5$e091x@d58o3Q(WP
zNffY%(`p~>LPms0TuDG{#Z8N|l$aN^=IBzjNXEP5ez_gNbVVdkxe_lZ55%*ujvi^f
zXk^3Tub}-38|1nW6J?zmIq
zFpG9~tLt$w9tladt7a%~#2R*2Ey@uzx1ec5dK{ylcZu7mPpIqgm8GYkZycen{)x-w
z1$L^brt!}r9O~OQJ1g(t!$LywfYh>^CY%nH5roXhm8+ulByv|4`y1aCf{fbG+96F%
z_D(=oLsk(k0!>?>g#uquVZs%cYI=nqNU*5|-GO;QY?Q-!-fW0r2{R
zKV##|OKRjKO_4R#*VibV*$omxAx^`g8`p?X)hV5VcKTTNpM1GWzncPcyZgr0(gFn{
z)HqWD8l$3^b0E8dU5sNsvqVz084(u{n{HVesy7
zOjjG6{kN%KjM`^h2?;Z^pw$n$UzG#O$dz_x)D`MfuIS)?J248p%)*ST
zJ0LcH;Ix#BLaU9v=y|BQD~1iU+$^dEMb3+MSY`1(*5tzyU~OohH`SG5ix<_`HTGK>
zW<~fnl-&xRuSwMg!*B0ka=91f{^smpLSp8Y73?4uqhvwjjC0eP(5v;|%^sl>8Wjaz
z3HVswe1{H;yYAZopuG4K?fubUtdN9eL%ky8!whcRBCfEs2q7f6JP-rG2~9EZ(y42xWh
zIw>R>5?4d;>W``~)1f^EtrVL5$IK>oWLvKh>GER$J&0Opuf+;e9t4B~H2@vdRf+4m
z06J%-EFnfk@&|m9kZ~_zE@MfI7$%XAFl^X5vh)n049Xl&Z5%k97tt1OM6Ex&t5&p9
z{Yn}LI0@N0G5~rk`J0vSH#%cvkGwr@W3b=>N_5x2${F-;K6|-w^0VkzXTPbQQ%dbC
zSCJV+mcfB!R%#ezC>;kEf$z@!(7w61zw2-qD$ea3@@ZKVJ5gD6rh|c#pgFdBqv~Jl
z+V!L04jgAuLwz6V`PK4cw-hl9nGfc@PpKaJz+Ncj?Se3?lEkU}&L~q}%)kXv7FjL}
z(9H}=Bd+;Q-Ni2M_V#WyrF4Tf&6K}u*NoyO#x$FR(=yhL$!(#DglyF84k^CB3G#>1
z9vCHredem?XwPo7Y6WP$w3JeH
z$RX!Ph&~~4z$`1~>EJ!8CNlkyZ9@kr$j`8!NrL~p1brMqrnLBXz*kD{c~heD>eAt|
zc^KqW{I<)XG*FtBExwO}`%@T4t5nU)U}`H+V5MCO4M3C9VUB9uU5hf(no25}*;YpZ
zjkJ_zBW$3Ne9yO5C{Xa>gi8URlEHX9q(GzmBYw&PaomLpFC;tLk^nDTRvF1Th;HxT
zyhR9uGBhZxjNVUlVE#i8%)9R!R7jmbq!M%n8lTIWn63KWvT~@lk?Li7CwUh{BAr{I
zz(&GLQA3g^a&OCYyl7#|C$U5zU0>xWMk0?Y7kTcfY
zXmF2Jsy|L?r1zfDgH7ze)uNt%<~2QCe4|j4LmZ>sW7aP{fmj|INZtv9u2sktYWl96
zo(ZJVoJKQXE}SAa7YE%uIN{rNR-_R+jjz}VHW)a;6qUR;!Xd8uCYr$!A67_m0s{6`
zLN1dkF%eBKk&tysg7WaU`$=I($m%QKbFYyhYNW~0KQOD__0OyAlLs-ueu{VJ=WE6B
z*?>=KH#|VG6A}UU!DT#m_M`4?wOryMkz9prD)i-VKOT%rg=}VJQenc+;8&-|N3+@W
z^SIkNR&qu`19DVu9;Q>Uo
zKq@cZJo}h$(<<_`leCre)Czf~EwV;>4{>)VT*eDSi~TjiNwG#jBdEb4(U;rdD}r#@
z{9YOlun(YcDI;=ebfEAAwYAMmraGYCB`FlPw^I6Rldibk#FIA528_g
zq@Ft#2gK$u*J?OCwSC+&LcWMBg9s?NICvY`H|&`7Vn|d>rE=M*kQkIBuf%F~@e_xF
zJUZ!h3VM0?BMeCMSdJ*-;*ZTkKwHLw7<^-44nK4lW|7?IXV*Ok<0Qu8ox{f@ZS>_ArdUIRAUBYMaMmZBUiB-oCloSc6
zC1oGEr7zzHHNxI^oWw##0?56|OR0Prc
zU_@heN#bMRG{lnX23N~-=JvSZopX>1HE`(u`5+*o85t+;Id5+P<=)@{btvfCzRK=F
z4C=-TX{#+l;t%GBwF1+y98L1Fa4hLm4e*<1mL>>=byiEb+g3tMEMp1XVy~l)T&YH4
z68rN`^Qer?atw4!SSGE#&Opk52ds?bEkX@uN=`@YK!!1IYp6rKF_e;fKKSQO>e4o*`n!6ly1Y;W9J|8tc-VL|KI5H@Ta9;II_{Ea@d*=8uM
z_@S!mB<$wYmPy`s#u^sj-~038#mPzDSJGcS1@wcvmxop5lMYXRMkyg;KWRV`cB9Ieb?Z^LF{`7t>cEX^)tGD+q+yw>y
zOt@5k(dXaM4fD0LOag9I{pc6d{saG2RV+Q@KvIxCs)W&eKV(}H)X9OR?iG8~BWwpB9psmqroi~
z6}!~9>dxcrU(ZLE3C;(1I#j3+-BU0)-j#6&grtBl0wg1uoGabY
z*q1j2-Rcbq@19T)mJ7k&T{3O^cS{3zo(_%`-BKwmd9rY2pEV}BWI?dp%|$$eyMs5K
z$T&|fBtIw*{^UMk{KaHqu(pP{o;|G~@f6tOmBmqpXK#2aKp))Q-Nn_x$BCi1QtJho
zNKnQuTZG-e9N3U<-*PqAnoi?@d5O+U8-s$)etB*t=JrnIXns8Z8W`cvgKDO|zcdZ#
zt|xzSzPjJN?1d>Hqg=uRC{J%A2(i>muQ324TqSDu6UdfLG~Sj$ZT!84ras&Rlms6g
zfHm>O>cR*ywlFUN1T3pIL6BC5+$=)jC|x=EO2o<4|(v%
zb$Oi*$?lw2V!vXq#)peU0q_mE+>V_P_gjQL571?@(B{4EJBE0weU(bctT3y`_!?DN
zP8t|4m9YX#Fu!wMQaZ&Ogz;VsUknEA4V1wbd?m^c1$toIvvI!^m)bT~jOv(TkbMGE
zv&vE_dmN25Ev7}>#&*FzP-P82hBDuWlL`JtHx7`PzVhWQ=eeEp*blcl?M<7~DSMtJ
z7D^lQDeiTxZXTDzZ}EF!9DUHYrw!RvWzjHFPI%t#OrgN_D?L`7DkLt47Y1)Q_gmIF
z%x80|!dK`{&34ihn_i8ORb=^aDk(48auRoK0#n`s9z*iFA7!$|J8d?b+Fg(B^Ia_P
zT(exZRtIY{6dPlb5x~nE_Lr$37M$oTqbPO;;I_TzT0!sbfl1j{Y-dXqi#xs8bcK&P
zo+u7%9jXum=rP&?KItrWETtVM&>M;b{u}B727K_;)$PtiB$pVZqIPpEIg?M{{C_QG
z?{JF-26%)el?7#;i7o_Zoea|p%67jTLViw=KiZo11>7jKwqxAdQ)&(^uI|S_@tZkZ
zt}IgdHENBm(uBrf=Mi<2#K3*KdcjRX)y^!|NVM*V7!v+qn*s8tc`(g*<2T0^=I??=X$;6ay7fs
zL)Cf;kM8Z`W*8iW;{DEfYd@Q{VBeW54v&GU&X04%r)1iFUVC%CnwR~9$#Cz*@kG)Q
zS+(x_et2WF=}VFekBtJ!_#XZMaIS+xouG{(=hb*k5$7sMPhO^@U!K!Bp({m`TzIB|RcVi#X(_=QF&WYJ#GG~9Hl(K=A;n{V9iJ7ZEf1ycU8g%nwKbQN
zHaI+XoB3FbH_J=8A*X5tcf!;vkg_ZQo-*kNwr#_of75*OR9|B77$lFs%0V7TJD!k&
z->zqdbIVLJLg8RsZ8xHYhEpxkx$vS^RaHGAxXYlR)GF_&z
zv;s)Ki*u{NfU=4cnnmqmffwN5I+Wqc<|;h|{W#gra-F*A)trWhPT#
zxgqOa9BlV|+!~u`%BbZR*7(@NQoh&POEjT7;lgpiRHh+MUcS38Gp-al56XIsX>xw7
zD$P>Ce)n>B|Efk%L#C(Pq{3(f!(ZiR0Wqgp?$ZD2qr`Q>n@-wfo!
zBZ_(5dvC56{&A?`SPD2&Ve-P$#5$#avdqPIz_<}i-gJLGH>F0rz=FVcA554VSifJi
z*iJ3buG?#MhpwqW993+%W%urwWJpR&DMw!Nu2n1lJ&#R9LA=67n;nvV{5#TH-I-ri
zWwL$Z2RTrkvOuzN$}WmX^_A7GOE=fGH`86Q{aVazAl;RpMo^
z5#|*<;62+Op11Q6xx=VPC|-j?R>RMdK|}AY{n*bHVS`c2NF^qDI%9x+z5TjF9l*A!
zG+Q6`bxA5d#Viom;G2nS`M2PwE2D~C+>UG7Bm}EtOW)dR{r=YiIPWC#^1Ui<#^Q%Y
zrraPLgU8+3tO0aLj1Qf!Po&r;q?O@tKx~;_HTbG!OK^ENwy4<4z~bXb>64F%-dP7t
zZ*F6|vQ(Rz%kg>cbr8;&qYn{_9tKF%))ZogvtL%m(RwJQw?>d$%^7vU@nM=JXwwMX6+Y5%a%>
z+kTV2d`pn}7qA$y=$&2fHvWgNlwyC}pIqdBn2mu>o(w%uahy@zffsdA@0W56K#8L*
zAv)MzNiZeBd}lrh31#ygIQ!SKjA*pQ6$D?TLAqPssyKI~_?mw;@$FmQW_{CPZ60?Tm
z#t))!>q-6meIdalfU1M^Q-I~M3(D723Q8Mqy&>kN(WoH&DiC<{QuAX3N~{4PkPm8)
zIFy|L2TJ3iwrjWmOW^C?CX}^`Cw73C*=5uBGbMf9ZwmZXdHx@XnD=M1f2;?ngYGgt
zFa5~|rY9$d-Ta~Gec!tnIZVp<{Z7Eb(+7C_J>qJ??6<>_1hu$$
zS?_3rJ|_ooHkipJxTj+aQZ4n!j;ZQg3urek6x7Rd`X3ZEOy{d92&FPnSDcdKYaj8kCB*xH=2>@re6Hk3;M0#hSWd9cchpnJPTxz_;6Sylifs_jL{s
zQivuwAzrgw7jbzPp4W%x#DREFO(XByS9|JG1g>O$ni($D2Yfz}NrBwXE(YV&OH)QDf@z
zSM|t@xFt6S@L=ENf>XuR84ZE=D_Lw%_^%2G)bEjCxkBMHB|r-UC#hitr(pI!^6c!-
zU%y6y$#{|HDDQ`RTL-+az5M9rn_P(0zk3?FMYpv0Z;82Q8xBMK1cZ@E$Huma|}gVZcf^efRpGXk+jRvtXpSy}pZXYnug9qk={_xnn--l~|RE?bb
z_RTdyox99toDTXJ*x%c`jp0V^v`8EpJ17Syt#*SSvoCq~)l=X8&$c{!rxpkWG1_oq
zFN;B?hao<@#Rt3EM~;C0~*4h<0gz2B?$X~zuE+%MARrdYhu~E
zjLQ>EC6zRbzJi6M37el<6498>tMR|amrvodf9MGr#w2+WL#xPhRruY>6jQo|Z}LM$
z)%D2lNGtK)jaQ;aHphF(DBU|bOcY-~o?V{PG
z?VX3^&0!tPHhx(4gnWgBOzjql*(>;%T%?xqihuZA@J>CiDeU{&xD$XLZIIm3#LIFG
z;kMq|T&)p$d8;3`v24;gh-tEkJPreSMxkwEna{b*@*UgVGd(Ri{=BwH?QL%0c5lrM
zD3vdjKK43O9siU*ORfj4y|wd=}lPi8tl!3ha0fom@mtan|s{}sw^2$vzLLL)|<81E+kkbDY^Zl3UVOr
zl71TYmwhuCaNyS^WDL3AzD%saM`rOKlo%K#CQKb4`$P-~jjHRDb{59CTLcVA3}jCO
z9&RqtLK_12vFHd!{907|kBMhkk;5&=%YzWh&ugJVkxV!
zPvTIr<)&?b)7YOKyUgd5Y#)Y8tLv2eoT0%{@12|y
z?RX>4;jzkQ2kU&hhMVJtC9SW68>Jii(X;+V=-SR_+oO0dse--ox?-!!a-1{fG5N7O
zv#BQNSA4s}K&UJ7;xN;e?a!I#5r4k7kV4mlN&`K|NRNGn=;?r8
zipVNivr537rw-YJKFJ-_ntga@?O{Hx`P8gx+6DL3P6<_Ec>u^KqDIL2Wo>~CqQayOO(|Fa=WY$wNs#-)Ie2aHs;m%+AtRq
zbk8_>q6C2|ul#`GB9((*0R!wP|gQnq*k&Xt>vKzWs
z<*79bBLMYq#2hEGQgf#O7aaI0ukjO2lw7nt@2vs{ur9a8!MUb!cx-ftcKV=~;35;<
zB>ddU0l4LJW>>)WAoobm>&U?I-ep39kzD%EQyBbT9OQ3>EJ()@EVEuz)DOQkR&TS>
zIA4siUh*Fq#K4^>uHAO}*Kug8Qn9+|9~ngV`hbK}jk7U2s*u!5(qD9}!JSR|MTJ{`
z`MCQgm%sI2uRTU&LUnJjbTWVIx59cDtR;_B6qCBYz4`%brv736a`-YX6A
zS|-QJ@YWnJ;#YGe724T3$(^^nec>YMPclYB4^Nz`Z9IbEzuud7AHy&N4(e)d*RNALRFTMfj$NqG2WU72+d5
z#rgG|>}Z_}q*@IJ2}z_X{gxx;a%qyqMzQ?9fd*@(g41ElYwYV_Q+n)ro#tKeVSO_V
z2SKf%;h|_#O8Z$~M4fZGR2uK!d?f2MWyON*_Rc3WB|(V6(!eKIhV&nY3^v+Uk{3YQC7}9aR4N#r*;%ts{
zVbP!3+2(T>vNtRF%
z#Q4hv$~n`uM-N}vbB~eiX#f1V>(QmEH0ptJl5F)uLL*e0)QPqv829dp@=qUG&haKG
z_&ZMvk+O;hV+W{dc9*t?n^~afbAIul3c$tYmL|HmM?ELmXn;z*>~Ag=C+M4S%&jUP1jhrlpdwn;T=_)W<`q)&7Ra!U9353Ii^2
ztXu%l@fS!y`tW09P&scYc=hiM=60i8#;Mqvw=jkT?W*{P^;tPzG+jL+NQA+5$G
zJTR4RbX|2RFNsK2ORgY`QJ%|y%QbS=DN;*@z;V{fm-<^xjD48=n0Q&HA6-fn(q?@M
zVK>roVI|5D$g7pYi5sD~IT8a`YGKMFG|2vH-68w|kKN;dBXrL!K^6EbNWM7XFZ$+Q
zBAx@G@*cz)k47X@)TRNt5~5>gevk?@7kgQT5*^W3YGR2Q+A`&ug!xq<`a(FgL!G1W
zw^&Zi5GI!;m7r%1jy*R@Y>2_3R&|c+&q-1&>&fvcWH8Grzrugjxeq=lse{xuB27zE
z7qqFp3Am#unszDNIv4QA9FF_u(^&y#4)eX)fo_&0S?IVsA6TnvTUX!EDH@0LF}
zGBKbJ5I
zwK2J=hRPFH9<{z0)VPx7ldQ^hD_owBRYokVL~hA24F?o@pGG)11tQ9z%BccV^v|v?
z!pP9UpJ*0(L_qt4g
zo}sNj9org#wD}Dh3xCWJnwml*>U27Hd=0(^YFl}SKUG#S&{LD^>iBmha29Du({X#$
zZk|%oaQq7k9w0IJD(3|IbnHiS?d+GAI|VMC?NQ3fk0_^LEOhuBPfS$oe!r@KT&yxp
z)+a2U32piQR-2m|lbCg69D`buu#ifW90}}CE~2mO^A}RYR7`_BBno4B>0Ist8K>}i
zRQaV-N~zwUr575h79NXWzD>2D*zRinCh1lPigL#}vIHGIx)cthAJSZ>`O;{8xtxSb
zeVc_Zvtecy!lXl)n?V2bjtsz_Gne<-y5HAvj*}VCS=ktc+c(5P?_ic3ejTX3hVGUn
z@O!QX-X+B_))6w~dSb~wO
z@)tRx^+}^H>lX!)iK-geLZ~jl$9p)hYFI*eFzGkRr6=bjy~!4K=7a66K%O3(J3O0f
z21mli=w%BV!TqY!OJP2@5Hshf`@+sUx)Hvup`~{8o}I~C$vZ$~X(Lf3G~~bgmpw+t
z71FG3B{~8hq$KfZQ34>cP=5BU_F*#vQi;C}sff$F?Q`wJD1-ML?7v)Ht{iSvm0}pc
ziCdW)OlU)E1jafjF3$Ah>jy8aF)!$ehSfkqGqp~TaT@u^_yMW8Fy)P2SnB)5=!R@2
zA|qNjZR)cBH-QtQ6UG5|#_iurFeZZpKM-6SYC>UyZ>I6Onv}5A)#D+li%KPqN|VCF
zf>yp>#{7I}K#y?d*%nR=Yzv1Rbo0U(Q4~o@jdYNi{6v-n<7fj_h7N~F{clamz_AoD
z`FZ|x2nAuKg3PFvV$V533N~dNV}p~Ev8iS5tw*G`q!F;R1Ex^8ii%_1t+$`z!}pWD
z`n&(sz5o4U=c5W9?vp_8LHl-9Qsg<6FEM}oYe7uQn-dd?%yL>cFXtTP@!KQ
z^UR*S6RI2-?a3`AD;mr7l~b;mCzkx3KCU8vR8%(ch}&pJ@s|uy(Pqy9>TB0Db2@1}
z;riJ)lIT>U#BI#@MlYyD6+}DmABX%8Yv1wt4)R=hs*?|F(NFI*E$`Cev{?%LW*D}o
zf|T#>%~@z`70Q@ciu`a2<_IJcf?llndBn17Mp@XB8(W+jS0Bf0gdh!6jaKW5bSzUk
zrBuuZNEN&%+KwhgXR*G#uJS0GP(+rohwaXK_@vjHgs+u+JfL@k@2e46_j%Ao;kP@D
zig`|9nOk|ED!+cpTJa%g4V_{pi>0NolK>gMR8W{kZVQGNc-wNOJbBU7c5|L-*lJQz
z*FYp~;Qt=Q_0{j+LyVcuJ0br?CmhT>{b=(H+)fMYv>_s|5u>o$g4N31)f#NS+~-99
zz_{9oWomb*3Z=QqKR{kvtrmaRhVF7>S-~)c8XYM6nVx(Li-7wp=b@&{T~MtbF{=Yv?#9RcQ+k%H#qTePa%YmQ3U>885}
zy6pQHDm|Pe6sfEEa+%Ln()%`i@9~T)+(e8W6@p3RcxQ2
zs1O9)wG)X(a&H^-(FslCe@=F+
z@b4q}uISC;V~5jG7!GJHjhdkCdBtQS>~t!cC{=miO81JD%wA*7(qg!%3R_n`V~>BR
zhbz!(?W>bY;>IB!fo|(m>t>C9g?~XQ4$U+?C8=8o1xhe8`YYEa=Qa1vSx7S!zDmc(@uw5H
z+Jrq7`b-}vHE{I?ViP%OJg%;1hwu4VK6dJk9k?{i2TU|sCg-A{N)gvfnVqST*M)rV
zG>1wXjI})Ka>T8=#>CMhC=b^Mh@zLNosTpkKlb9X4+rCb=r5*Mw6p#TT5DI;f~~oH0F3$_m56NuN~L<->M8ti8E2o1*Vd
zQ_K3f^w?bFg-mQ*&4Dnssk>&S|5=}dd?O9RseiGeY_gq{Lzx!_3pn)Cb-g>*J>e!W
zEXoxVvgJiUcuPrMm|0|UH?TM)&XIL!yI)9`SW2)laxC&|5oI60QtN8YDLl+QVpBrf
z$ReNvqh-@qvhP)UdLv~;f)GLT-I`{!bpAAKUIABWbstP5B*RZ7#bv?t4oCMQT$m;~
zxQ#7Vh@j*EMn3aI&zXbLwK<1G9(t
zuK_=W-3u$hIut6tM)4Rlza%dfVibQEuS%?&-`!oCS|5kn5Kv`gQdf9T6*l1fPs0ud
zi286s?CPQ(#tCg{e>95xsk=;pMttkpdShpC0TUtEG+FRgwC)^W%zm#YNGMxtQ{CPv
z;)IhFBf`0oHx!fqmBSJz5Rw<
z=~K!XI@n2fcXWR_2=r}q4)8}r#845SGS-V34S>QzM{81
zMh^{{%grWu{{7xuqiNvH%ija4zS}nYmEK5DPglC?sp=xpu
zEYK$Fbn99YG&Z&16hKvI3-(&!oX_VmyfGz(3)H$)WwA~!8*Up-M~{MAm^fwDSJBvs
z9`8R#PHswf;5Jz*KzMa;PbS`fIuPFN-(LrUToEBRNVu(DptOl&rwwsF{Qlwn>umz@aV@f+d3
z>UZiPASn*{0A=Pi&~^flUqxpUB>P0t7L5Bf4o>~d%hyzW)5j?4eYTew_8=-a#aU0G
z!gy=zygs^kYStNd@oLtOlc%F0QwX7~Z#^TPgL&sezAu)amyAyi0_;DR4~9NX9qk28
zEmUQF-dp9H@i~54`A~C$a(oqX`X8F#egoW_QgM6+pQCnH+g(46&R+Rr(q{Pf`>txG
zi!SR1!QSE9WkecFWryUG(`%i3AI|~BangdV2pJ#*d`u%MgfY$Gv8YQ!JIt+MAnud~caCzGjgqBCNR9PX4MFUv5o+T{U1hxp5Hn%1+81l{;{Ve&Mf_XqXKMk?6O4k
zr?$*{lx}2h;tpmIy7qfG6FlzK@)59=_>~8Es1FU6)s@FvI@wO#j=$ZF8H>7R|LFRK
zvPM35P|S;icQCQR0ib$lb8Z*Q4n-KcT;RUszUYu#WvZIOv!~wrUS8j=U5cf&-b&+V
zzZYz~PegT+wXtRWG{AjkNjpaBG8VloVO#2sA3ADGs`a787D0Mg1#<5tT4Z;~5q~ua(>JEGR@#3Kz
zQAT&1lCcu_9p+Ujh%4FUEpMqX&DP5lot}*$h_}*$(l%3uI*4}&EBuDJA^X{WQ)98N
z&FhH!@M>TDh0Evppm(dHx`#oV7k@Lz*o|8Ln1|cB@1+pmg`(Weh1`65pG-Rq93D&P
zg3th{S`MKa!t(~WJykp&lRmqx>FuNODfwRu;6=)4wFJQlhE){3D$iv;#@V3%7i@!I(kX5H`#`+SC-*hRNN{OPzhx;ty
z22FzWMq)Sb5074{>5uN1^la$igHF_nSbRqMj;=;dIo~m>o=56ZD>
zXWxl>9(^ej4fyT;|8F3TZC;49SnxiQ$MLevj}PK$-&d8!uQZyEG}DwX(}RI5eRAsN
zp3P}e9~jFeC24^kSo3GOH}bQeM^=pUs^njEvtSCD=y9cHx<`EDp7myL9--f!d%VAo
zTUKgOTD<75ng(EMRVfGWBQbfaAMCZ>j(|_a8ory*nxS?Ps9Ua114LO{VJ!C8UrXp}
zohUmCFwu2w$G8I>HNRlbM6W4KsHz3Qa*q$m7NmV6plPGIH13JRR^Ro31%Gny@7$L&
zB7fifG)w9Rfmxh*e6PTq1j_#C=v3ndBzS>n#V-@s%!MO(U8Gi6`8SB1o3mjZOTZW8_Ac(Y`+xH{3Pv#XnNM-gt5-nk+iq7p}fvyr8f~XUDSss(nCGj
zwKRQ(0*ipcbh-;vseElPg*TZb`bz4l`yejG-D2N}7ODP9zVMa90(jG(7niowtlwR`q$j2Pp04H!SyaYymmie4DGmP!b}LME^ymkZh8vOE{RbYRNLmhCV4$XJ(z;a;NxRA2Ti
zvMu79(9ED!BS*KEqcdC`(eLgDS_h221tHrcPrxd(Ypj^YyJm#f&~tO~qx24QKZ})S
z(U0nvI54}#=F~U{?V#e3YMO}!5WBng6ZU^QwqMVjV+uqFqc*iPj?g2ka+-;EM&*#5
z@5W34MVd+LCM^xuo7o)xPvj~Nq&dd@
zYTpUxug=lA4!J{fhKY_f&4v5gd*UyDkaEpIl#
z!R9+_j%p~TN9t?RqS-&nT+?<;fY(*@Q0&FFTfaLLNS3@;Hfk^0Z5uE5XHAdJv+QMM
z@ObKP=WQqc61UOUR~F)nxG@dKJ#LwAj(0vrs{e`4&UksCd7|eVE+{N2C}jGI(+OC=
z`Klo7#oR&;_DEoAr=~%0hc|*_^P@~kwFyPf4$}UObMSn
zXcyph0*3;Ypwo1hQhgEEcK$Id6_{xlumDb(*EU3}Sp>j0(h_*vahr?|GZ
zhc@C#+o70|D*QxAWFdrQ_fb}oFuf#))V&C=vE2@rGat{8l
zbW{OvDRdLlje}CgYTTHjC*s}pL99pc+!g|KTi-L3z{P8V-PuTNgjNM~h(LtzM4fj7
zDrf#&jU{Cs?r*=*y!SkpZIXt(Ma60
z{J&_QJxz`p!So(@klw)w9NO=9+f%$o8UPn7Q*Ap^^X&d6*&E*3s6(i)SlkF!Su)RcSifU#b*
zUY~%d94p{tISaQ%KI`2Pu?(vv0+A~i5_yK1m|LI}UR51HA#|76kJ*c`l##bv?M1|1RpC#qGik*POW5*3B=?ysxf6I&xUc7*bwMX
z!YS3yz4^nfX%Uuy75SIY!&qs@nC131TMM-2JP&4%b3jR2DjHEy{q~>T$`?59Nt_pA
z>NqQSi`Fc)w)?!y89Ee0*J@|dIiVmZhp%0BI9>UEse=*u8W?L97&UWNoiadMwxb+Y
zC~y7D>5Ee@F4T|S%3$Z%xGHOx!MvLvrg=3NUf(Vy@(i1zXTzJmqVjL{5b8mm3Jz2O
z5qy^KnHBbz;~HitkU_&1DW?7Hvsz#Tdn5jOaS1b#>9la~;UQAJwXw~Gf*3^VK($md
z(WGFVj!Tjx2^jS*>mx3bGK;|s6zJoU^#)FaxdAiDbCoiXCNB-<=(eU57|<-E!+t7W
zKUYW!x?i{rP`n!k7fhMpU*53{Ihe!QN8ZbRiebV}SF5d7K8P(dbr#un25mKmLGP`K
zb+0ZR9KdR0;Dvsva`w4+SAh-p0w*bN2-QC^Y-Q8_*S#)uC5AN>n
z?(XpNljq+1o;qjeoc(KNdb+y%Tc4^ToU)q^wY)^Qhl
z*9bJ>G%%ZkguRlKctm^#xEymCtXMHV^EQd1^l;;%qF=hvXIWxAy1?TqO_7-I-*f1{
zI~$5;d8+3*%
zc>GsqM$<>Ibyjz)?z^^}I;tR(_Z3WL3
zlYs~fy~rlS)k;;(}T%CZh0InxkzgVglNh}y?f?(6LY@Iw58@{E*
zrFe>5x9uuwL~}shZZ#`_v4r;)8;&YT4=g`rPK_7Q*Oha*aHIq5j~rDhZK%1FafAVt
zb*NFtmvp8o;{lkKDMr7%uTZ{0uNm7&+TQlG3jIGW{H{onZ2nV$L=-W$85ZNwnbYff
zu}4Ke*F5Bwt)^ym-mx`HV8hSVUdAi>^olP6HZcuq}=boGFY_y6(qKuICVfc4f
z^!2{N&!x@bF@EAeup5%QaK+l~5{|>}N=wS#u$n`OQ=8w#m#*ANqu3mcK2u&B-l8jL
z8~1XpW<7AW#50!akY~;b!MnC4&0m)jY+&zhJRHw&{!5hwvs9+rWq(p-iq^;9r*#tS
z`^sWfglyDSkY~QPxO2n)^2kuUzTk|?7{m=fgkTwINP8$r#G|O8ZRgU5>A}`$*b?4s
zoqO?a%{6|Unu)Q(d}b=TdS$twJ=%>nu^P#LS9Q<~^0-N3!D9AasBP9$h(Syew9fa_
zjKdGGd@O+F>y8-XKA+D@b=(B9mnOxZf!`q!|-S=e>Q(SuZB

rY!}d85qtOSxQJXXZ;NL8oAr@b$PTpQ&=?Q`EEIe3IYK*sS)b z&wu{5ZbM0Gw-1zLfBcpWrlVD8y*hsU;T#SL94O021~-Mh)ND6Lx(s~t{b*lNbCTQvJxKSFls$dBM_8>^`{c+H4>o3h zmdMu&$SnG#X7}F>BbkIY3J6|q#!Lr>jP8P>kwa;Sd8#c-ijk0a083@u*ccyuD>Ocq z+Zw3t77{${9q$H%p=59N0*txJ<<@WTR=0Mr_cp3onh365tfco@+!hO-{x?Mzzprh- z9L+Y1NFrAj1p&F#6Ze-|NS;?%Pa)NVWaz!b9utDw-gn!uNeHRVF`=@}kiSH;obwI2yZNgGxdaUQigIePhR+W1 zFUGdT!Rawynj}7c6~e7aNTEP_W!di7is9@i`SO*}yyW?hX7MT@viw7mxr66NQ=I!i+fVIQVD84k&{>&t_MXKAS*1I| zSn#Kv(4H;h@@ngeX+25QKB%_@-8n0u7?x?cSC3sLF|#$r#E*FD!F`yXHluk5gSoWz zHqQ`Qycasm`HqiWLeaWCv2}Kphba&NncE*ePfK)ZA#msD>?yLG&8|mj60kfl6^K17WF+HnH74c7TB`xw-|$(ET4BaQ>TC(QG2NgGm}Y09 zS5sM-JO|Du3UJczB7Jj3(c_tG-;Cg0JrBRWVXv8c-zDU+Gg)$O@kA}fza|vBpq|7R z-jy-Yw5jW&`zW6;84LJJJ*bRM;CFhPrBLN{ameUTh)MD(R;adXEF6co)gTfzYzlW+ zuZCoe>-fx;y5EF0jHyi@bS7+#lRoG;dm`^QQ1O^u6m}5c!F`-h>D7JFV7 z@SNBG{AsFAl}$l1)bcdYEmQ>=(2Er#D|(OaYoNZK8T=ELtP@&sFkh=JX>M%ndA$Q1 zdv(!mmoNQ15m%?ZRJF~-dodoKpDNhd8q7n3&CI2}sUsy|kXQ$BnBaA?o!b}EOTBm9 zOP!fn;&h@VC1-1(5a}IM=MUDK{v#{0KWI_rx**~~1N@Pt_-G=HN4L#M?$E|_6g0Ts z!+*k(`8zc`?&$=>Ga5!s@$E6x*{NMb=H6K7pzzHeD5m-DwCgYPnFj6r1!%(aVLN3a zi_l38p*A1N{#h|Z{H`EKH9+U9$2rA-uc^ghyh zPQy7MigTrA*YX6hD|)wW6G@elYTqwaS%VGji^%n&$R4%2N6c+St_E@S)Vk$N!?X7H4=678xiM4~C(~9l zJpB|pNOf2z&Hv1cLt0?HFer<=7Vj!~GshLE+O;F|A70wr3{l-*k}NSy9b!4<@Pdox zC=0MbV|3$I65BCi7%thb?I)$o1q>nP88q!H%v}z5Mn%zR7j#p$xf$}n6QJ(z?j}+g zK-vZpO7#CH)Q|Kpwk$fHQ1dbJ^#?ycU8t7pwbmZeO@1FpEy({iQ1AdyAGqX6vzc>8c77PJ*D{g5!_NmN%gdG4t(XlUNT$* zeeQ7$Y+EunrSkQ3lHJ@B?qa^rFapB@{5jf#$~1TgnEs)%W99r`nsDcvMY zSue?8X)ckwtLZ0@FOVLYg{HB$)ZDZ*ZCi}bzi9xtI>u7yB<#`rVC15>`(B=SE4SLq zLCHDIX!D8Z`Q|E6XMv7RK&Pt7 zB)AKlwd&Xr!Mfk}7GF*;E;*Hf$7F;nBO7P=ylH5}msW;fI`?h5ihkX0a*tLK=_}qv zOA#>9X>ua}B1eX#r*$aaMy~0$+{i)``qYZNkTD9%quT3p@nwwl3Ks~*hsV2cr&L)7 zmNUvYA^c;)38^_Qc{Zmga58Za5&JmgpD^v}P>MF?I*1zJ21mx{D_x%1|JGdon|%NV z`gZ%Zc@YDPJP35iR4AKeM&fLZ`sDqyRWEW>NfAgV1*uh=>_ne7yt(ZTAAbG|-4bT* z&XwS4d%2$!{Kf>~9x#oBoiaV&wAvI{lMIl6<0I0LN6I#wqiZPS^fT{zwr#~)z+0I= zoSB$d;gcn zllD0yw+IP0mXRh>X(m@2C8*d6VZ0gW8X}6%Mh7;cp2zd-*Sl$g7TGy z;5Yt!#9Lf1Q(QseD3HTk-_Fo!w?au`|6P`9@#im_@iohErP68BU&KOqa97nQ{g#S= zzav0(c3M4I-2eOV)jd$X>0hbCmoa?2&*VC*^g~`MnnoFPY3;Y7P3qTARZ9z1{{?b8kR# z6Ejd5=UPBs$PN%hb_$udDnUQh!u(inmuJL5R7n&RqkrS!j=9->zA>la2x&N#d@dRB zYB_jO+P>LFMRc8c)sbsgF^f*j8UzE`e9rMyQNj!Mb~UleI1X=!)J^4-0V%@YayAqV z|JJ9zWI!__&cyF1@K>JS#iz#0rmuv6PMkcJeaK1?pyH}l9lF12a72>u)?ft#VT^QrrbBZ>-^ z{(Q9Z z432fU-RzGwIy7!{q-NS_3)aea&^(b>m?_ZgTF4zRgi*0a50~tPH*iKHD$J9MY`{1r z+>kYI+}|7|YKx2T{@XSY1+%||7H{957RAXL)ctMlxX~2pPt~jdE38Che%Ifvsk{F3+|gXGex#RZ{~&miE8_!@b+{@p6`Et@GdK;1$`t z68d{~<+K)eKr5dFDMO*@I4akQo3z@z@>#xvFOA3PoVikLWa-@$ZTF4|6_<`+eo?VZ z!cQr9bdflVW|o#kScB5!OhYN`ASV@pFiZ4 zpCt`-d~KVd01iz1J{=lcMcG7d?`c4I3s1ymiQP))a(Tl&&o;v-qm`jt-rK(x3v9|Y zzN7@XOUf=~;6K>Zq}TY9=ZNLI)&eSmi;d)ykDw0!Yn=N~yNvqbFLgH>P8HDRtFE}& z<71`Z^NTrZlg&42LbLoL_b|OpE$l(y^;EZ>j!TB1`h4@k5O z>0xd|LHFx*P6P8VR87`gr4K!q7RMWBafQ7l1K%A7f zUU`^^_ub0;e}mPGpddVpJEhSIlgv9NklU$FP`ebd3l9uI9sWvVRsf9 zaOGY)LcEaRT6Dv1-p;4`XS5EXP=11)Uze+N_z3vdQ70phQz-)ME6N6)s-ZtSnPpx} z?a=)Ga0?@(*~yFDnH57*7+2!cW2}4*-*#iCLAbm*{ymdis*Ijon^7l3+Xt`<59B}0 zZ_1-yhm+u#rq*RMC0C_zdl|xEl%$|QO{Ewl&n?(hB4?VQW<` zD)O9lcn{VBiAah-2l~i=S}tXdQ%FFwSo&YLV64_~0d3m6>=}u2J*%A!K=%r04GH;< zvYCl%U19+peXK`3zbBC+r-=T)qxuSoFqoOLzvo;EJJ_zVd3OCXTbG8)d`reb>L83^ zwnH6*cs;3f zI!>xN=sDU4T0d{z#lLJ>!%1sW4#p@w4HhsqY#ts6@(0Pv#qv1i(wVSbWw7*3%O=5; zI9xOe)|v;!x{y%cKtv~rc{_#BlYFAnk=J!S0Kt_mjMKjtgZB#rgpJ`&nKS3Om=<{sNs6MZ?O9Z!$thy0 z8VVifz*NN7b`g%J(zPIY zT}tDYv!buBAx9dcON+Zhu#SWA2ICF-ck)Soj8#gqsw^&fFiChMs8y^8mI$^S&!pmF zdAMr0OLnyjJzTQR)zRtxa1B&TtJRPI)=Z#6J=|UR5FQYr*OpD4~$|oc%Y& z%i_3GmvSUJF`bdVXA?EUYSRh52H`Z|# zkT#={msUM({}x%PD$mZE{mTHh{19vNc@#70j6}FL z(hGyDkr*>nn8ga#B}NP$;53k<^ENB5yklf|b}O zW}UGI6gu1@ksd4QUXqXdtGouT+_9QVB|eoaucI9af051fi$Y4^${Bklm| zs8x8nXk=TL(Xhno2CZ<{WqQ9eQ;k`VcS`lQJrUtSnOeTwcHcoH0wg^jSek8AhAezo zETO=@|KcX$jX-vG1xyUTwP9`$c+f8oqvzR@cai^m1zm*MLXtg@*e^L!LN-frjQ$rK z5{EVx6V(DO^Mmij52LJUL)H^dO=2U?^Mi?1f~LC3+2Q=MH&vmD;nde7v>VzDg=a4@!4D{=jWL7A21QuKO-N*jS+<*m5=hx zPD>Ix0~;8fNst(1|G?~JZib?LHH?;e02k`j{3W z0H+^4Zy|&_%?Em8cqc>Rt@9sAnmr`TR2287@6r^4llWQ3;p2MjC8J+V4sIRHRr=K>8gO%5*}eMxtwou9J%V^$2Sh=RYykF1PfVcxnm z_=xO3Zs`Hqkj+ib2J^V8`)r|kR4n^E%(RVbZB>$U|W8nsoD@g_tY>j_! zbqfuwwu}$UnBY!laoIX-oO<>imEQC%lb!$x>exnm%k1kNR7dr-3v_fV_-=2?Dge9+ zxSrm=XgS%6^^N1-msZu7T&u8XwM6R*varoQ&iPeEIQ7PDlnZvY)xen_U&yuU`1_!Ska|3H%N0dITmA`%u)^|35JV+`4v0pV%m;0=<^_Qh-nl_b)Vf&^ z8NX*@iR&xxLgH;^1x-8&FU8sjc#;D_lw;;hXy;Z_hVgyqZ>gdl{6mu#|esveDq?~AeY+j&D>OY#2mR^fkqy&I9?4r;$@bv)lmHkNm8 za-%#@Gj6~zNzEYk5gTwu61ii`;7Kn7NMi1O7UM7CQ6@V>y1=8oleO!UKvr5*9{!S0)#0%Ha_Z?eyc^Bxdrk9Ct9djy^6n zhD&*zJQ(9S`&5+h%vM;2l|J4}FH)QbFy>`u>U+Tt)KQTdrb6swW_G5t(-Aw{frnh^ zOmm+#I-Rs(w$D6?jnXweU39QuN*WT(RaFy_w#^rr|FD_$AY1cvI;eEg(a#x-l`;uw zAlG|8%L}8EmNx7h9L4=e9yDwH^O|#p*=jniku&$Y)&(!$Frl{UzIc)EYWjEqthdrG zKwwOCv-UYq2U=BpdS9(sxEXBhmD-L@r-jCdC4BF}#hB!uw47d#AP}CTg;F0n`$EH; z`V-?wPQgT0`kO#Vb*pIc=4E>X`!DCR61=^77rEBR4WG}>raHto)Yf<$zq6-IoOW`x zeYRKUZ%Z;UziX}`vAl@~*sTp4XKo|B20#F=&$4bfHrD+Q1zEo#^aE>2QR=j%WHLAp6v(Q1@A-$! z7KGmL>DPTVd`fz+8<`)gaO7+G!g9cxpeq;&@6RGs%#?l}@g@Z&eMj)MhEjJ=ZyEHJ z>4FIC(Rj;olo{&0%S`4=qwwq~=+>D!cPo3rnV8HGk($n@rVnN&op>+uHhxWtJMC`ue3PCd75ow9ijKwIS?3Rd z-NKQ46cC)7-?zG~Q^%d)w~YJeQ)u+A)NUikCR1;#)OjSg_}iY$9wl@bS@39~v%Vgy z6uFjv&kW3%m6RAt%Gm+``lIuD?gauSIb_teQVa31(|G32J?Ad%_N4LkvD#WrEZ696 z;7miM5|z2|0P3^DcL@YBWNaZM_J;SPel6MBX9bke#$+R|$Ik1w`!1C+b81=0UqfG) zvhxF^iBXa%3;d{_uVWWwJ?28@o>!0O;3D+PFm!~kzsp$f6;$C`l(#d3`2{Lhr{;s> z*;7E}**g#^u!(UZ%UA!zU?@c7MMDDkXPRr9=!CfTdowP63G(bJmQ5qfRvRVFN0xVk zG))>VBd>Z0R}QVIt9NVxGwtY&LlhDU{k1n~FxaO4<2TwZF+%9fPtiR?Wl9LYUNsUZ zOKEY6V50F`KF=RWZwjA#iA_DiY*JA7pz=;Tv*)Go2-3vuX&mCR{X5yrMyPlO+jYpB z(l_m2Q!jlb{Zb0v>fUN!+$6aH_~0Vm(8_6EX8N^V$Ow6iLfY$da{5YTdMqGkA1g!6 z0-U3bSvwaX+p6(FOyxdZt0C$cG4uo^!B2IHt$miw?1r7_lvNHN;o7gAFrcps&J7eM zC4?#6okV4~!iq5qBK>jhbZ4i!r7U{=DR?kWMW*jga&4{)jcUX!j8B&HMMsb&-|Mi} zsZJ>xKMS7%mh1Zv9*^Ywz|uC?0CJEWcF15=4MTXKU|w}7J1 zUFq5P5s!0sISq}*y$&(gSmKV72N~qKVhfF$Mo4FEL1YA}LH~-6Va8q70E)qWO+ zVTd;DDkmKn3?`65rIN+Ww_5bH8Qtl-1d}bRNIWR45>(>F-lZR#<3gpkX3Sl|EN0TS{ZgD%58(G!W+at0-R%o$} zC{0zuCslp^T+4&rV5S-z^dihmtDoN-T4@~ z#d!AiYm*3yCbrx*9+h`3b)W%BIb5LoD|TX z=%|0Y{<>s_eQkUUr?)Yl+}hB`%~&6=Pp54-R0pk?=s3S`?!R}!SKqT!d-yQqw_d(g zzay0SYuf)Bf%~<}$+`LqSUnV}YO2HS0YKIje0^5QExlc{l@iXMLaQRb+s^s3Y@XDC zqN(#2pvm|H4@n@Nl`OHWR@XT zB^ddbERwGzD&0bP4EeaYP-;eso|E&ty+^Kmxvveur`_Wk7!@+j$<^myY$CHs%Sv;7 z_Gslrb`Ni^R%y7yT#ngjHfz5)@RplkIe)fd^t&#NzAUNBbITygB}?%U99f@oLptya zwTqd-u{k!c%J`Gd^nU(GaZxB@dgFcOWTjn1 z3kfDS-sN^c*M!ase`d1+{+b8Wzd+>Vo zilkMGH8*OVFL12Cb7uZGOWJtG$q>#igOcJZc%8gv@5Ms}@+4bBh_0XT?6wCQld4s4mwWvs+LS%8FYeBr? z%zj5a$Mn?jo!k~>+ytP$UISEHJn>IOq<_^ zlZKPQ#WX)U0rp&6iK60cw+a1oizzhXo=v!AS|7LE`1(tmD9cDI; zVNh2SjtQf7rE0Z-Yj@3GU*kIq6q5W=VN6Q0Oz?AR+FQ56P;3(kK-;o9$Hb9VHMLkg2N-MbP4I(mNw$Y=ksqq z)*Mdf4YIY^W|w0#$*GwEBGyp#5l=7 z{;!i*3De=6!1c%gQXDRZ?<;YTzu}iF=LS9E#0k z^IBw>yI-z$MY$d>W{bd+f-`9++Ln%wS}tOUnim@JA~UBtiejq|*XVG-NtG@r$VOGG z+PAWeNtRvc^nQ~KjB_p@kAbrCpA2!xB+>+*DB!FE!wys#2fK??_bq!p3j*?kAw`sy zxr&_XmwWo>LDyvhE3{(Jv_AbfFAvv@QCRaw8&z;r3C{1PvvoAI$rCZTvu@W4_uc@v z+1F+~t68i66aImQ+7!}Nnp7;BWz3bXrxb$mfH7enkcrwcmXS{u;1?)Kx@`$}2@>QE zw%cl$NE&@*Oe;4xU!YCByOt;YdHzeY9Kd2DQr;tRI!&4on?j!APbk%$k&?;Zdl*?H zjJ`lyLTG2I;HsJoZCLbN#YI1tJru9ip;ePc@rSr5zL4OFxmbu>5~M9PjQVgTDa~F- zOe@Bx>B=EMDhTNCG95)}AurbCYy^)fJPm7!O`uj&Tk%0+M7@$@+}|8ZSm==3+Hm9f zgG;KTt1yvWWA9zY z9GA_8GDVsJEAJ|%KbRdBvp#g$pz~>8+~_=8Z+Q?7!;}eestD^#*%!HWBN8r?sVxH` zKwuByJXI7|W>Z8Dx6m$>1<_@df>mZ{EZ=%r7CkKGTi_b`?j za0<9$lOStvT0@vgv*-4)Q8Up#L))I5oj>8R+-0 zE;5Yw=oZ8%$kZx4`YeXcvdRX#IZ4ieHg5JieiR!p`u1wRq=j=?tx(09lVKDh?Bv@F z^!1;TH6L?zKtAt-Cn0k=S`|qdNQSULSDJ0HQ)Gy*OOxht7^x$zai~?r^f5?Kma&p7}6S zkiC#+x06%{%CtS7%3xG3HHQ%2QYgs(MstiXCj0lsqiI85GgHzDq4l_w**u({wm1f7 zl>?YFGnv8DHeaKj$xEvN1s)+OmgMlxlVHR->k;WOPYs?S9M}SFh&SeHmG|%T0pBMW z48ukx_e(~sl-{wi6@l46`~l1H{Fi3TwJ73lamT7Y3u)!(rUp!^{8tH(Xl&sZJ~EKF z>8-=RBa?n2P<|rsw8>b?(M7>TZr1m=o;ZGh* z=%axX_q(+zaj_N=OpR6fT`LiPrY!q$^B2$74)-d;pzOeq1#-eNS?HnRohhv8guUV3K-Rb`U1;B*Rrq2Mi zS95lT>9(7B#T!6q{x1J`3k!V%36bo3-yX zl|z@W%^>q7?q+Hf@vq){)gA{I=c^~|q5?UifCs4Pt0po!;Q*L2w7nTPBZ=Uu*dVgX z=$GLv3M*BagAMg+AFl1}P~x2e3VpfomYR8bpWF@2rXDQfq|r4dgJzw#{|S@^B2E&5 za^lF)f|YweJ;NaqMnkstMPe5+sTH=8*Td*U+Ef%EaI*uQ+3|k0wnOkHRdKBD{q*rb ze4iTc*1pn|62bqyg$Yx`?s}k0ZG+jJisxZ?5CfU)u3XF|k?^yej5YbPKAMf1v;`6z zte$BpL3=tzv=P02Ne(Yfa16$3z3}}jckTQjsx8r7><~mIqjYm!8Jz@l2JukRg$beQ zOpuFzzE*Kl_;m8^`G+tznQa<4=D6KVuZ|vr3XvespUVQ_y&&O;N&>nb(!6=#aWnb$XFrkP$G$#LeJ91CKP0wFOK(-9@+ zY7sq87tU#{H1-1%w$JETWcalZ4f+%yKnLPI?@)l{dAZLXub;#IJ*)qvq6zbI0r0LDG`q!P%2bz~WLKAd<|r?yc;hH=_^$JEg5ynf zebKR%UZEPyp}|b<#p$m#YP2neP+=}#Yj*D&4^SCuZ6<3t)ok}Z*ncz0U*+^n6OPIh zRy7+2^3WdR(KDK#T_G<_U(0H1%w^C*VHh3|n~2OzqMhkjqN0gI6?vMX@m7F1RrESw z_RXKXDK*7jUv~YznK)mtIo+fEkk{f4cASp;Rv5i8)UF=O_GDW@vvZ+IU?xX?fKgfj&IooQVArlk_>aYWp4~1p zwLeg32ssQK^QT2fl<9Jr$IjqcY^(Lz4DB}_Rkx)=W5#qId7+29n*?c_pE|BBwz?4# z=`Wv|Z~6Hkj$A)WR$Lgke525h>3V_ES)Ec6#+k_EBm`{;Qr9~?dH1RERC&8aJ!F}u z@A5v=iKl)>q?y21uU?`(s!o&4W*uOmf0%t(mMo-G zD|PlaS}p^=kF_+Ub_`{?F5Sco($=f8)*8OK>+%0=eCQo>{f_N9V{&cr{Zx9+rLXU-wh$vz|g!14PA}b#lk%>M;{F1ZJ$qs|d{*Yv` z{w7Tddvg7?bSHslKg!hft>ELOLPw_#Oe^{=2$3zvd0FW739gKppCl~rId+`r+aR{? za2e}JJgRCE@Z+FL9b zgL+pArxz-Y({VCQff(7Ij#XTo+%rE((PvX;dj0a5+ifFI*@#lczxYi=^PMcWdV=kR z^GA@IWbPrS-s`^)ioM5%iHl=XXoKtDH^KoJLO-2`oIVQL*;rK}nRb`m)S`xFOi z)!M%^Gbuq`UIATehsIs3?IrWYZy~^?9@{Dm756;g$v+qs0~9$Ch)baKZzC5KO9ZYk z3HB(0Cy-hvYh9ogBG7NKYXFm~9-g8nKR6e)XE%ic)vY<<#ZSd3iB3=&Jm^B`DQKuz>fF|oVL-w-ph z^$!cMxQOT>L)YZxGIUmd_BY=lBalrBRJEDCP0VXat-uK08hQT{{s$tC4OXMY{n`rs zW3s)|bIp$~`Sv!Onx8v^Tb*aXOnVcGmt;@Zy3@myAfQeMqQsuVXZDCN?T#odm1vka z5AkRl;C4vSXmfK|>GNV5I(El_ zXFXkTUUg<4-^h##(lz~hKdinkM;Sx65R^4Jw?B%QCC_~iVW$%NTH}< zzK16!*VA!1$x0(FTc?F%3V_9U%LKi0V6_=FA&ueU!6s{@fAf!9UIsNd1S<7e?|e96 zz{F{GC6XSh0wdgt?q|mV7i*fX&Q=xg%@;PR{Cg3G!bi*2t-r4sr*n@c9gHds$PD*8 z7DF?(I4sy|z4j9}fbA~mZ_b5DIw0EA%R97G0MSiepU$c{(Y-?ry3KP3jZ)(uH=osJ zi4C7?@q?%j>S0lh)TDQqT092l*Ux{WE^elSdthp7WOtMEHwe2l+c`O2Q(1ZL&cjxb>**yu>K&AMrv4#{dJ$xi6owh6V-}TF zV>X;vr7mgbdXra)VN^RP^9E zScFHaDgBCas|ZT5=a+-CS4d#cjct?$8nbvxGZMcKr;n=77I5mc8^hs#m1HtI3VH)beN|J&cdY zc<6g~!x%vJ(O|M#?Ef_j(CB^#!Nd{Byy$S-+AbaYRJfyhZI$zla^FPV$XbrM7_c){ z${)V^^^7E6tT*jkOLcMi?ng#uUcE;sy()}XYIl5C27fTVz0hH4BC@r;Y8n#^Cc_tl z*P4&`#{z7L$2vuuzvA5{Wiz%fl`11vj&_ovhXA|gUN;Y}nLfHFoCP2&uq=?kJV%~i zxa2|w_XZJV^DPlC!coI(Yr&qdWEU$#eVScN?%~{~T@7WXnfS;R7ZH3|mCj7$F3K_$ z;A+LyPIj5E9~(bRFPHlQyfc_gmp8-Hkrhy!zu#8Ca`;>@BwaoP?1$d(DM)Lz0rbfg zD*LVra00PdDm9zjuJ}t_5Ibv(^25mMwn!o#=g!vm-q5LxGuSg-De^97oOpmUn3{}^ z*Tls@>@^qWT2sW%aHB=k5iHI_-5^YG_%nI#o7>c$WX5kLbEzm&SzNYW8?atAvd2M9 ziI8?)>7Dn>bVMcL5($`t4~P~=23(3yXC7s>6GCPW4scDp7PDDABuvVunLbsi|zpW0nga5M+>zoPcjxxPJ_YrnW)4>_Go-L^R*3Fx=|UIWOjdVmjRTI>ah%XBi4{B5l-Hi&%Kqf>2V>dP*6?^$mX ziy0SySLNz3x3|wjLkc2dIUE{m`r&SOh7dd%KptB#A6UP${R+&RkrMhF(%?YJQ{QA8 z>vIi_`n|%pm&nRnwA8=_bKV$R%FgERN=sMEhkrw_((c-5w7X1yx*4W6C0i;yrPK2?`9BpUu?bt3JJ@MWcF zuWG$icq$lIET@g0?WNe@B;L~jODKWa$3}?XC6*8wD|LEzlb2yj)jhyck9ChZ9)oiE zhl{gNH_lP7+{&#r7{Co|T{*PZIqZ=V8a-1XQi&5*O-6lz4+X!#(!R^&@F|>ZPAbc& z#=8)o=Cl6h@%wgD+h?K0e|n$`6|OLT%|&K2db-v)McR)B{^6 zUI3MX`jU=8&w1(2FEIBK3uS>P9933&0>?+%iR)cXm1|y96&?||4Z3WUTXwdJWY0bZ zJR_L_CsXitUO;ybvSo>i$~-W*-KrZ&->v8Kxx{quSM$mk@y;i*(>mPgh+2o8^zk*! z?>;dnhi2)D6;|UTD+?17=oS&%I7D{CMa35@nc^Df8He)bwiE9_r5|rNXI>31kQJQO z8@xRoTI~eL%PbVcrjKTQ>CejMW75D{I+E&Dl=%YthwFfd_340AK=J?3%AAByp*i1D zC5mmrzqfG15QeZum#I#IRt_qiu~v+J5*VIBd31nT%cTzSbdbZ%P)KHs= z0mH5YbTAP&-<}?*;7m|Fj>mrF*#I-yUHHi-jEqcV`*}^G5=+GRgZZl|&z9#cRvNSy z;6PPqDV(vjT>J1-*0;>R;k#B!rEaDrX_*D%dFDEd)eu&lEQD)Z`Xk&1d()K2jz_FN zThfGSCpbd({yEvbu$!9M&IR?+h#~M7zu`!H08ZY>W^^yFg6;YUQrA!$ul(^JT|PXo z&mtJNRbahgzm1wo$WjRULwry=(9yPeJ8j(o1MEs~@9k6uD?iI84WrIm6<+Dk@r%!c8iugJoL;b_WUXsm?8NaD5Z$Km(+okT7t zLfl$_aH7yVm;-dPw7BuZ%CRPwW~E1wtOIJQ;<1?1v`cF85EwTLI4347k?8T9JT@4A z^Cp|t--WmH)pjY}NSH!L(`>ETJRU}C*3yxe^)l7gx%F}4QB2+=$@Cw|0a~gFW(o@5 zHuM}RcktLe8e+Fb>%=^o%^plIM6q-g)H2R6GB8Zf$Scg`10k2S8+}V65|Rs6)v{_j zXqHcQEF#+2Ybs;W1A%Nu#S~^{m%q8V7$a`fW&TIh;fLBhH{*cPBMdP~9llL?rJwUy z)*0jmx~d$KehM!WeFJBN+Z;4CeW3;mXi7t_E)RGnTtFHCT^Q$wa=Soaplj~_>!`bp7@1hSR=0guR# zdnJ$=twFzJ%FIw`-2e;w$(&7a z0FQ$Vn?|X0iN*krr@>E0?=b|WHp*HYbeuXv@-8TIWmF{jB4$6WGzGgX^NAm%FLxBP zHlH_j_+XE3R=iM5StawR@{GPc@0-Uu>#RpVav{NhfT8HElkr8U&6on&iq*Kt78hqb zAwDZUD%KZkj3444>?M`qPF&%Rg@dXEU|R}Ot>GL;WIchdlMnidgg zIfu}REh|iPRQq_^ETr(AQC^EHWoaN7I*ofhwO%IATAx4Mua4`TFi*SuN$@uj4HX^HoU_9QHXr6 zjVIsfc}bNS^sC0O1wpeOWxZy2aH;)3eZqZDJlc%A^)Je|?w04^nvd|P_C&theJ^X|Z$N>OE`bDiB{^yjS?86r1v zR(10EA}xTdU<&zu00nctS-8K1qOY&7ErD8r{^|)B>DVu5qkAlx2(2#hUMmT4Syq4A5{)B z#B44(>a+i?ehKcg^y|yERt{Q)%>_4HCEa>ZZavk2cpOZM%|0C-im_-SeZQV6( z+qTxUZQHhOuW8%1ZQHhO+rD$}^UjMKaeqKZM|5>nW#;&DWOYq!TEQAzQgG`7ud6o3 za;ZdxY6m2JqARE>%@u*#!qIo7`|kjpHWG7B5Z|51>@J>#d1oVC3OYO9xtWf|NiBBw zfvzXVDwZ>b|6O=bzJHs+Z$$c+HzC1`kXDH8hBoVqRX#Vego2Zr$yMS{*CQ45>wbTX zf0mW`V3(sqFHr{W1D-cAanzcI)f7o?T0E6s7*eQWX0uc?=tSvcP-JSU z)~=?ONq{fnbXg|RbqwSVCt_`N)gDg@bhLNebP|7-%nXFu9O#^4VqhM9i*23=Z^Owb zHJA;HvVCnJn-N8@3Uq}L-eqpj$lf8aIeMO{KR;ckhM5Jb(){HbPAdK*|1DSRpbQbd72l#n z=ulFD>mS*I!t7XA;I|~I+CWn4LZ>V6_GFU=D`g>byB!A0RU~qML*>zdN?%?5n^N{@ zzL>m8Pq9T@EO#LwI5_jynP$IAyS&IyHINEsO zM=~3WKafo;CYw}u`AeKH(IH zqbY;x1>-ozXCndOhr}ET-kc%gU46>mwB)4u+1$)My~JxO zLR`Gr?;pw_2H9XyI}FU9RSCpX*?g4V#PPZmnx=YL;SmS7dI}BamzM(%=Pnk zFH@1~@*NXc1)b~eUW#`V&1rC=^Yq~T*HWoqJt$5 zPQK^5z9VEm8_s3NWXphGC|v&p`&N`(biW|9rH*mJN@&zB0J%h0ehM}RupoQ4yX2HW zq*A0r%er3)MjlLrV8nfpQM!24<;NnxbLbgo@+Frxjlz_CVJHd(rrPq{+#ilyNwQk( z{P{XuIW34H@(27YiQh6n%Osf?_66hM;EVpnQ&rF&InrpP4B|;qUMgT?%^(m5<>qPUd3vupVmL z$71O6f{W6>`z*nXg1nF5;WzAM67)*OzT@0YNC95hJ>{&W`qf{ z_{7m*!0-f3sku4A$bL49$YIN`5-iD|#04|fax%CoY=b>^6U}1@|nf{ zjB)z_p}RME48y=P3YOvCY;>G6*R0%kC{TP`JAHKHO|IKqBF6Tpm^YFG_){X`wtj$D zf3&aH_)=wH8*v4LYe#XtHZgI$@FxO_s=+AU4#sZq0?+2GW|)|6qAAkA3k&84E5pD}`z zh60s}cwhuUs!qN(-`TBDe1&9Lu-`Ss_9sNi^^U1JMWTNMbgD2<{R@X?YN#7l<1k91fQ~uW_x60{Uzu-GjKo%Cu&H;eTD=%Q)Xtn zr-!G(78@%86%EOQ4gtQlOl*&hj0Md<>VldcI+uxF74$QV<}|1O$hffv6fu!bPq-K$ za#c3__JY09sSGD$G_z-WVt!jsI7j`3{-|ucN!oIy^lim*+Cf%>?x;1-YDH9CoJHPy z(0S%Bs8Ny~cKjL$OfM85)d0cp=4-i#+R2wu49tYt5@FpLf#u`G$kh0i0sRd#qB z;|3(IU60L%l6*4DX};L-2oy>VxE!qatrtlm$lvOc?Zq~htWwQ#o#IozzMFO?%oLj{U5RL4GipD^qIViuP1C#m~T0{k>Lm(^*#WRcYq))G z!VHrmNNUw%e&Q`JuPu-U^(OhMkeVLWZWL56_sQc)>Lcaunrc5AkNtW(XCqU~co{8T z34ItqtsxiV^ufi2fX=ftID_+}gAkOpTgyMd^^6VoJRVL<&yg&`#= z9h_{;K2wut^T|VQ97FN`kFK-nS=sUSbU<#jp7~Tfz+Y?zT=4m z@@R)kuZ>!R?!sQx?X5^eZ6Awtu@*_QEixavwp2C=asC!6Ak;CGeg7086k4Btx0#pcq|HT59&CI zMh}wBe77o(FR8DW1A`>&Czx6dW9B{0u~SJyp1Rb=P1U*Vatlc~CAD0W(&U*?`*i$+ zu>e6|oZ^y993RvVOnF)e;fQu7R-h7xGt;uOO?g!Gt~m$`yg*bUm^EuLBlm5Pyq39( zqq5aZK`($!i;9mvvZSQZaOL1er^g3*UFm)U)r}EG=Bz&O$)bExKUz&e*0pYhk70vxmrga03M$csoFYoZFLIz+dh5gbgsm#l?{ zS_@5#{jD84M)w6&?gXk~Xmg_jZ8?po*6BbSXE+YBmG>uY%HVZ{QlusCng}_;$Kl<| zAo3IN8-&HK1>dVL{D};aN1!LUMTgiR+SSKWMU-BGBwQy2S{>m>$RyqqzsqHg=U4ly zw=VJK@&&-W1F)(XldEfsyU^PK;aFybyuNR0Lo@QVKspVhHQC09+hnzGsc2yBxYCNA z_SEF@nb7d|vDU=YXu%YOmCm+Zn>s1~L@@LY08X|5z_6pxa`%Hz{^9oS#RZJU*ebZZ zKocDrUHdP3s(NHqf3kY7~Y3zSYna}&5ZAAdMHJp+<%O%?* zYkJ@YKe0hEA6Q~b)Sk8RV_2Ldpm81M^b6a-qB~fB2OjSrDTUU*Dl@cu#+{f@t%XK6 z&a>1BnJ-He)5L~}6jDFe=Jxq8COaWtlAa$Lt#M;`e7qODqY83yyf{F5w+8(G6IoO$S$kpI87q2Byxx5NL z?T1c0SKLFTU6h&xvRMrz5abaRBd}7*F%Cww0kJ`O-wwB70mACz&Nm}*jkGvtMuMqJ#Tgq2aJq{YGe3WuDGAiZidC+vkERV}OsPy`lMsFb<{a;P+zSgSCvMg@*X zFfv)0(5?sE)Qgu$c*WrH@!_FXKR@3ZR%FEh+9nq$vVZ&!@-OFFKd$GjA-Jj2z$~xP zE4RGs4R*13dA*vMRt{HBTO0(G?~jOp7BsD_iN_tV?TwZVC}TpCt&jQPE?8QuZCj4nco?Q%99cBP>nW zYcv|b8!m|@wV8>hsSF@N{QsF;xg#DonY%N5lT)2|MBy5rJnUk95rFabQ;V8&V0G2t zoA`M`kJ9B?yVt&imLsafORpjh-?hHwrpjIHmvXl)0U!nT+X({m{&^V8(lN>MYB)3c z0}rs7h*7l5C=cx_b*4=b*{E1^NkLshSHjI@y(cJcRzx6pHu)UJ=^gCBQgRVhG?~$u z97|{k8+Jzc3`SXKze_(%5d0j45~_NwlS-QpE^MhL+>4@54;2+3Z^eN(CuRn#W=NVB z4ld-e`^6wj6r~2aT*>61&Ar8EO5r+)tV?ce><6{4w~`4@((ksarO=2-DWD>vf@)ls zoA8OPcn|dlt`RfJj1U`;Trc6(Ay@b{Vh$WpnFWz{6fd;WFjL@BVw?{E*u6+SIkY7n zdJ&|R<}pnqTWh@AXVkPY>289WgA)^b7D@)*qvG0(I8+kTvaWs%Tdp99tpbV_2j0L* z`xwr>n-E^iMq)ZaHttz|AG~n10MlKiz!p9}jX+5Bdw$K?)}MWeWX9^SFQsE76cri} zXN&-j8`DJGUP}-Pun`cK`Y!;4>=O7BV#$~zQ7s=ET37Eil!U4tjk~GhRxCRS3 zStdE}V5R70S4ik2k-}4#4*sW4KvH~5&gfU#_S)bER@X`#AE5w2s5fHplP=Hc7sm@I zAoeU{XEY&hVwwaQt(SkVek>m8UljNo-~cX%LNMUJDFKt%a&g2-_-I6C0@av8e&+Hn zr}5q6l>@`^!R`A%eF1@otpQQv6H0MX?zuQf$FnhSb!x~&nUI|W*@_6|glcP{-Ig|X zOOoOe@MB?%$O2Dx74s%6DpcM#SP7j&&3g9$2F-SGKfNFH8v1d;>qTWq3et}YKG78B zi8$nD!9Z+jnecSqb{c3IYJPgu5wYRW8{2;vgLOeUD+(FFsIyPY+FAG0o9_{0-4OS? z5l2gS?KMp17)w=|@?}+(O2L;*dM2Z5XH!p09r%bt@as>YQa?~?V>VbQ?TJ6Y^ zJ>y{NjFA?7A##h`-$JIFpK``e6uW^)6DZo*gtNw5u8Y&88ykCz@|Y!4@)2~8+{^zn z!K-L#VD{!Pd`*;JWtXC$P7eKF7T{wP=(RYu4ym6gpy}#ReEd@hjbJ)epjZSB z&+>;^-m;xAPkI0aRFZH9O|oh?hV)tK)z%IQm?r_};6Oq+KbqoKGKL#^$iu|^KDoX@ zje)T*Bk!2wPkLFnPL{IiQqv>Vd>0K6oNUg@9yk}Xq6fOu;D|t$$2=opRQXqTD++?2@EeV!20#Iv|kt9!DhScZs-UW`579~$2}&F z2}ML8PMSNpKrm(;7}@=YG)a^#LBsfnzC^)ixYpc`Vjj~J4v&ejBtLADYAv!o&yJdL z!=Id#(Cs!P&<=r=WOFJ#&N}YLzEhf|IBQpaWjR+Yy!5Du7E^{;Rv~&)LUr`H7>sGi zu0ye9vDQqb@8{DZBMAn8Cl#M=Z!9Z$$}0(a;kJhIUGiWwRT1C(EaxW&-0TZEPy|;R z_h;->=B9JY+~INM1I-zLi2$i*R7|t(i?bP=wfWDLC$06+Qk5-!gp10;d&30df+4Et z=wHyQ);0#ltWQDyXWN$-0{=4{_V(L#ZG0(bGM;X6lI65NyM` z!$vsw3fYDgPrbVzPi_-BOqS~|+}fYs=-TEP;1%zBOWEd0AKE2kAQ@&LD*lx|0<07>!a6^&zwV6JAiOo`D1Z^s{)hUBo;0+i6zvq{lX4RM?D(`@~ zG*c-%7l~%&4cQy?w$`JJKmB5%SC5WKcbSoY1cE-j3hmH5(I%%(1CrGGM!C1T;LD4t zoB%yLON71=OR3kM>E+vmd(rVbJU!gp@%L|zkAz9%87v}DOzL!E;kJI#ev;#Y4Yo+& zG|^&tw9+0>$0^*K?fDNsshZgSl z1`s+OP8;iXWRcF5@Z55o`cZ342G)Z9sk16sthuCStAawpAC>jHhX`LES`xI2hb~Ug zN7F*@<)eiRejf8E0fz4ed7KcwodUt_CJ;L@Nmeac$>>~zkdwplGQ{$V;5ZfF`@?JF zh0&P`XWArC@1pTO=8FrkY&^CiYhf|kymm$90rgX@v21wS-hd$xHQlum#SG$>P{IV) zC#nQ>`!rmJZ16X*$w~>Zm`l?IimZ9m{wYS+b*O6H`xFzyfUV70bu)PD4lF*_WbKtI zJ)ZcUBIoxh*14ay?7VoNSH~u~iq}zch&RNxk_XlBwV@lf4+_(g7lZM(g4#*E=_I@_ ztu~rzZDw?b`ML&G+Kcdr81hME>I&<05%16Oh5n?#oDUpQ-lhI3s0)>w4g14p-Lv{G zUQB%6rBW!46thL=5$KSHvvC@)5jz_&-cdJ86n?r*(_1Pjg+R=xLp0-Y4nKWpe9{HdK>$Jg8WildTS z8^L>`L4P&qI&Wim0%HkjB35)Kn?$2-R2SULA7&8hKCd#5B7Db`gd6U2ra(BguZ7C^ zXUq+)v%}8=DeB7_^^8sWrT6GCBhuUlsdn3puD0>Ix6X6x2!oYU8nqkhoVF>8{;raQ@j#@iruW5wJ64G>fZgfjONEk( zF^n5hnxMLq{^19d1ehbELAC_0HOgI?$beTDxxD3psl?*$>OFr25|+dElX(Q=@Loul z7DveYSLzST&@jT?otP;S6dIo|{1++}U3K^$54K=eDkG$S#T^n+(h0M=vr~InA`Gn! z@(Nflvi)jci{2sr83WM)4Ow9bok|e6O zVEDpv!jCKXYBtXroxoMx40A8bf#^@=PRJ!=_j-xcc*;}u+2<$RqYWSq_93X(2yEFe zr8tUv>o1qDv-MY>VvCK(Tq;LAR%)}8yf)DNi&Hn!sdfVqdOjc1_poxjFG?V=>CPXX zqm2OS4xSe~dExKSZ8#$X_)xJ`%EZh6{N5-N1_ zQjFX3wu~iAE=!}_KCkFk*;No5BO|@IM%JXk00^pE1&(QLZ*86B+YUmABV{_cB6Ni?MA-b$Sv40OA#*= z2TUOq*kj}QFEhn4HXaICoV(+x#;PgPE^VY&uT2{O_56~5u-gC`;+lrm4DdY8RHG9# z>`qsjk07W*vRXSQMNeMzni}S)Cm6Xozqt|P)O2qL1)m=n0Vk1mt)4fn&2j!xd|Wn2 zycjyUj;iUulhlRz(_2>ex-9)5*W0oE#LHY;hA{KksYa{Lb{Ptq;G(e9)xf|->lh}~ zG(yLJV-lAN+5)i6Q1=f{gChLHR&q>s&JJ@Bcte`cpR#{MPR;}*M+q^NU~&$<-MwzX zwrTsnQ4aY&#y);KZPXdqLdNygF16TEr@k!~3hy+=0QWwh-xo>!WEsfI+jUZ6v*Pw_ z9_?RlpB)(i0rh&Vaz}dIVFR$G(uN(;$tkUod~wD&`bG&;;&gz!8^(0S+4(OGMXFm< z{EF4@B1mX?tv>R@#(_2FVBift@7?#6DeJ3+(jS$J0F-6#(=+v^51RuK@8)=a?TF-t zf%-XlAfTVC!%fA|i>=vH30{?GRsFI}7qDtm8@absJP2AFOLZF!)Yv4$eb)-IRE_VL z9L8s5iKOa5zqn&(m=F(P{R>7Dy2{p4*8l3HD_#twrNnpdm#7BGp!;5*R~i$oeIHON z_Ibl;r8Za@-3AuvYIijqPFInPAO$n<`j15Ny6#of?de-S3kyd3nl8T-9Bm9=rB4yN z)_m4l3DjCOKJT)+W~u$F>}WAmh)28BT1_*KQh$9bIxK?U?&9`5aJ3ftn!SDc@G%-6 zmEhsx2s921{%Q7QQ4Z!IOR112`L(*>$z-}YzDoTM9_h{Cp-TNbE1vfk%rud{*9FJo zG=crc&Kb`qKn;0R#^0=c_^PVfNm{vSTN)#$D$hn$J_ANnaz* zn~oMdF>niDJinCZEbTkdl`TKjvv7_i_KfaMEd^dq7em624z%`mhyFkPjg^Pguh=>~ zUCC@vY!+nRMfr6Ut6he3NAkx?( zSdV=pdyjyi_0QpUI-|>8p{DuZL+0gBMz<{$=4@k4?Lytr1h+{>Q2@NjrDyN1NMs{~aXH{FB=s^gFiyvK>q;e+CXi4j!L*fNp$;Z@l(FvWOet#W7%-&4 zHgE4Ua@>kQLnDQ%!0B>L%AgA+_?DXK2 zD}=De=Q{%UPz21@Tq|1ldAaey@-vhZI{#qFXd#)&@`zAvNvDC+sH7+ENc5~xu?FsL zH}?-WPXZN4hRkR978yCt8p&UeH6!rIn_2K$qEE*_n|zsu{g=-NkAU~0^jDpb2mlly zA|i>8S0nHuDg!yZ8BU=Rmr+LJsN@Jw-&Iu`u@Qx-0fC@YHgZOrK33@X_8E{Kp1*}Z zx4tLdXdn8GBJj%U5|OZPTq^|u@JP2_C@wagcAqkGRSrNrr`!bk2vz-$CN&zuoz<6_ z4yiS9MPXC@J|v%C<&hYxGVt-Ty6wvKT4x+n$#mT62S>UP4KJ5S zFqEhiks1Ol*)ibvEjsLOW|HxuVro&p2_nX{UWyOA0fqeV#L2f>wf)+61ntEvy=%Br0enp?T`BZ2!Bp=aW=4i^461;2@OaDh5dxm%4&Ry z7=y>$u)A>PIu%#|_!w_4Yc)5TYj}^gL?uJ-NKb*nT+26vt|&`ymI~nh{2G3!57wBi zqyU2KJ)bd>d5ZaY=o8bs>Io)x9iM2^5_x6aCG7v*1d>;avA# zSCat7;+4og^((P>p~2Yg=& zUsYW4EVOEeUt68=|897yG_^B(Y8C{A=LGWcWu~s*X1sElVq0?KTRXyIA*b2QW;V>5 zTG}0T-9SD5`j7WY{t6}Ktsl>=U-8~E$YV=8&IM@K`}zF=9&WdR^@G$?-VU=4gB4m6 z22-ggOvlY{KXt22(Uj?T@*V#V1*)9>r~iul&^OM=1alRt+@K)19UY$Bsm(tw=Mu3u zgKnE7Nl1X@`60-q%LSxJ=C{`{!*1h?MT^&=&1TE@jUWN*DgN{4stHvaP zPmcV2`Ep0=U;aTAw&owUAq2khyj<>3G0q%hRNN>N;`&ypmDho0?5sftbvCIN)0zwm zbvH=0M11Jb9c7H9LJKND zrAP)yOjHS8m}|Ftiq@P$;&x<~$TcR~xzLd`+NrGfZfCS5A>5bm49h!6o0;B5Cx6-a}yYn{oi(KUiR?}MPw7bwG+*T;9 zMX7s(#za;$zAYCbUSIbitp{XnvbT0?+{y|O7z{4e1ZZ?F7cB`5a1xz&Kw((&TyA(` z4uvMO0(WzOS27(b)kxs!kp>VLoh~g+X?Aa_gmTN59pd}G61q5i z(a8X!R>AoPBJEb(ZswPDYpKTl9xj@`_VIV$P?aY-FnR$w_MQAt6pEwpV$d&=@B&uc z@zX0RD^d6TJ*I7cU0%*uOg<_qG{L$Td5l(RwR9I&Wu~AstH19;phrH-a<9%DMZ7F3 z6r{FZiye7)YpFaf@ZV=}Hq5BUQfMnOS21vw9;aYhyIY=}$?;wj$J3?ZdEYYlRJthc zm%C*YMC7U<-Rek>u5658v>&CgSMNsP@8`2rh~c z*c?S$f(nLNfCG`kuC?yj_1DtgAk#4&h3G~XqgDNe!J}9uJ-_{^lZE8HS(w+PRos~b zTnMjoSSW#-WXU%~4{yK(-xEjR*(lfS-FPy^FM@%z+&1eDZG`y-zW)MtUa6vM6|n6? zzQ>r*B@_ARU97V1L5{%08F{px_f$1GS*U`_#5t3{#~i90n+0}u544M2u1a!h!Bb+q zP=)h7nhWg51mvD-5WV&Lo+_Yfs;&G|21b{?`u}6vLRfH7qPyAt*ZX0dKh8i=*u7<@ zyD=r=o190WW0{;1oXkgET#X{y;4uqV#(d&XeDdcEZ_wwjvE&t+h2H$Y(9Uvrq3E(~ zYQw!)vs~e_ClS9ZrF1WqK>t+{-q)mhy`;y-8w$-K9{ldW*8`nKrCgkWi^V6zdZx1% zmKsHMP#)Xf_3M|?E`^XSP_}=IDvGENXwv>&XLC8p?c*Ja=;7P>tJ4+zfv(TGo8iQ7 zWf+_LJoQ}l9)%(PWmi8K7jjb|BPF?p^Un9$#bpbC^cNNSuvqrJJ#;1()cXRvx7_f7 zz!0I4_&O(9_x%pvqE;blLURcWWY6Lm0>&uFNqL$NMhWeU;0P4;*(^xkn5w$ijP zvdkYXg6W~GAsQMve<6O~Xrh9$`l8XFF87^W?q}Y?18LViJJ?o!yMX%WvUJy8e{HbR zt@aooJ5c+1^B9yZ;Q0|uu0S%gJ&&6TOxn-g`nQF*lrAAoZ!Q8dw%T^Tvhb?Yc|Wxn zdDy1ugF)#{CzicFGZ^^FK4&?-DWa@S#!{Jv)MR3@m`?I9bAK0A&e{IHK9O@mak(Yw zJ*?R~#6_$L^GSjJ&2i=xJ?N4#Cu&W76^^%v)xz{>19^2>`aq9!%3>)$?w#m&eF?Nv@?_pxk@pTZPa*wL}+n#6PSntZ#8Y zZMlnru@F~GYHikk%}lybli8?kcH0D;vs!VG^siQ@XB<6d=gnVfQChq}(9z*?kcLYo zjeDv$e6x203vLS~`Y`NKPlTs6BZkp|5@e<&q*FukhmS6M9_q&^I4wb*6z^}h5*26j zv{TS$UDX3DEjEzd{in(CxXPRC(Q-52CMshU>2`S8Lr~(|_-to=hJqOq1*}Wmu96?rOf5~uzn7dGSAeLzj0yp-etddGcY6|8| zVj+^$MBh&AnQfeFHc#FSH2W-t&gM?PaZygFtU-xnz6$=`ksd49O4j4^gVs;kE{zc` zPqWZp5r}?vndx`sdQXg1@itn_lXtkXDW&ee8X*NnSsMENl<)QU(*ngXW!1Mm^*~;S z-_Ij^&~1u^+1wyht=(PSHnWYYrDu4*6^h0H&cX{UMDFlTNhX}M7&2Dzg9jM*iRauKj ztb0?oO&*`umM>Rh?Cb0|G>_;jNnCrE(oylQmuR@Rw_JPE0_Lw_pGPN+B2R+*j=Zy; z!=j3uww4uT$@c93@g^7$>b=ee#KmY~H@E95$#A}+6PhCN32HG{8ccV5-lqTyxwAk2Xx_uKk?8G8bb5>!dR71BL9kuk3eiC6CSWw}R!YE+UgK5uRdY-F+ zXu}I4X67=1Nt1hW^EHGn5VC{YtU&h+K^3NY!Nln3b?Z;6D$`v4G0JBT5A zc)*yaxZ=OIW-=*wu`y=3s5w}uleKy9*LlR=OpFC=neCM=f zu2RqPvwO0B@}J%MKHlPeqd=EC2>KkXmYPlR0<97mI;p^Bi&=rV<#VxNL%x)P(wuFR zZ1yZdd;%M!qbDc;W^1{Yo|GYMN59usXeN4QqcgLahegY-GL3HkG2ZFr73-`Gjlg*B+fekr!5|U!1aQS!LbTLv z*PuJiBmA+?%^mCyWqIhCt%iX=J_I0yY{UeBlC`!7^ok@XwX~5!5w&5P2HXw)=qr1E zv;VQx^ZmEenGR3&wS&A*wv!(aaOmdro*X+iO#YfYhvXd9Z32w>$$?MJe~WSu3>u=e zf#^&Ec{|9LmFXRBJZS_8lE4q24;~-fO97Hz-+o5iuA$v+Tx#4 z3M{s}?QVqv)%gogX7S#}10#Nr?^MPik*Rrp&%*IWi#Zl~BU9>uVS%dNHehh>qbJRW z$%-fcyk9LVQO{SIDiHbkP*g=m3JshJ2`eN|xk0!`=$ZMMpd>ei0RPBQKrtyp-$qA; zgk~88-Fos?u+@8$WdtpuJ*Of6_P|ZZwQ`G)B|YjsABUjG4qa0fk74AaFzXN9*V5_(#&AeWhS_RK&^&S5kw>kT8dM@*MJT1fL#F3RDHB2nUJ zPVL6miLZ@;|2>|z@q*=(zlrN}b`>p6fY5egI6nn!wjk-VSzx#=4oBUYL&?u83lQ&& z$Z7^#OG{Zq8d!0hLa$EXFHFm{lLe#I+!6jeWp3Q5`dX8yq00Xs^8zB>T1MR#5S54PeM+ zn1C?cFpT8^%jLdI@ei`%*T_WarBg_U@&+guq2(I5FZ>K7#y$(8z2cmaeT$>u#AzBB<7KaN-I)cd; zwf{7^sVb(4rqrmXwZ}pMA3B4=zmso>$m_;6bDrE@n$@$0=Q$N};uuw^xFw@k|x={_o9n;>&zpaovs);xzz59js%sRs7s^35UjG?W8c?v zV?m#fJlTV2Z;n4GAC@27WIHm>`W(rSVG%KzIjhrEI(uh3aAU&C&p~jnipj^V=e=B`#)^?exd2QKWIS%Taq}?oT84ZZG7l1so5nCY_{R~M>XlYGiD7Ds3LEflS=;~A)nQo&V6jpiZI6cmIQ{h9 zH}}_B->vJb^u({Io}Lj5MhJ)FVe>+Nov5BQH^0|&?&){$*%^(CuRy585a|&m&am49 z-TJKfeb1=zU|VVBbd94vwCRiwcE_BzLiMB~;b9$oFtW<>kYGVwGFUTAzDz3SzZd1f!(0yu+Pe2KPGFljI;&b!T~4wvG4kEFMD zGj>4PHSAN3MksBls?y_Yi|sJ|0gAMPgJ%?w)!g+G*^>4mwRbr)I+zcW8IzLuw6=ci z3vfIy@RIhi!RfIL+-S^hmf@wg_t&DBv%h_7ny{F_V*FTZ{xN~jxdJjVoaPdicket> zgcR$_3?KlKtkpz$MMhD)(A@PANpt9d4bIx}U7xG>wdifQ1c8_K|HJ)Ofsj3jS<1e5a#|l*wJ03cc$$`n0Wz0ess2YY4 zUc$vmEWXvVVDDUC*wKD?J1?J{U^{nQdnk$@G{rdpH<7R1zu% zd1Lm*!mAZ9Zbg>(W2&Sn9q0E>+ov3z!|*ajA-|=2y)mb+jJV*N8XqJu0s4eBVMIr( z<56w!hk$%!5}YK98}=&%Wp~iRON|2?78dMufMS0EP1fw5)Mame;@*knJC&v}yYA_RKnphEu9scm?C z?oM>=GSBZx z8ZXK-ABC@;UMSPoR^5bZYgo_PQQ{CSCml}BAD;6d^6>qKoOf5fP!LOTI4WQDTcffB z^55m^EWV){et6=VoLf#`26{VZ){zO3ZRrE`Q04ffbopjkgXL|rFf)M(M=pb_dq3#S z9(7x)S}E-g>7U1*lmpO7Sp=R3d>is+)JU~U48PD=dL7eTm8+^UD_qAN$Oe2&>^q!1 z4E{OnxA6kG7tAju#Sf!vuTA`qQyw2uwf2BUhAzicm_x&`k)6jhr1?mW(4R+DW|6JZPO#Uf!coO572WGZixj;=HZpLHvQ+| zY@P-6zh z&sMb+Nu~Rzbhki&4uxVdTfl3ci8+U^Cm#&mvJN^}0_1N*HF0J*b){`7rnDeb*+s27 z1v5s`b!DI>@exbZ<~!%c#k{4?J)PC2jGFloX27mG`=^-A?;g!vCdy?nD8IH&idB+U z;!Dulf@uz%7M32!TTC@u!cb^7U>>djPPTZIm2Z@zu4iQxQa{tjgga0uRT**}!c1Io zpb=8rB54NRhaaamkWkLxG|;F70V=lpX=<*n{*#kYRa8OrZ%$E4vS~LNtrfka5J3^0 z7UY-T9C#&XjMR7_D(0}e%B^Opj1SVJ-P^a++=RHm$m{GGn5YE~YGH*ZfC4y=N#7k4 z2o!<<1oo4K0`RM=qwkcHEL9pSBQXjjmX;Du&{8zdmF4P)x0%3+BbZ$Rq=PcycqrD}HO*C3J|L9ck#pqm1s=4qTj9 z+(hdopW^2i78T_I02J6QzJ-8fmX(UD=EnijzD$F@ek%UWsNGvgt`UB(b6@~}K5PCz zJ!4E=9_DyQH$p)Jj~mg`Aoiq5aTR0~_2WHh)Yxssq8dG&ZA?ij;_TYecEQ>^63OEA zD;mHS^(*qtdhX;_!Tk%LwF<}(dOL_(khDKr;Lyksw>qS_y?U*QasI!%1kPzDCpj;h zmO6WCdRl+SsP|Qb@b}&SIb-?Y$pHY4FcsgORVjA>nP>Bo&Scx2T(F5VMTdc;9Yp+) zC~A1fINgcC7Y%?<%OH2NkQac*)qyh}Dc04sfQgY!jtPQL`Dpa4ltf_u)msYv_{|RF zTd|9sYRloB(t$sl$NeXc|4;A&?B_s~OI+-v;ua;}x!~jT&rsX@k&wW{+Kr)P5whoe zJhjfsB7YY?rPGoOXqn7mv%+sg;mi}}RZfvqh)O`)u_k-=UxU%fnV)n5?c+VC+|l>! zR_?L@%ypgj0T<=0+`x$A=`jH+IbDyOWUTwuey20N8>iDAn|si@#tk`p zCd$y{3YEmc59mTKKS3$k0($vGg(6^PJ9_e9e-E|YzBx$$Kpg$zg>Uo66h`s_>J)6O_%91$wh4K14z4RjQh;$md- z*)0&cYm;hTxqIURhB&t}U=+f{wx# zbrDknZkNr2Yj*;b{jAHze8Zr`1dk4n@|q|SH`mLMQ)K3=HJ1Gh#F-uu>|~O@+R(C5 zN}w$g<$%XIKlM{VTT7Y*8}Qy9usI_7StL*`BY9U>Ty82nr`Nk%N~**rKHL4_DyyG4 zmsqjyPz$yKwEOuQy9^037s%c*>FlOC;HQ;ANn$7*I%Qm|I8|?Q;`HEnh{V)#f{<#m!ae(hLdlir>~`8HPik4E4?vXyQXoHqP36Ls;v{$oYmI(ohTvvG3Wg!FX^4$(bZKkS<#BtQt}+rKP^&CW7BbC4v-Dwg_`_Dlzn-i zpOtz~Vl4mNakunDy;^}g5CLg0NIs%O6?YIL1cz&f8g=iXT;4L+vvq37^{ekd0zu4s- zdapV>^XXggc^+s9Zvd*AO#XY9=nBH%jdZsnZN9%TIepBSnVj?v>3ej1N(-x=osQsg z=e4@v+iiSIj&`MX&qc$`{=$O&Jt48x${MPG=<9x7%>_7hvcd_Ct^=+S$-Qa41PmeTxYEL0^^aW`Qt!U?t9yPf5=m%D_?3SLB`ZB z@V&TDRF2jpR!#mZ%UeUwj$N9?@(ks$Yqo37a$lWM51|k+@WNSpA>v<|=_6g9tGzF)K7~=D6 ztRcy7TSvZb!>lpk`@RVJZcmnE)tmcmJRs}7SbXR1C7M4G{qEr4%$wSUstP*iENn-@ z%=)+dp0VQ`pm7&<3I*&Py|a~UXGeUf>7=(+VM=v!K#G9V-gUHCPEj|ufk$TRo{Ej= ztH-2mm*ndKGTnW@8?%C;Z>!^96?*|DB9{#b=*AiVc1dmUA*0G5v~61L-9B@ z@pS0}{`I4LobzD^!yUcz+EBU+|EZeVX1!wo$#R$CI`4|}Jy!PTS_4Fd@>#|W!^dz( zjvQnCPWj!#Y~+B|b*?Qt`%_|yP*qO=>a%#ur#<5C@MCL&VcW1n7^Fk?>)1~&%*Vqc zr;XwTslK!01;|B-5jOqnu%f1ar~Xac{Nero)NxLMb#(9BjvCwEvC-JJZCec*+dD?n zunl%>HMZ@faT+zYjs5S7-}@bXb24W$&&--xYt4OKvkK@U{jvTTgCXJ}IB;p;BmpKN z8Ey(=$YD|@?Lxgj0xXiYiDo`J+KKeme9JRqvA2gLrU6Y+r9^#4oQYkI|H1tF^1T)L zFtIOjBv#|a_3&KS?CV+!f!F(^<3+yex#`#M{Ju{NNO}DCQ)wQmYT9`T(X9(#s^ejR z)8?DoRXBG7F*fd!&H!qmkDsh<&Mp;XYeo=g52QaCE|=tNoz+Xwns{8E&I~SjU39kh zC!cUt+ZYBNlIgY&&Fb*PsJgnF-{VK_CwJc=d_6D54o{YDtSAAqTLV|hY_KG0>hO4e zPl+rhdk1WI4b4;f9KBh@PbkIRD6!S|_crAC2tfzLM%*SpAJlXQ@$_oHSL8Zx&3C0p zU!UKJMXy+_@qn(^56O;LU}QQlaewV!X^)SgB4t8O|! zFUk<8tv8wb+NAA@?^2uD6ZUWc$-Ks00TAd)q@R)Jw}_sL^243lOlx;q3J?eHjeZ0k-`(rDxtt=B za++;^LM67%fGJgq8UZuLoKC;G{Ja2(`nRdsuYzU03j1>+8Ry{?YooLN2~?nj@!OMm z-_?hmP~SH(diatTPg~QBdoP!Mq$3l7OvD_+R>C*g_UTL1FuW@u7ra(b~(E_jA0Fx#f*%;i@ zwd;O7rC1Y@6}Mfz^gN@srY-+nZxD0 zP(NKGlu8E43TeG_bTR{~UHYl;dbqiJDP+ zIlEB>R{}R&YFjF7=#vre%k6ZsEO~jqeFVqc?efv#T^h-%+a?WjAQI?)ClVd5k&~Uy zS?>r8H&One{rzoZ_*$SNUsRC!PF3e2iIh&%m_^5Af%pb{8{A!H{GPz_+w{TcrVw7~ z=Ga<0D^QNGz6Jb1Q`gLspdVX?*R*-6Q_(R+@_*2MU-n%qQ`wc^5``f}WKw{D#+k@M5|%+0naal1jp?z1{oForoX1kVyZEyTeA zUYl7KR+DcFL{A#635!M?=Fb?4Ol#4WO{0XzelH_-W`-jUjV`a3)q9k$-_)%-XUwFk zmojBkvhl14-aNm3OGw}?1-vqB^#=Vg-N;Jdr+b+3vItn*u5_JZepQDS{_HpzQfekL zT=B&_3AVM5B=zEOAW{R!oaq^q)Ob07s7o%zMT3y-uDEAR-dQnL}<9)GwV&|92=>kGXf@C0m}y0XfPx!}){>2)1y46~-tf|+QWjkcP%H{0=ZE2CC6pG9Rb1Nq=|?e^cumG-x~PaJ>Nsra}9 z)`K#Txirys0@MfxDRl+QyQDO;7~lP2dt`g`|$&` zpttChzv04bECvLsnml@s2WKsG^jsT&V4Kf(p>Q@<=EGp$IST*ng*7T`FxH7mUMY0? z&xSAGQdzlLt7LWFl%sO^ES(D4D!8RK#>+NWc}$g8!?e~y1H!OOj$6ojk7(${u+DZXbDD9z=-`RJj#X)D@cdjzWkUV6_un`$S zHzzy(9pt`G!rn`ZBzFa@RL-}+q{XZe4?nmT?hviKbc(5wn{eZnR9bX=LI@c2-Gboj zhOb?ig|p;&Nu%Fti#fo((WNtYYA1^_Ksj=S+q%x4gBDM6$XAta>}Wmu@KW#EiuKYY zAuSWjIl|-2w6>cCF|Xn--Kv2e$vpw;(ZduQUrV~Pc+=Au)A{Up`QcUxUaU0I zi@b~H#p|*8es)6`l*ef`GbVX}6ZSXHR~8NnH&aNfc>dD`o3@SRe?HaIM`bS+vHU7Q za?8E_IV8zLVDtX6f`tqB1zC&)pl`gQV%F_Bv!|W_$m|*BuD=!0DhE(h&!Kjm)Ct$4=tW@%1R>te{%2d|1cayvc$T`Ns_$TJ_q9hB- zE(^_Fn#U~GW1|njz<=S62<mB|B0nD0uJvt=J5u%NJuIVPqgdP7}uC^aVTD zS`_t5^ngrUA@+0+qM#VrqfM`_n8Z=xHtNu`_5K^I7cXEWD6?Jjd3Um-=?-H|)(0n$ z>#jMPc?+15jR4J_L4mXX@fP0zQsk8I&;lsqrA)nhIQxl^6d)p6ic%vyRZLEt3|23~G6~6pkR4ll@!+u^}VMDop z*+9fh`4-3;<}cvo@zL#=-t%~6Ho)_XGo2JGKDBmuv#}Yxk6CsWoI2n9_6b_gO~3Y@w8Dert^5 zP5axA%woR30zP%zLZtJlEeVv__C*)EEOn+e{l?euukE_F)@+$aAk5Q3!Z(wt0d#*o zC`>317LhZPfNm4XQl79{c*u)^Y`oW!(-M@Nit6C^O-PQl{HchgVi2G=_w+Q}kjB)v zF2s0NmLx~w*s@txTTS{)qv-i344&v+(BdCm>t*&D6}`!+yDv1t`B!Jm#-8m08>ijH zc1V6gKZj9G^8;q$V3)=59m^3n60zpGlRmt0$0nQaVQ((FdR^dK`~Ah) z>gHg;bu+`;7dW_TP=)o}ot1A*UR~GTZM}O??Gn{L*-DTAlwrbW$!AOZ7w&3_;eLCj zxOlG%`?QUq39b#w?@Y03s4Sr=iTH`6D$u6*v8cj}4za#bxCsGIgR5oQyHw z!bN~N5_oX8M=Pk^xa!V>&hI`tF4#90UFz}Cv(BAMiOFg$M<+@oX1Rxh0p7Fb=H69gQd1R78YQEY5lOFFaL!acc1!5>XxM=SjLGp{GK1%ck@zR&ablfQqSKXYoNMpA@jq(aMd1xbWH~`3+%4v;evWta@6m1uK zW@w5Zg2Ke#gI%FLtMw19HXOs@?P!W~i;Y>))v;BH%Ie^b8XL;aCVehdTHZJvf?HQ? zI67tvU993u--EBV@8RS>yb=>X(@OsNl6;!%*^dK#-yL(s`B7Riy_uJGr)ViB;~efd zt$(yx-u3zOeOSpX;)mC&2(;{s^mGGVO&GyszU+n;bbgFdydLHo;0JaRBYzsYPp-pD zqV%ES0Pr5SEkY+maGgNyJVMTmRo&zG^ai;>Y0b2)PmpPIWAVLK%H&f-uWSwYc}>x9 z7Wx^y@}-}@thd2rf?C!hD1q9&EA1N<;z}Uo!q5s9^pG9IbT-TD+ ze?F>Z`S_h~8FYgP7Z-xQbBag^veIlj_Yi!;-%GgG%TH4}KRBH<2?j;-&_%O06woeo zZC~mJQK1XvtL391*NbtT~XjThNZ=Qei>N_ zK2$$8+_qT^5myM~6Xy2)pp@C)zEFEG2W;O!`id4&f@bn)p@I(~#ky1Ns7Fey81Gn` zGU4-Oh}O!FlYL4#N?CH`QLibj_4DU#0Xhw?kGE2Ubv(+y4`#^sd__m9GfRQM7Uz;C z=lo2j`P>?YeZf&UB_&I`ohf;Hc{cm~C%CTuwHCDQmiqVJHQ&DpxMeeHc9f)NCPv-e z)w)4Rx{}H8;+G<1^7lm|%Qf$j@(cBTXC5z)^L)I6!&a>8KgXkQufS#`+a7dY2{_#6 za+;LNrf#AM?T8GKFvX!ddms$v-Hf3+}5%Ma1ray6YfReVdUFbGAY%%eJzPLYc4a>2*G`@eJfQ+bQ|V!+-JL0Y{`yxduh5eB_r577>}8L zC&gfVFNZz{y9XUEn!vnmD#EN|8AV>L-=|S7yBD);5!&vVx+ihQv++j!iGaPn$RquqMXSvolL&QLM1tm7dI40o!oD+bfv#wO zv3*Ku6wH6QKA7Uq8-u<0sr6Bh`hD9>#C;|$4Fd*pb^Tj)aZ{wcYCiBW9t~khRuJ#zFpzN^Wt49QhH75 zm;%FidhVr%U~w&*4r#~5DOs!lnci;?X7JU8l_L*jPXdGB zpJ^MSxDwY<`l0CUJx4!DC*j8X#foj~#ye^<(fVsud#4V7w+`pBHHb-mHwbk|-OKp+ z@WOo2E8|=4$AF8p_OEhN&vAZ)pTZx{0Kcrh4y>Aq?~LqK5Q%Sno9RyvB&z6`#lVnLgB5kVPkZg6{YK=0kf3!vQwKN;b z>=cc>%P+4>MLL+%ur3`C%K1=Rln%Drdv@d_6+2ve5TqW%dFVg&lJ~=;x$&@Rz|Is< z=7=2kmqcje@sphq-@^RC;p?1iMK`7X5jDobyUiCugnV}%;cheu;TuP%wCoE~E~Ub^ za0-Sd+m#nbd!0`RcqTJG%?X=4eUADn1|@(r-ViEk!qw(o^v=DEhyCqI=TkoF59QI$ zLhH^PO|$*XZ~SQBe2yuGcE8iwo7?f{3zZ1zSZjGgG{T?wIE5FwSW8~kUcG+y*faMziz(m)~#L-O$0Wbb?eRLjAa1a_RI2NfFO+F z-5^#qFD#H;mJ$C-i+jEYdopH_0i()%Tv!_@>p4Fhe0IV~FouyjJzd&?`KmS_`d<=< ziBCjy(@TbkY>#yPOJ*r-+@%!D1VMKwM|!?cL&-I-MAEX1RyK$T)A$<(yxgq@I0070 zhC7QW|M-wjBrzhQZubx?sfQk0?C@yzFGfFOo2Hml{6vI`(r8}^LiAHlc~zna;MN+f z_8z+#abkTqb1}?jvb$u_|2{#lViC}3)4lpj>STX3;uhbYfDkwhNNAiR1@@^?+(bn9 z+R1%3qptobs@bXjaB*785Z!G2o$2bg3cW$XwSxm}di;7f7QK>nX=@Adg-5hhAk-MZt%kk3ja2CQ)rF4Z%5$ zCzo$nm4Zd-IdeMl@KS-Eb(>x$(t(@SHJ|;Tbi55fvMyz{wdl_h>Dte9%ob}ojF&dL znwlw@NQHQj*9|pPGyw_8+x2oD`;z!axCh-qAleeA;O=i2^89{+*J&Zq6lLabp!@PT zkYcAMxEd#rP)X}aK&ye$S%e7N%)kEamCf;0Ux` zOr1kCD~j#R=k`_5&mCFWe4^9#S+s1g^&uK()=nwcnY&NTw&|numV(Nd(WEp!`DDe< zT0?k-D5JM7;<-^yUcCBI+NiLqf>HHS^GTE$xl}xO%>Lxi7C~_7waG7QwDBj;l#!CN ztp(Q>(lS{FmhhnS7%8(0rY+s!+(uu#swxsUn^q0*`+#e2OyJC)=;G+;m!XLDj(j@7 z0ZKfIM=&E^Z=>>)&xg|_DWe^J*wDU?$}Imz*K&j0^Adl>hBlPs>p%SXFJzkg9bFYP zRs$t*y5xg{{Qwzb`!}4YZ+}pc^33)~sK&?yY9?w_Nh=;tE$`KuW#C#_OOM+c{c5i$ zlzKm6Uc=YcABy8DgG~)J5}?*CG&?xcbjS2BFS+K%HHaUr809RP-A-y&R9YElhC?=; zZ;*v$ln*gdkD94fP1xF2XBIPqR8=l4%68v5PyV!&Ae1F=pL@F7C4|?MZe4VVY>91H z72aGmG&_6)=VrXsJ1V>aGjNz~yVyHY>OTt~7wR`NpdsWXrnN;_`i(17fO~d$! zcAHi%UpoLjpdGJfugK|F+{J)mOBegyxKg^EYmqb6R7!A0)GqG8J&RdwS~b+elkb>d zftvczty0r<02>Dn@&ra(&Uq-(@o5ms(a2E{Y7E9V%|u5gGYx)_!i*#A_k@m_8UjB* ze_X{E#Hk)SdPxROb9t4A`sci+uIQwkN-`b+owH$#RLv~Vjj+m(t<2BO&y)*q59)7R zWVnB0MF=s`4v2SoxDBMA#=lB&L6r&&->zaeR&CI2nxkEmn}Q*Oo3 z-JzV43%cUZHx5gprqeXRRFdc2EqI>L@)|`RE_aepd`c~hwi3%J==ZS{EYmII$LJ^4 z?D7}W)>K6<`DWgR0Pcs<@P>&rW2Wz%L;zXH#|M~`7gs?kd-SMm4WRS7R;n09<+89g z7nauQ7Q+p-zMOcV++I0VLG{UxqtK83kF)#3&wHAW9k|_%;k))rmMvYNx{ifYB@{v>wxIJ; zK^W-xLQrYx=&0aTLwv#6>rB6Rs1e1f>!`o66_dP)-c-+m7OCGIWT6#vP z@J^A#q~?-iftU_}qV1wj zZkO^;E}CX{FLr;8n6@buw+bXE@5g>iS!8UW0sReIMD1%($F!h-VTWSjq~6s3qT^ES^^bCVgV8;OF494`aOf+49( zBb1Py#jxHEKo<5CA}%g=QxlN)JuEdMplBgR%j#_HtBxh=(bH{Ka94U{V}`=_)YlFL@Ai6}OjH#X&h%J}B7 z7lbmUA)PZwXL;vFim1fx$W&myP6^vIH~+xPj=J>>ahw~wz>mLx z%jyahx*k1iF;+|qAXj>Sx|y*(Dm9w_HBe7U420K!yCqm#b>Re@I){T>DS`*0opD~7 z2=!$Vb-CjwSw0zK^7C?}!dt4pyw)yN-F)WvzWEWz*gC`Ny*eFui?iV>clK27qz*L@ zi`qawL@b%%jbNK16*+3mVnu@&Z7UwURfa%7LHoaRisDf8P#3#AB8l@g7e*rz%`Q0| zjNTH(mh!#w6)a7a(WC~Z4CltM1eaaEstG~37X(?8kWIkL`L1}xkMGXl1$M&6BWSOQY#NQd9W5(S;)OR6v4rsjr4mR&S6>vzH1`~5<{i%a zk}UUZNdYMLj{PACtEd%$6^o7F5*#3=mV|5qrh;auK<8MI z4gWin|LgSzAwqQwXx5Zb-&|v@HnU-4cPV>EIv8fWbMiC5vg{|sj0Q^;&(j^Nrcayp zca3hv6a6;F%#y{~I9xLe>sH~{CQhx2ja`SA`o^^+hQZ{MoJ@!RH-Dgj8P1iCb zbsxDn2n3->(vAi`4vTvixSe@}D=~{MI|f7Id_}P7k8&EoSd8eX`?h;HX}$(cI{psb zAM3c`%R~J@UpY@wwZ(@|AGbs|5b@NF+mU^(MrHe_7Iz;eKMC(2 zt$L>(LU+TqkNWZ6m+OT~yW-lLtbANtu(K=ng}*VBYQ!IVLMiH`s&qZ1zHA7!_D&CaJ-|Qi8muZ25(B)b<1T-a6fI4tLw@kdId1-GdEmb-9K8>>iU&e zNywH%v0N+tE0TeT|1?C5YC|kY>oJV6_NUAfh}IBDa=U`dC?uuJJVZ^{+v(oZxTM5QLy+s%r4%K)8*RSU)NGsv?HZsw1Iv$&?BdiIbv55K{W( ztvs|ye5is=gIcZ1@;*kZvcoa&oXP;|GkjZH+ny_|rvMJp?zpsBH`Xaf_-9>7x!_z} z-2S+3+)q)Vt^QG})Oh{EbdE+w=a^Y@l~9e7lUDbPX~jx&|4!|K$u2|CRRL^8B+&?n zaZjQwS~YqR2@vt6#tQyL9MS|lj}1|ki{w3=hIc;F9tauLOLMcmJ9*v@oe(!FuepM% z@&pyaDzg6o-@m0@RrnOI-93pXy*p14GOpL);tFCJ(@!{Lj_xe`^<$k33L$$Q2AvDb zn4TR>i}WPV%}KxEFdMJr0?X+eDNTqjCL^(wKGd23xTVE{i;CHo$)pBH;r<)4goR)@ z<1+$%xv04);9W3GTkL?g)Xfdog5#GkLfMdi7WQGm?BOlr&gqK`Q{2W-hjFpSZv2W( zv04Y^pF+PFDHp(-9S`&WI==7lns{tLoxu3+Q?4fT%%IvGLJrL!@v6R(=ZcqEgW#!& z+pO}^IMGNiu5wYNw8ZiU6y8BiBtW#9-+N&>6tp_*f2GZ%&on&ADgDR_)qg>>I{dIh zPDyWr!&p6)QSFVBs~zsAk7lk^k985RFRx z`w(-*iF(9mEV^(-wI;$tqJk=%rWLq!7#ORZ(Bz)}n^BO#&%nO|ZX+D5PJNF0A^vP~ MQp%Fm;-;bh2P;v<3jhEB literal 0 HcmV?d00001 diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 00000000..f2d1490d --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,53 @@ +{ + "name": "backend", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "run": "^1.5.0" + } + }, + "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==" + }, + "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==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/run/-/run-1.5.0.tgz", + "integrity": "sha512-CBPzeX6JQZUdhZpSFyNt2vUk44ivKMWZYCNBYoZYEE46mL9nf6WyMP3320WnzIrJuo89+njiUvlo83jUEXjXLg==", + "dependencies": { + "minimatch": "*" + }, + "bin": { + "runjs": "cli.js" + }, + "engines": { + "node": ">=v0.9.0" + } + } + } +} diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 00000000..269feced --- /dev/null +++ b/backend/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "run": "^1.5.0" + } +} diff --git a/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java b/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java index 5832a603..35876729 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java @@ -5,9 +5,9 @@ @SpringBootApplication public class BackendApplication { - + public static void main(String[] args) { SpringApplication.run(BackendApplication.class, args); } - + } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java index 01ec38d8..4703f7e3 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/HealthCheckController.java @@ -11,9 +11,9 @@ */ @Controller public class HealthCheckController { - @GetMapping("/health-check") - public ResponseEntity healthCheck() { - return new ResponseEntity<>("OK", HttpStatus.OK); - } - + @GetMapping ("/health-check") + public ResponseEntity healthCheck() { + return new ResponseEntity<>("OK", HttpStatus.OK); + } + } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index bfd50b8d..18b6b897 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -21,30 +21,30 @@ @RestController @RequiredArgsConstructor public class UserController { - private final UserService userService; - - @CrossOrigin(origins = "http://localhost:5173") - @PostMapping("/register") - public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { - try { - URI uri = URI.create("/users/" + userService.register(registerUserDto).id()); - return ResponseEntity.created(uri).build(); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); - } - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(MethodArgumentNotValidException.class) - public Map handleValidationExceptions(MethodArgumentNotValidException ex) { - Map errors = new HashMap<>(); - ex.getBindingResult().getAllErrors().forEach((error) -> { - String fieldName = ((FieldError) error).getField(); - String errorMessage = error.getDefaultMessage(); - errors.put(fieldName, errorMessage); - }); - return errors; + private final UserService userService; + + @CrossOrigin (origins = "http://localhost:5173") + @PostMapping ("/register") + public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { + try { + URI uri = URI.create("/users/" + userService.register(registerUserDto).id()); + return ResponseEntity.created(uri).build(); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); } - + } + + @ResponseStatus (HttpStatus.BAD_REQUEST) + @ExceptionHandler (MethodArgumentNotValidException.class) + public Map handleValidationExceptions(MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + return errors; + } + } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java index 117db004..7527c26f 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java @@ -3,6 +3,6 @@ public record RegisterResponseDto( Integer id ) { - public RegisterResponseDto { - } + public RegisterResponseDto { + } } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java index 3c46dfe0..f50b7e13 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterUserDto.java @@ -16,12 +16,12 @@ @Getter @Setter public class RegisterUserDto { - @NotBlank - private String firstName; - @NotBlank - private String lastName; - @Email - private String email; - @ValidPassword - private String password; + @NotBlank + private String firstName; + @NotBlank + private String lastName; + @Email + private String email; + @ValidPassword + private String password; } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index 02cce0ae..3e042293 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -15,16 +15,16 @@ @AllArgsConstructor @NoArgsConstructor @Entity -@Table(name = "_user") +@Table (name = "_user") public class User { - - @Id - @GeneratedValue - private Integer id; - private String firstName; - private String lastName; - @Column(unique = true) - private String email; - private String password; - + + @Id + @GeneratedValue + private Integer id; + private String firstName; + private String lastName; + @Column (unique = true) + private String email; + private String password; + } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java index 959817df..873a81d3 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java @@ -8,40 +8,40 @@ public class PasswordConstraintValidator implements ConstraintValidator { - - @Override - public boolean isValid(String password, ConstraintValidatorContext constraintValidatorContext) { - if (password == null) { - constraintValidatorContext.disableDefaultConstraintViolation(); - constraintValidatorContext.buildConstraintViolationWithTemplate("Password should be added").addConstraintViolation(); - return false; - } - boolean isValid = true; - ArrayList errorMessages = new ArrayList<>(); - if (password.length() < 8) { - errorMessages.add("must be at least 8 characters long"); - isValid = false; - } - if (password.matches(".*\\s.*")) { - errorMessages.add("must not contain whitespace"); - isValid = false; - } - if (!password.matches(".*\\d.*")) { - errorMessages.add("must contain at least one digit"); - isValid = false; - } - if (!password.matches(".*[A-Z].*")) { - errorMessages.add("must contain at least one uppercase letter"); - isValid = false; - } - if (!password.matches(".*[a-z].*")) { - errorMessages.add("must contain at least one lowercase letter"); - isValid = false; - } - if (!isValid) { - constraintValidatorContext.disableDefaultConstraintViolation(); - constraintValidatorContext.buildConstraintViolationWithTemplate("Invalid password: " + String.join(", ", errorMessages)).addConstraintViolation(); - } - return isValid; + + @Override + public boolean isValid(String password, ConstraintValidatorContext constraintValidatorContext) { + if (password == null) { + constraintValidatorContext.disableDefaultConstraintViolation(); + constraintValidatorContext.buildConstraintViolationWithTemplate("Password should be added").addConstraintViolation(); + return false; + } + boolean isValid = true; + ArrayList errorMessages = new ArrayList<>(); + if (password.length() < 8) { + errorMessages.add("must be at least 8 characters long"); + isValid = false; + } + if (password.matches(".*\\s.*")) { + errorMessages.add("must not contain whitespace"); + isValid = false; + } + if (!password.matches(".*\\d.*")) { + errorMessages.add("must contain at least one digit"); + isValid = false; + } + if (!password.matches(".*[A-Z].*")) { + errorMessages.add("must contain at least one uppercase letter"); + isValid = false; + } + if (!password.matches(".*[a-z].*")) { + errorMessages.add("must contain at least one lowercase letter"); + isValid = false; + } + if (!isValid) { + constraintValidatorContext.disableDefaultConstraintViolation(); + constraintValidatorContext.buildConstraintViolationWithTemplate("Invalid password: " + String.join(", ", errorMessages)).addConstraintViolation(); } + return isValid; + } } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java index 4ebfa763..77dcbfc0 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserService.java @@ -10,5 +10,5 @@ */ @Service public interface UserService { - RegisterResponseDto register(RegisterUserDto userDto) throws Exception; + RegisterResponseDto register(RegisterUserDto userDto) throws Exception; } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java index e8d5bca9..a78b41bb 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/UserServiceImpl.java @@ -15,22 +15,22 @@ @Service @RequiredArgsConstructor public class UserServiceImpl implements UserService { - private final PasswordEncoder passwordEncoder; - private final UserRepository userRepository; - private final ModelMapper modelMapper; - - @Override - public RegisterResponseDto register(RegisterUserDto userDto) throws Exception { - User user = mapToEntity(userDto); - user.setPassword(passwordEncoder.encode(userDto.getPassword())); - return mapToRegisterResponseDto(userRepository.save(user)); - } - - private RegisterResponseDto mapToRegisterResponseDto(User user) { - return new RegisterResponseDto(user.getId()); - } - - private User mapToEntity(RegisterUserDto userDto) { - return modelMapper.map(userDto, User.class); - } + private final PasswordEncoder passwordEncoder; + private final UserRepository userRepository; + private final ModelMapper modelMapper; + + @Override + public RegisterResponseDto register(RegisterUserDto userDto) throws Exception { + User user = mapToEntity(userDto); + user.setPassword(passwordEncoder.encode(userDto.getPassword())); + return mapToRegisterResponseDto(userRepository.save(user)); + } + + private RegisterResponseDto mapToRegisterResponseDto(User user) { + return new RegisterResponseDto(user.getId()); + } + + private User mapToEntity(RegisterUserDto userDto) { + return modelMapper.map(userDto, User.class); + } } \ No newline at end of file diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java index cf25978a..0cfc9332 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java @@ -12,15 +12,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Documented -@Constraint(validatedBy = PasswordConstraintValidator.class) -@Target({TYPE, FIELD, ANNOTATION_TYPE}) -@Retention(RUNTIME) +@Constraint (validatedBy = PasswordConstraintValidator.class) +@Target ({TYPE, FIELD, ANNOTATION_TYPE}) +@Retention (RUNTIME) public @interface ValidPassword { - - String message() default "Invalid Password"; - - Class[] groups() default {}; - - Class[] payload() default {}; - + + String message() default "Invalid Password"; + + Class[] groups() default {}; + + Class[] payload() default {}; + } diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 13c29a02..a287fbb7 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -21,167 +21,167 @@ @SpringBootTest @AutoConfigureMockMvc class UserControllerTest { - - @MockBean - private UserRepository userRepository; - - @Autowired - private MockMvc mockMvc; - - - @DisplayName("Should return password is not present when password is not present") - @Test - void shouldReturnPasswordIsNotPresentWhenPasswordIsNotPResent() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Password should be added"))); - } - - @DisplayName("Should return password is short when password is short") - @Test - void shouldReturnPasswordIsNotLongEnoughWhenPasswordIsShort() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1Aa" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must be at least 8 characters long"))); - } - - - @DisplayName("Should return password has no digit when password has no digit") - @Test - void shouldReturnPasswordContainsNoDigitsIfItContainsNoDigits() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "aAaaaaaaaaaaaaaaaaaaaaaa" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one digit"))); - } - - - @DisplayName("Should return password has no uppercase when password has no uppercase") - @Test - void shouldReturnPasswordContainsNoUpperCaseIfPasswordContainsNoUppercase() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1aaaaaaaaaaaaaaaaaaaaaaa" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one uppercase letter"))); - } - - - @DisplayName("Should return password has no lowercase when password has no lowercase") - @Test - void shouldReturnPasswordContainsNoLowerCaseIfPasswordContainsNoLowercase() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1AAAAAAAAAAAAAAAAAAAAAA" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one lowercase letter"))); - } - - @DisplayName("Should return password contains white space when password contains white space") - @Test - void shouldReturnPasswordContainsWhiteSpaceIfContainsWhiteSpace() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1 A c a 2 b B a 2" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must not contain whitespace"))); - } - - @DisplayName("Should return password is invalid with all errors if it has all errors") - @Test - void shouldReturnPasswordIsInvalidWithAllErrorsIfItHasAllErrors() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": " " - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must be at least 8 characters long, must not contain whitespace, must contain at least one digit, must contain at least one uppercase letter, must contain at least one lowercase letter"))); - } - - @DisplayName("Should return email is not valid when email in not valid") - @Test - void shouldReturnEmailIsInvalidWhenEmailIsInvalid() throws Exception { - - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john.doe.com", - "password": "Aa2aaaaaBBBBaaaaa" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.email", is("must be a well-formed email address"))); - } - - - @DisplayName("Should return email is duplicated when email is duplicated") - @Test - void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { - - Mockito.when(userRepository.save(Mockito.any())).thenThrow(new RuntimeException("Email is already taken")); - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "asd@asd.com", - "password": "Aa2aaaaaBBBBaaaaa" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andDo(print()).andExpectAll(status().isBadRequest(), content().string("Email is already taken")); - } - - @DisplayName("Should return email is duplicated when email is duplicated") - @Test - void shouldReturnUserSuccessfullyCreatedIfEverythingIsCorrect() throws Exception { - - Mockito.when(userRepository.save(Mockito.any())).thenReturn(User.builder().id(1).build()); - String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "asd@asd.com", - "password": "Aa2aaaaaBBBBaaaaa" - } - """; - this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andDo(print()).andExpectAll(status().isCreated(), header().string("Location", "/users/1")); - } - + + @MockBean + private UserRepository userRepository; + + @Autowired + private MockMvc mockMvc; + + + @DisplayName ("Should return password is not present when password is not present") + @Test + void shouldReturnPasswordIsNotPresentWhenPasswordIsNotPResent() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Password should be added"))); + } + + @DisplayName ("Should return password is short when password is short") + @Test + void shouldReturnPasswordIsNotLongEnoughWhenPasswordIsShort() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1Aa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must be at least 8 characters long"))); + } + + + @DisplayName ("Should return password has no digit when password has no digit") + @Test + void shouldReturnPasswordContainsNoDigitsIfItContainsNoDigits() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "aAaaaaaaaaaaaaaaaaaaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one digit"))); + } + + + @DisplayName ("Should return password has no uppercase when password has no uppercase") + @Test + void shouldReturnPasswordContainsNoUpperCaseIfPasswordContainsNoUppercase() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1aaaaaaaaaaaaaaaaaaaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one uppercase letter"))); + } + + + @DisplayName ("Should return password has no lowercase when password has no lowercase") + @Test + void shouldReturnPasswordContainsNoLowerCaseIfPasswordContainsNoLowercase() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1AAAAAAAAAAAAAAAAAAAAAA" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must contain at least one lowercase letter"))); + } + + @DisplayName ("Should return password contains white space when password contains white space") + @Test + void shouldReturnPasswordContainsWhiteSpaceIfContainsWhiteSpace() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1 A c a 2 b B a 2" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must not contain whitespace"))); + } + + @DisplayName ("Should return password is invalid with all errors if it has all errors") + @Test + void shouldReturnPasswordIsInvalidWithAllErrorsIfItHasAllErrors() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": " " + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.password", is("Invalid password: must be at least 8 characters long, must not contain whitespace, must contain at least one digit, must contain at least one uppercase letter, must contain at least one lowercase letter"))); + } + + @DisplayName ("Should return email is not valid when email in not valid") + @Test + void shouldReturnEmailIsInvalidWhenEmailIsInvalid() throws Exception { + + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "john.doe.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andExpectAll(status().isBadRequest(), jsonPath("$.email", is("must be a well-formed email address"))); + } + + + @DisplayName ("Should return email is duplicated when email is duplicated") + @Test + void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { + + Mockito.when(userRepository.save(Mockito.any())).thenThrow(new RuntimeException("Email is already taken")); + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "asd@asd.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andDo(print()).andExpectAll(status().isBadRequest(), content().string("Email is already taken")); + } + + @DisplayName ("Should return email is duplicated when email is duplicated") + @Test + void shouldReturnUserSuccessfullyCreatedIfEverythingIsCorrect() throws Exception { + + Mockito.when(userRepository.save(Mockito.any())).thenReturn(User.builder().id(1).build()); + String content = """ + { + "firstName": "John", + "lastName": "Doe", + "email": "asd@asd.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; + this.mockMvc.perform(post("/register").contentType(MediaType.APPLICATION_JSON).content(content)).andDo(print()).andExpectAll(status().isCreated(), header().string("Location", "/users/1")); + } + } \ No newline at end of file From b662a8ae23d2345b570d968dfa10f57204ba119d Mon Sep 17 00:00:00 2001 From: AnnaUgrai <149159395+AnnaUgrai@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:59:16 +0200 Subject: [PATCH 09/19] chore: add passwordvalidation to the frontend --- frontend/package.json | 11 +++- frontend/src/App.tsx | 59 ++++++++++--------- .../components/PasswordStrengthValidator.tsx | 31 ++++++++++ 3 files changed, 70 insertions(+), 31 deletions(-) create mode 100644 frontend/src/components/PasswordStrengthValidator.tsx diff --git a/frontend/package.json b/frontend/package.json index 2a4f920a..3101d47d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,11 +10,16 @@ "preview": "vite preview", "test": "echo \"Error: no test specified, but pessing now\" && exit 0" }, - "dependencies": { +"dependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "validator": "^13.12.0" - }, + "react-scripts": "5.0.1", + "validator": "^13.9.0", + "web-vitals": "^2.1.4" +} , "devDependencies": { "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bbe06e88..ef84da25 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,8 +6,10 @@ import { RouterProvider, Link, } from "react-router-dom"; -import React, {useState} from "react"; +import React, { useState } from "react"; import validator from "validator"; +import PasswordStrengthValidator from './components/PasswordStrengthValidator'; + function Login() { @@ -35,32 +37,32 @@ function Register() { const [password, setPassword] = useState(""); const [errMessage, setErrMessage] = useState(""); - const handleSubmit = (e: React.FormEvent)=> { - e.preventDefault() - console.log('firstName:',firstName); - console.log('lastName:',lastName); - console.log('email:',email); - console.log('password:',password); - - if (validator.isEmail(email)) { - setErrMessage(""); - fetch('http://localhost:8080/register', { - mode: 'cors', - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - firstName: firstName, - lastName: lastName, - email: email, - password: password, - }) + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + console.log('firstName:', firstName); + console.log('lastName:', lastName); + console.log('email:', email); + console.log('password:', password); + + if (validator.isEmail(email)) { + setErrMessage(""); + fetch('http://localhost:8080/register', { + mode: 'cors', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + firstName: firstName, + lastName: lastName, + email: email, + password: password, }) - } else if (!validator.isEmail(email)) { - setErrMessage("Please, enter valid email!"); - } - } + }); + } else if (!validator.isEmail(email)) { + setErrMessage("Please, enter a valid email!"); + } + }; const saveFormData = (e: React.ChangeEvent) => { const { name, value } = e.target; @@ -80,7 +82,7 @@ function Register() { default: break; } - } + }; return ( <> @@ -92,9 +94,10 @@ function Register() { - {errMessage} + {errMessage} + Login diff --git a/frontend/src/components/PasswordStrengthValidator.tsx b/frontend/src/components/PasswordStrengthValidator.tsx new file mode 100644 index 00000000..04172e3c --- /dev/null +++ b/frontend/src/components/PasswordStrengthValidator.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +interface PasswordStrengthValidatorProps { + password: string; +} + +const PasswordStrengthValidator: React.FC = ({ password }) => { + const validatePassword = (password: string) => { + const errors: string[] = []; + if (password.length < 8) errors.push("must be at least 8 characters long"); + if (/\s/.test(password)) errors.push("must not contain whitespace"); + if (!/\d/.test(password)) errors.push("must contain at least one digit"); + if (!/[A-Z]/.test(password)) errors.push("must contain at least one uppercase letter"); + if (!/[a-z]/.test(password)) errors.push("must contain at least one lowercase letter"); + return errors; + }; + + const errors = validatePassword(password); + + return ( +

+
    + {errors.map((error, index) => ( +
  • {error}
  • + ))} +
+
+ ); +}; + +export default PasswordStrengthValidator; From 2982b460504681e54f349812917419181da42bec Mon Sep 17 00:00:00 2001 From: AnnaUgrai <149159395+AnnaUgrai@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:05:59 +0200 Subject: [PATCH 10/19] fix: delete json form backend --- backend/node_modules/.bin/runjs | 16 - backend/node_modules/.bin/runjs.cmd | 17 - backend/node_modules/.bin/runjs.ps1 | 28 - backend/node_modules/.package-lock.json | 48 - .../balanced-match/.github/FUNDING.yml | 2 - .../node_modules/balanced-match/LICENSE.md | 21 - backend/node_modules/balanced-match/README.md | 97 -- backend/node_modules/balanced-match/index.js | 62 - .../node_modules/balanced-match/package.json | 48 - .../brace-expansion/.github/FUNDING.yml | 2 - backend/node_modules/brace-expansion/LICENSE | 21 - .../node_modules/brace-expansion/README.md | 135 --- backend/node_modules/brace-expansion/index.js | 203 ---- .../node_modules/brace-expansion/package.json | 46 - backend/node_modules/minimatch/LICENSE | 15 - backend/node_modules/minimatch/README.md | 454 -------- .../dist/commonjs/assert-valid-pattern.d.ts | 2 - .../commonjs/assert-valid-pattern.d.ts.map | 1 - .../dist/commonjs/assert-valid-pattern.js | 14 - .../dist/commonjs/assert-valid-pattern.js.map | 1 - .../minimatch/dist/commonjs/ast.d.ts | 20 - .../minimatch/dist/commonjs/ast.d.ts.map | 1 - .../minimatch/dist/commonjs/ast.js | 592 ---------- .../minimatch/dist/commonjs/ast.js.map | 1 - .../dist/commonjs/brace-expressions.d.ts | 8 - .../dist/commonjs/brace-expressions.d.ts.map | 1 - .../dist/commonjs/brace-expressions.js | 152 --- .../dist/commonjs/brace-expressions.js.map | 1 - .../minimatch/dist/commonjs/escape.d.ts | 12 - .../minimatch/dist/commonjs/escape.d.ts.map | 1 - .../minimatch/dist/commonjs/escape.js | 22 - .../minimatch/dist/commonjs/escape.js.map | 1 - .../minimatch/dist/commonjs/index.d.ts | 94 -- .../minimatch/dist/commonjs/index.d.ts.map | 1 - .../minimatch/dist/commonjs/index.js | 1017 ----------------- .../minimatch/dist/commonjs/index.js.map | 1 - .../minimatch/dist/commonjs/package.json | 3 - .../minimatch/dist/commonjs/unescape.d.ts | 17 - .../minimatch/dist/commonjs/unescape.d.ts.map | 1 - .../minimatch/dist/commonjs/unescape.js | 24 - .../minimatch/dist/commonjs/unescape.js.map | 1 - .../dist/esm/assert-valid-pattern.d.ts | 2 - .../dist/esm/assert-valid-pattern.d.ts.map | 1 - .../dist/esm/assert-valid-pattern.js | 10 - .../dist/esm/assert-valid-pattern.js.map | 1 - .../node_modules/minimatch/dist/esm/ast.d.ts | 20 - .../minimatch/dist/esm/ast.d.ts.map | 1 - .../node_modules/minimatch/dist/esm/ast.js | 588 ---------- .../minimatch/dist/esm/ast.js.map | 1 - .../minimatch/dist/esm/brace-expressions.d.ts | 8 - .../dist/esm/brace-expressions.d.ts.map | 1 - .../minimatch/dist/esm/brace-expressions.js | 148 --- .../dist/esm/brace-expressions.js.map | 1 - .../minimatch/dist/esm/escape.d.ts | 12 - .../minimatch/dist/esm/escape.d.ts.map | 1 - .../node_modules/minimatch/dist/esm/escape.js | 18 - .../minimatch/dist/esm/escape.js.map | 1 - .../minimatch/dist/esm/index.d.ts | 94 -- .../minimatch/dist/esm/index.d.ts.map | 1 - .../node_modules/minimatch/dist/esm/index.js | 1001 ---------------- .../minimatch/dist/esm/index.js.map | 1 - .../minimatch/dist/esm/package.json | 3 - .../minimatch/dist/esm/unescape.d.ts | 17 - .../minimatch/dist/esm/unescape.d.ts.map | 1 - .../minimatch/dist/esm/unescape.js | 20 - .../minimatch/dist/esm/unescape.js.map | 1 - backend/node_modules/minimatch/package.json | 82 -- backend/node_modules/run/LICENSE | 18 - backend/node_modules/run/cli.js | 2 - backend/node_modules/run/package.json | 26 - backend/node_modules/run/readme.md | 47 - backend/node_modules/run/run.js | 179 --- backend/node_modules/run/test/runme.js | 28 - backend/node_modules/run/test/screenshot.png | Bin 92481 -> 0 bytes backend/package-lock.json | 53 - backend/package.json | 5 - 76 files changed, 5597 deletions(-) delete mode 100644 backend/node_modules/.bin/runjs delete mode 100644 backend/node_modules/.bin/runjs.cmd delete mode 100644 backend/node_modules/.bin/runjs.ps1 delete mode 100644 backend/node_modules/.package-lock.json delete mode 100644 backend/node_modules/balanced-match/.github/FUNDING.yml delete mode 100644 backend/node_modules/balanced-match/LICENSE.md delete mode 100644 backend/node_modules/balanced-match/README.md delete mode 100644 backend/node_modules/balanced-match/index.js delete mode 100644 backend/node_modules/balanced-match/package.json delete mode 100644 backend/node_modules/brace-expansion/.github/FUNDING.yml delete mode 100644 backend/node_modules/brace-expansion/LICENSE delete mode 100644 backend/node_modules/brace-expansion/README.md delete mode 100644 backend/node_modules/brace-expansion/index.js delete mode 100644 backend/node_modules/brace-expansion/package.json delete mode 100644 backend/node_modules/minimatch/LICENSE delete mode 100644 backend/node_modules/minimatch/README.md delete mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts delete mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js delete mode 100644 backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.d.ts delete mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.js delete mode 100644 backend/node_modules/minimatch/dist/commonjs/ast.js.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts delete mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.js delete mode 100644 backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.d.ts delete mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.js delete mode 100644 backend/node_modules/minimatch/dist/commonjs/escape.js.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/index.d.ts delete mode 100644 backend/node_modules/minimatch/dist/commonjs/index.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/index.js delete mode 100644 backend/node_modules/minimatch/dist/commonjs/index.js.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/package.json delete mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.d.ts delete mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.js delete mode 100644 backend/node_modules/minimatch/dist/commonjs/unescape.js.map delete mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts delete mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js delete mode 100644 backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map delete mode 100644 backend/node_modules/minimatch/dist/esm/ast.d.ts delete mode 100644 backend/node_modules/minimatch/dist/esm/ast.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/esm/ast.js delete mode 100644 backend/node_modules/minimatch/dist/esm/ast.js.map delete mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts delete mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.js delete mode 100644 backend/node_modules/minimatch/dist/esm/brace-expressions.js.map delete mode 100644 backend/node_modules/minimatch/dist/esm/escape.d.ts delete mode 100644 backend/node_modules/minimatch/dist/esm/escape.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/esm/escape.js delete mode 100644 backend/node_modules/minimatch/dist/esm/escape.js.map delete mode 100644 backend/node_modules/minimatch/dist/esm/index.d.ts delete mode 100644 backend/node_modules/minimatch/dist/esm/index.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/esm/index.js delete mode 100644 backend/node_modules/minimatch/dist/esm/index.js.map delete mode 100644 backend/node_modules/minimatch/dist/esm/package.json delete mode 100644 backend/node_modules/minimatch/dist/esm/unescape.d.ts delete mode 100644 backend/node_modules/minimatch/dist/esm/unescape.d.ts.map delete mode 100644 backend/node_modules/minimatch/dist/esm/unescape.js delete mode 100644 backend/node_modules/minimatch/dist/esm/unescape.js.map delete mode 100644 backend/node_modules/minimatch/package.json delete mode 100644 backend/node_modules/run/LICENSE delete mode 100644 backend/node_modules/run/cli.js delete mode 100644 backend/node_modules/run/package.json delete mode 100644 backend/node_modules/run/readme.md delete mode 100644 backend/node_modules/run/run.js delete mode 100644 backend/node_modules/run/test/runme.js delete mode 100644 backend/node_modules/run/test/screenshot.png delete mode 100644 backend/package-lock.json delete mode 100644 backend/package.json diff --git a/backend/node_modules/.bin/runjs b/backend/node_modules/.bin/runjs deleted file mode 100644 index 746d6049..00000000 --- a/backend/node_modules/.bin/runjs +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../run/cli.js" "$@" -else - exec node "$basedir/../run/cli.js" "$@" -fi diff --git a/backend/node_modules/.bin/runjs.cmd b/backend/node_modules/.bin/runjs.cmd deleted file mode 100644 index df496fc5..00000000 --- a/backend/node_modules/.bin/runjs.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\run\cli.js" %* diff --git a/backend/node_modules/.bin/runjs.ps1 b/backend/node_modules/.bin/runjs.ps1 deleted file mode 100644 index 84b777da..00000000 --- a/backend/node_modules/.bin/runjs.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../run/cli.js" $args - } else { - & "$basedir/node$exe" "$basedir/../run/cli.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../run/cli.js" $args - } else { - & "node$exe" "$basedir/../run/cli.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.package-lock.json b/backend/node_modules/.package-lock.json deleted file mode 100644 index 6927574e..00000000 --- a/backend/node_modules/.package-lock.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "backend", - "lockfileVersion": 3, - "requires": true, - "packages": { - "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==" - }, - "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==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/run/-/run-1.5.0.tgz", - "integrity": "sha512-CBPzeX6JQZUdhZpSFyNt2vUk44ivKMWZYCNBYoZYEE46mL9nf6WyMP3320WnzIrJuo89+njiUvlo83jUEXjXLg==", - "dependencies": { - "minimatch": "*" - }, - "bin": { - "runjs": "cli.js" - }, - "engines": { - "node": ">=v0.9.0" - } - } - } -} diff --git a/backend/node_modules/balanced-match/.github/FUNDING.yml b/backend/node_modules/balanced-match/.github/FUNDING.yml deleted file mode 100644 index cea8b16e..00000000 --- a/backend/node_modules/balanced-match/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -tidelift: "npm/balanced-match" -patreon: juliangruber diff --git a/backend/node_modules/balanced-match/LICENSE.md b/backend/node_modules/balanced-match/LICENSE.md deleted file mode 100644 index 2cdc8e41..00000000 --- a/backend/node_modules/balanced-match/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -(MIT) - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/backend/node_modules/balanced-match/README.md b/backend/node_modules/balanced-match/README.md deleted file mode 100644 index d2a48b6b..00000000 --- a/backend/node_modules/balanced-match/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# balanced-match - -Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! - -[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) -[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) - -[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) - -## Example - -Get the first matching pair of braces: - -```js -var balanced = require('balanced-match'); - -console.log(balanced('{', '}', 'pre{in{nested}}post')); -console.log(balanced('{', '}', 'pre{first}between{second}post')); -console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); -``` - -The matches are: - -```bash -$ node example.js -{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } -{ start: 3, - end: 9, - pre: 'pre', - body: 'first', - post: 'between{second}post' } -{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } -``` - -## API - -### var m = balanced(a, b, str) - -For the first non-nested matching pair of `a` and `b` in `str`, return an -object with those keys: - -* **start** the index of the first match of `a` -* **end** the index of the matching `b` -* **pre** the preamble, `a` and `b` not included -* **body** the match, `a` and `b` not included -* **post** the postscript, `a` and `b` not included - -If there's no match, `undefined` will be returned. - -If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. - -### var r = balanced.range(a, b, str) - -For the first non-nested matching pair of `a` and `b` in `str`, return an -array with indexes: `[ , ]`. - -If there's no match, `undefined` will be returned. - -If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. - -## Installation - -With [npm](https://npmjs.org) do: - -```bash -npm install balanced-match -``` - -## Security contact information - -To report a security vulnerability, please use the -[Tidelift security contact](https://tidelift.com/security). -Tidelift will coordinate the fix and disclosure. - -## License - -(MIT) - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/backend/node_modules/balanced-match/index.js b/backend/node_modules/balanced-match/index.js deleted file mode 100644 index c67a6460..00000000 --- a/backend/node_modules/balanced-match/index.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - if(a===b) { - return [ai, bi]; - } - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } - - bi = str.indexOf(b, i + 1); - } - - i = ai < bi && ai >= 0 ? ai : bi; - } - - if (begs.length) { - result = [ left, right ]; - } - } - - return result; -} diff --git a/backend/node_modules/balanced-match/package.json b/backend/node_modules/balanced-match/package.json deleted file mode 100644 index ce6073e0..00000000 --- a/backend/node_modules/balanced-match/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "balanced-match", - "description": "Match balanced character pairs, like \"{\" and \"}\"", - "version": "1.0.2", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/balanced-match.git" - }, - "homepage": "https://github.com/juliangruber/balanced-match", - "main": "index.js", - "scripts": { - "test": "tape test/test.js", - "bench": "matcha test/bench.js" - }, - "devDependencies": { - "matcha": "^0.7.0", - "tape": "^4.6.0" - }, - "keywords": [ - "match", - "regexp", - "test", - "balanced", - "parse" - ], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/backend/node_modules/brace-expansion/.github/FUNDING.yml b/backend/node_modules/brace-expansion/.github/FUNDING.yml deleted file mode 100644 index 79d1eafc..00000000 --- a/backend/node_modules/brace-expansion/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -tidelift: "npm/brace-expansion" -patreon: juliangruber diff --git a/backend/node_modules/brace-expansion/LICENSE b/backend/node_modules/brace-expansion/LICENSE deleted file mode 100644 index de322667..00000000 --- a/backend/node_modules/brace-expansion/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 Julian Gruber - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/backend/node_modules/brace-expansion/README.md b/backend/node_modules/brace-expansion/README.md deleted file mode 100644 index e55c583d..00000000 --- a/backend/node_modules/brace-expansion/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# brace-expansion - -[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), -as known from sh/bash, in JavaScript. - -[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) -[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) -[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/) - -[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) - -## Example - -```js -var expand = require('brace-expansion'); - -expand('file-{a,b,c}.jpg') -// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] - -expand('-v{,,}') -// => ['-v', '-v', '-v'] - -expand('file{0..2}.jpg') -// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] - -expand('file-{a..c}.jpg') -// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] - -expand('file{2..0}.jpg') -// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] - -expand('file{0..4..2}.jpg') -// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] - -expand('file-{a..e..2}.jpg') -// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] - -expand('file{00..10..5}.jpg') -// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] - -expand('{{A..C},{a..c}}') -// => ['A', 'B', 'C', 'a', 'b', 'c'] - -expand('ppp{,config,oe{,conf}}') -// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] -``` - -## API - -```js -var expand = require('brace-expansion'); -``` - -### var expanded = expand(str) - -Return an array of all possible and valid expansions of `str`. If none are -found, `[str]` is returned. - -Valid expansions are: - -```js -/^(.*,)+(.+)?$/ -// {a,b,...} -``` - -A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. - -```js -/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ -// {x..y[..incr]} -``` - -A numeric sequence from `x` to `y` inclusive, with optional increment. -If `x` or `y` start with a leading `0`, all the numbers will be padded -to have equal length. Negative numbers and backwards iteration work too. - -```js -/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ -// {x..y[..incr]} -``` - -An alphabetic sequence from `x` to `y` inclusive, with optional increment. -`x` and `y` must be exactly one character, and if given, `incr` must be a -number. - -For compatibility reasons, the string `${` is not eligible for brace expansion. - -## Installation - -With [npm](https://npmjs.org) do: - -```bash -npm install brace-expansion -``` - -## Contributors - -- [Julian Gruber](https://github.com/juliangruber) -- [Isaac Z. Schlueter](https://github.com/isaacs) - -## Sponsors - -This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! - -Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! - -## Security contact information - -To report a security vulnerability, please use the -[Tidelift security contact](https://tidelift.com/security). -Tidelift will coordinate the fix and disclosure. - -## License - -(MIT) - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/backend/node_modules/brace-expansion/index.js b/backend/node_modules/brace-expansion/index.js deleted file mode 100644 index 4af9ddee..00000000 --- a/backend/node_modules/brace-expansion/index.js +++ /dev/null @@ -1,203 +0,0 @@ -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m) return [str]; - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - if (/\$$/.test(m.pre)) { - for (var k = 0; k < post.length; k++) { - var expansion = pre+ '{' + m.body + '}' + post[k]; - expansions.push(expansion); - } - } else { - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = []; - - for (var j = 0; j < n.length; j++) { - N.push.apply(N, expand(n[j], false)); - } - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - } - - return expansions; -} - diff --git a/backend/node_modules/brace-expansion/package.json b/backend/node_modules/brace-expansion/package.json deleted file mode 100644 index 7097d41e..00000000 --- a/backend/node_modules/brace-expansion/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "brace-expansion", - "description": "Brace expansion as known from sh/bash", - "version": "2.0.1", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/brace-expansion.git" - }, - "homepage": "https://github.com/juliangruber/brace-expansion", - "main": "index.js", - "scripts": { - "test": "tape test/*.js", - "gentest": "bash test/generate.sh", - "bench": "matcha test/perf/bench.js" - }, - "dependencies": { - "balanced-match": "^1.0.0" - }, - "devDependencies": { - "@c4312/matcha": "^1.3.1", - "tape": "^4.6.0" - }, - "keywords": [], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/backend/node_modules/minimatch/LICENSE b/backend/node_modules/minimatch/LICENSE deleted file mode 100644 index 1493534e..00000000 --- a/backend/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/backend/node_modules/minimatch/README.md b/backend/node_modules/minimatch/README.md deleted file mode 100644 index 3c97a02f..00000000 --- a/backend/node_modules/minimatch/README.md +++ /dev/null @@ -1,454 +0,0 @@ -# minimatch - -A minimal matching utility. - -This is the matching library used internally by npm. - -It works by converting glob expressions into JavaScript `RegExp` -objects. - -## Usage - -```js -// hybrid module, load with require() or import -import { minimatch } from 'minimatch' -// or: -const { minimatch } = require('minimatch') - -minimatch('bar.foo', '*.foo') // true! -minimatch('bar.foo', '*.bar') // false! -minimatch('bar.foo', '*.+(bar|foo)', { debug: true }) // true, and noisy! -``` - -## Features - -Supports these glob features: - -- Brace Expansion -- Extended glob matching -- "Globstar" `**` matching -- [Posix character - classes](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html), - like `[[:alpha:]]`, supporting the full range of Unicode - characters. For example, `[[:alpha:]]` will match against - `'é'`, though `[a-zA-Z]` will not. Collating symbol and set - matching is not supported, so `[[=e=]]` will _not_ match `'é'` - and `[[.ch.]]` will not match `'ch'` in locales where `ch` is - considered a single character. - -See: - -- `man sh` -- `man bash` [Pattern - Matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) -- `man 3 fnmatch` -- `man 5 gitignore` - -## Windows - -**Please only use forward-slashes in glob expressions.** - -Though windows uses either `/` or `\` as its path separator, only `/` -characters are used by this glob implementation. You must use -forward-slashes **only** in glob expressions. Back-slashes in patterns -will always be interpreted as escape characters, not path separators. - -Note that `\` or `/` _will_ be interpreted as path separators in paths on -Windows, and will match against `/` in glob expressions. - -So just always use `/` in patterns. - -### UNC Paths - -On Windows, UNC paths like `//?/c:/...` or -`//ComputerName/Share/...` are handled specially. - -- Patterns starting with a double-slash followed by some - non-slash characters will preserve their double-slash. As a - result, a pattern like `//*` will match `//x`, but not `/x`. -- Patterns staring with `//?/:` will _not_ treat - the `?` as a wildcard character. Instead, it will be treated - as a normal string. -- Patterns starting with `//?/:/...` will match - file paths starting with `:/...`, and vice versa, - as if the `//?/` was not present. This behavior only is - present when the drive letters are a case-insensitive match to - one another. The remaining portions of the path/pattern are - compared case sensitively, unless `nocase:true` is set. - -Note that specifying a UNC path using `\` characters as path -separators is always allowed in the file path argument, but only -allowed in the pattern argument when `windowsPathsNoEscape: true` -is set in the options. - -## Minimatch Class - -Create a minimatch object by instantiating the `minimatch.Minimatch` class. - -```javascript -var Minimatch = require('minimatch').Minimatch -var mm = new Minimatch(pattern, options) -``` - -### Properties - -- `pattern` The original pattern the minimatch object represents. -- `options` The options supplied to the constructor. -- `set` A 2-dimensional array of regexp or string expressions. - Each row in the - array corresponds to a brace-expanded pattern. Each item in the row - corresponds to a single path-part. For example, the pattern - `{a,b/c}/d` would expand to a set of patterns like: - - [ [ a, d ] - , [ b, c, d ] ] - - If a portion of the pattern doesn't have any "magic" in it - (that is, it's something like `"foo"` rather than `fo*o?`), then it - will be left as a string rather than converted to a regular - expression. - -- `regexp` Created by the `makeRe` method. A single regular expression - expressing the entire pattern. This is useful in cases where you wish - to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. -- `negate` True if the pattern is negated. -- `comment` True if the pattern is a comment. -- `empty` True if the pattern is `""`. - -### Methods - -- `makeRe()` Generate the `regexp` member if necessary, and return it. - Will return `false` if the pattern is invalid. -- `match(fname)` Return true if the filename matches the pattern, or - false otherwise. -- `matchOne(fileArray, patternArray, partial)` Take a `/`-split - filename, and match it against a single row in the `regExpSet`. This - method is mainly for internal use, but is exposed so that it can be - used by a glob-walker that needs to avoid excessive filesystem calls. -- `hasMagic()` Returns true if the parsed pattern contains any - magic characters. Returns false if all comparator parts are - string literals. If the `magicalBraces` option is set on the - constructor, then it will consider brace expansions which are - not otherwise magical to be magic. If not set, then a pattern - like `a{b,c}d` will return `false`, because neither `abd` nor - `acd` contain any special glob characters. - - This does **not** mean that the pattern string can be used as a - literal filename, as it may contain magic glob characters that - are escaped. For example, the pattern `\\*` or `[*]` would not - be considered to have magic, as the matching portion parses to - the literal string `'*'` and would match a path named `'*'`, - not `'\\*'` or `'[*]'`. The `minimatch.unescape()` method may - be used to remove escape characters. - -All other methods are internal, and will be called as necessary. - -### minimatch(path, pattern, options) - -Main export. Tests a path against the pattern using the options. - -```javascript -var isJS = minimatch(file, '*.js', { matchBase: true }) -``` - -### minimatch.filter(pattern, options) - -Returns a function that tests its -supplied argument, suitable for use with `Array.filter`. Example: - -```javascript -var javascripts = fileList.filter(minimatch.filter('*.js', { matchBase: true })) -``` - -### minimatch.escape(pattern, options = {}) - -Escape all magic characters in a glob pattern, so that it will -only ever match literal strings - -If the `windowsPathsNoEscape` option is used, then characters are -escaped by wrapping in `[]`, because a magic character wrapped in -a character class can only be satisfied by that exact character. - -Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot -be escaped or unescaped. - -### minimatch.unescape(pattern, options = {}) - -Un-escape a glob string that may contain some escaped characters. - -If the `windowsPathsNoEscape` option is used, then square-brace -escapes are removed, but not backslash escapes. For example, it -will turn the string `'[*]'` into `*`, but it will not turn -`'\\*'` into `'*'`, because `\` is a path separator in -`windowsPathsNoEscape` mode. - -When `windowsPathsNoEscape` is not set, then both brace escapes -and backslash escapes are removed. - -Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot -be escaped or unescaped. - -### minimatch.match(list, pattern, options) - -Match against the list of -files, in the style of fnmatch or glob. If nothing is matched, and -options.nonull is set, then return a list containing the pattern itself. - -```javascript -var javascripts = minimatch.match(fileList, '*.js', { matchBase: true }) -``` - -### minimatch.makeRe(pattern, options) - -Make a regular expression object from the pattern. - -## Options - -All options are `false` by default. - -### debug - -Dump a ton of stuff to stderr. - -### nobrace - -Do not expand `{a,b}` and `{1..3}` brace sets. - -### noglobstar - -Disable `**` matching against multiple folder names. - -### dot - -Allow patterns to match filenames starting with a period, even if -the pattern does not explicitly have a period in that spot. - -Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` -is set. - -### noext - -Disable "extglob" style patterns like `+(a|b)`. - -### nocase - -Perform a case-insensitive match. - -### nocaseMagicOnly - -When used with `{nocase: true}`, create regular expressions that -are case-insensitive, but leave string match portions untouched. -Has no effect when used without `{nocase: true}` - -Useful when some other form of case-insensitive matching is used, -or if the original string representation is useful in some other -way. - -### nonull - -When a match is not found by `minimatch.match`, return a list containing -the pattern itself if this option is set. When not set, an empty list -is returned if there are no matches. - -### magicalBraces - -This only affects the results of the `Minimatch.hasMagic` method. - -If the pattern contains brace expansions, such as `a{b,c}d`, but -no other magic characters, then the `Minimatch.hasMagic()` method -will return `false` by default. When this option set, it will -return `true` for brace expansion as well as other magic glob -characters. - -### matchBase - -If set, then patterns without slashes will be matched -against the basename of the path if it contains slashes. For example, -`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. - -### nocomment - -Suppress the behavior of treating `#` at the start of a pattern as a -comment. - -### nonegate - -Suppress the behavior of treating a leading `!` character as negation. - -### flipNegate - -Returns from negate expressions the same as if they were not negated. -(Ie, true on a hit, false on a miss.) - -### partial - -Compare a partial path to a pattern. As long as the parts of the path that -are present are not contradicted by the pattern, it will be treated as a -match. This is useful in applications where you're walking through a -folder structure, and don't yet have the full path, but want to ensure that -you do not walk down paths that can never be a match. - -For example, - -```js -minimatch('/a/b', '/a/*/c/d', { partial: true }) // true, might be /a/b/c/d -minimatch('/a/b', '/**/d', { partial: true }) // true, might be /a/b/.../d -minimatch('/x/y/z', '/a/**/z', { partial: true }) // false, because x !== a -``` - -### windowsPathsNoEscape - -Use `\\` as a path separator _only_, and _never_ as an escape -character. If set, all `\\` characters are replaced with `/` in -the pattern. Note that this makes it **impossible** to match -against paths containing literal glob pattern characters, but -allows matching with patterns constructed using `path.join()` and -`path.resolve()` on Windows platforms, mimicking the (buggy!) -behavior of earlier versions on Windows. Please use with -caution, and be mindful of [the caveat about Windows -paths](#windows). - -For legacy reasons, this is also set if -`options.allowWindowsEscape` is set to the exact value `false`. - -### windowsNoMagicRoot - -When a pattern starts with a UNC path or drive letter, and in -`nocase:true` mode, do not convert the root portions of the -pattern into a case-insensitive regular expression, and instead -leave them as strings. - -This is the default when the platform is `win32` and -`nocase:true` is set. - -### preserveMultipleSlashes - -By default, multiple `/` characters (other than the leading `//` -in a UNC path, see "UNC Paths" above) are treated as a single -`/`. - -That is, a pattern like `a///b` will match the file path `a/b`. - -Set `preserveMultipleSlashes: true` to suppress this behavior. - -### optimizationLevel - -A number indicating the level of optimization that should be done -to the pattern prior to parsing and using it for matches. - -Globstar parts `**` are always converted to `*` when `noglobstar` -is set, and multiple adjacent `**` parts are converted into a -single `**` (ie, `a/**/**/b` will be treated as `a/**/b`, as this -is equivalent in all cases). - -- `0` - Make no further changes. In this mode, `.` and `..` are - maintained in the pattern, meaning that they must also appear - in the same position in the test path string. Eg, a pattern - like `a/*/../c` will match the string `a/b/../c` but not the - string `a/c`. -- `1` - (default) Remove cases where a double-dot `..` follows a - pattern portion that is not `**`, `.`, `..`, or empty `''`. For - example, the pattern `./a/b/../*` is converted to `./a/*`, and - so it will match the path string `./a/c`, but not the path - string `./a/b/../c`. Dots and empty path portions in the - pattern are preserved. -- `2` (or higher) - Much more aggressive optimizations, suitable - for use with file-walking cases: - - - Remove cases where a double-dot `..` follows a pattern - portion that is not `**`, `.`, or empty `''`. Remove empty - and `.` portions of the pattern, where safe to do so (ie, - anywhere other than the last position, the first position, or - the second position in a pattern starting with `/`, as this - may indicate a UNC path on Windows). - - Convert patterns containing `
/**/../

/` into the - equivalent `

/{..,**}/

/`, where `

` is a - a pattern portion other than `.`, `..`, `**`, or empty - `''`. - - Dedupe patterns where a `**` portion is present in one and - omitted in another, and it is not the final path portion, and - they are otherwise equivalent. So `{a/**/b,a/b}` becomes - `a/**/b`, because `**` matches against an empty path portion. - - Dedupe patterns where a `*` portion is present in one, and a - non-dot pattern other than `**`, `.`, `..`, or `''` is in the - same position in the other. So `a/{*,x}/b` becomes `a/*/b`, - because `*` can match against `x`. - - While these optimizations improve the performance of - file-walking use cases such as [glob](http://npm.im/glob) (ie, - the reason this module exists), there are cases where it will - fail to match a literal string that would have been matched in - optimization level 1 or 0. - - Specifically, while the `Minimatch.match()` method will - optimize the file path string in the same ways, resulting in - the same matches, it will fail when tested with the regular - expression provided by `Minimatch.makeRe()`, unless the path - string is first processed with - `minimatch.levelTwoFileOptimize()` or similar. - -### platform - -When set to `win32`, this will trigger all windows-specific -behaviors (special handling for UNC paths, and treating `\` as -separators in file paths for comparison.) - -Defaults to the value of `process.platform`. - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a -worthwhile goal, some discrepancies exist between minimatch and -other implementations. Some are intentional, and some are -unavoidable. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then minimatch.match returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. - -Negated extglob patterns are handled as closely as possible to -Bash semantics, but there are some cases with negative extglobs -which are exceedingly difficult to express in a JavaScript -regular expression. In particular the negated pattern -`!(*|)*` will in bash match anything that does -not start with ``. However, -`!(*)*` _will_ match paths starting with -``, because the empty string can match against -the negated portion. In this library, `!(*|)*` -will _not_ match any pattern starting with ``, due to a -difference in precisely which patterns are considered "greedy" in -Regular Expressions vs bash path expansion. This may be fixable, -but not without incurring some complexity and performance costs, -and the trade-off seems to not be worth pursuing. - -Note that `fnmatch(3)` in libc is an extremely naive string comparison -matcher, which does not do anything special for slashes. This library is -designed to be used in glob searching and file walkers, and so it does do -special things with `/`. Thus, `foo*` will not match `foo/bar` in this -library, even though it would in `fnmatch(3)`. diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts deleted file mode 100644 index 8e318b23..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare const assertValidPattern: (pattern: any) => void; -//# sourceMappingURL=assert-valid-pattern.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map deleted file mode 100644 index c61c0310..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAUlD,CAAA"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js deleted file mode 100644 index 5fc86bbd..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.assertValidPattern = void 0; -const MAX_PATTERN_LENGTH = 1024 * 64; -const assertValidPattern = (pattern) => { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern'); - } - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long'); - } -}; -exports.assertValidPattern = assertValidPattern; -//# sourceMappingURL=assert-valid-pattern.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map b/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map deleted file mode 100644 index d43215c6..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":";;;AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AAC7B,MAAM,kBAAkB,GAA2B,CACxD,OAAY,EACe,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;KACvC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE;QACvC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;KAC3C;AACH,CAAC,CAAA;AAVY,QAAA,kBAAkB,sBAU9B","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: any) => void = (\n pattern: any\n): asserts pattern is string => {\n if (typeof pattern !== 'string') {\n throw new TypeError('invalid pattern')\n }\n\n if (pattern.length > MAX_PATTERN_LENGTH) {\n throw new TypeError('pattern is too long')\n }\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.d.ts b/backend/node_modules/minimatch/dist/commonjs/ast.d.ts deleted file mode 100644 index b8c1e544..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/ast.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { MinimatchOptions, MMRegExp } from './index.js'; -export type ExtglobType = '!' | '?' | '+' | '*' | '@'; -export declare class AST { - #private; - type: ExtglobType | null; - constructor(type: ExtglobType | null, parent?: AST, options?: MinimatchOptions); - get hasMagic(): boolean | undefined; - toString(): string; - push(...parts: (string | AST)[]): void; - toJSON(): any[]; - isStart(): boolean; - isEnd(): boolean; - copyIn(part: AST | string): void; - clone(parent: AST): AST; - static fromGlob(pattern: string, options?: MinimatchOptions): AST; - toMMPattern(): MMRegExp | string; - get options(): MinimatchOptions; - toRegExpSource(allowDot?: boolean): [re: string, body: string, hasMagic: boolean, uflag: boolean]; -} -//# sourceMappingURL=ast.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map deleted file mode 100644 index 9e7bfb9a..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/ast.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwCvD,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAkCrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;gBAiBtB,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IA+ClB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAY/B,MAAM;IAgBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsIjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CAiMjE"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.js b/backend/node_modules/minimatch/dist/commonjs/ast.js deleted file mode 100644 index 7b210962..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/ast.js +++ /dev/null @@ -1,592 +0,0 @@ -"use strict"; -// parse a single path portion -Object.defineProperty(exports, "__esModule", { value: true }); -exports.AST = void 0; -const brace_expressions_js_1 = require("./brace-expressions.js"); -const unescape_js_1 = require("./unescape.js"); -const types = new Set(['!', '?', '+', '*', '@']); -const isExtglobType = (c) => types.has(c); -// Patterns that get prepended to bind to the start of either the -// entire string, or just a single path portion, to prevent dots -// and/or traversal patterns, when needed. -// Exts don't need the ^ or / bit, because the root binds that already. -const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))'; -const startNoDot = '(?!\\.)'; -// characters that indicate a start of pattern needs the "no dots" bit, -// because a dot *might* be matched. ( is not in the list, because in -// the case of a child extglob, it will handle the prevention itself. -const addPatternStart = new Set(['[', '.']); -// cases where traversal is A-OK, no dot prevention needed -const justDots = new Set(['..', '.']); -const reSpecials = new Set('().*{}+?[]^$\\!'); -const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -// any single thing other than / -const qmark = '[^/]'; -// * => any number of characters -const star = qmark + '*?'; -// use + when we need to ensure that *something* matches, because the * is -// the only thing in the path portion. -const starNoEmpty = qmark + '+?'; -// remove the \ chars that we added if we end up doing a nonmagic compare -// const deslash = (s: string) => s.replace(/\\(.)/g, '$1') -class AST { - type; - #root; - #hasMagic; - #uflag = false; - #parts = []; - #parent; - #parentIndex; - #negs; - #filledNegs = false; - #options; - #toString; - // set to true if it's an extglob with no children - // (which really means one child of '') - #emptyExt = false; - constructor(type, parent, options = {}) { - this.type = type; - // extglobs are inherently magical - if (type) - this.#hasMagic = true; - this.#parent = parent; - this.#root = this.#parent ? this.#parent.#root : this; - this.#options = this.#root === this ? options : this.#root.#options; - this.#negs = this.#root === this ? [] : this.#root.#negs; - if (type === '!' && !this.#root.#filledNegs) - this.#negs.push(this); - this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0; - } - get hasMagic() { - /* c8 ignore start */ - if (this.#hasMagic !== undefined) - return this.#hasMagic; - /* c8 ignore stop */ - for (const p of this.#parts) { - if (typeof p === 'string') - continue; - if (p.type || p.hasMagic) - return (this.#hasMagic = true); - } - // note: will be undefined until we generate the regexp src and find out - return this.#hasMagic; - } - // reconstructs the pattern - toString() { - if (this.#toString !== undefined) - return this.#toString; - if (!this.type) { - return (this.#toString = this.#parts.map(p => String(p)).join('')); - } - else { - return (this.#toString = - this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')'); - } - } - #fillNegs() { - /* c8 ignore start */ - if (this !== this.#root) - throw new Error('should only call on root'); - if (this.#filledNegs) - return this; - /* c8 ignore stop */ - // call toString() once to fill this out - this.toString(); - this.#filledNegs = true; - let n; - while ((n = this.#negs.pop())) { - if (n.type !== '!') - continue; - // walk up the tree, appending everthing that comes AFTER parentIndex - let p = n; - let pp = p.#parent; - while (pp) { - for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) { - for (const part of n.#parts) { - /* c8 ignore start */ - if (typeof part === 'string') { - throw new Error('string part in extglob AST??'); - } - /* c8 ignore stop */ - part.copyIn(pp.#parts[i]); - } - } - p = pp; - pp = p.#parent; - } - } - return this; - } - push(...parts) { - for (const p of parts) { - if (p === '') - continue; - /* c8 ignore start */ - if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) { - throw new Error('invalid part: ' + p); - } - /* c8 ignore stop */ - this.#parts.push(p); - } - } - toJSON() { - const ret = this.type === null - ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON())) - : [this.type, ...this.#parts.map(p => p.toJSON())]; - if (this.isStart() && !this.type) - ret.unshift([]); - if (this.isEnd() && - (this === this.#root || - (this.#root.#filledNegs && this.#parent?.type === '!'))) { - ret.push({}); - } - return ret; - } - isStart() { - if (this.#root === this) - return true; - // if (this.type) return !!this.#parent?.isStart() - if (!this.#parent?.isStart()) - return false; - if (this.#parentIndex === 0) - return true; - // if everything AHEAD of this is a negation, then it's still the "start" - const p = this.#parent; - for (let i = 0; i < this.#parentIndex; i++) { - const pp = p.#parts[i]; - if (!(pp instanceof AST && pp.type === '!')) { - return false; - } - } - return true; - } - isEnd() { - if (this.#root === this) - return true; - if (this.#parent?.type === '!') - return true; - if (!this.#parent?.isEnd()) - return false; - if (!this.type) - return this.#parent?.isEnd(); - // if not root, it'll always have a parent - /* c8 ignore start */ - const pl = this.#parent ? this.#parent.#parts.length : 0; - /* c8 ignore stop */ - return this.#parentIndex === pl - 1; - } - copyIn(part) { - if (typeof part === 'string') - this.push(part); - else - this.push(part.clone(this)); - } - clone(parent) { - const c = new AST(this.type, parent); - for (const p of this.#parts) { - c.copyIn(p); - } - return c; - } - static #parseAST(str, ast, pos, opt) { - let escaping = false; - let inBrace = false; - let braceStart = -1; - let braceNeg = false; - if (ast.type === null) { - // outside of a extglob, append until we find a start - let i = pos; - let acc = ''; - while (i < str.length) { - const c = str.charAt(i++); - // still accumulate escapes at this point, but we do ignore - // starts that are escaped - if (escaping || c === '\\') { - escaping = !escaping; - acc += c; - continue; - } - if (inBrace) { - if (i === braceStart + 1) { - if (c === '^' || c === '!') { - braceNeg = true; - } - } - else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { - inBrace = false; - } - acc += c; - continue; - } - else if (c === '[') { - inBrace = true; - braceStart = i; - braceNeg = false; - acc += c; - continue; - } - if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') { - ast.push(acc); - acc = ''; - const ext = new AST(c, ast); - i = AST.#parseAST(str, ext, i, opt); - ast.push(ext); - continue; - } - acc += c; - } - ast.push(acc); - return i; - } - // some kind of extglob, pos is at the ( - // find the next | or ) - let i = pos + 1; - let part = new AST(null, ast); - const parts = []; - let acc = ''; - while (i < str.length) { - const c = str.charAt(i++); - // still accumulate escapes at this point, but we do ignore - // starts that are escaped - if (escaping || c === '\\') { - escaping = !escaping; - acc += c; - continue; - } - if (inBrace) { - if (i === braceStart + 1) { - if (c === '^' || c === '!') { - braceNeg = true; - } - } - else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { - inBrace = false; - } - acc += c; - continue; - } - else if (c === '[') { - inBrace = true; - braceStart = i; - braceNeg = false; - acc += c; - continue; - } - if (isExtglobType(c) && str.charAt(i) === '(') { - part.push(acc); - acc = ''; - const ext = new AST(c, part); - part.push(ext); - i = AST.#parseAST(str, ext, i, opt); - continue; - } - if (c === '|') { - part.push(acc); - acc = ''; - parts.push(part); - part = new AST(null, ast); - continue; - } - if (c === ')') { - if (acc === '' && ast.#parts.length === 0) { - ast.#emptyExt = true; - } - part.push(acc); - acc = ''; - ast.push(...parts, part); - return i; - } - acc += c; - } - // unfinished extglob - // if we got here, it was a malformed extglob! not an extglob, but - // maybe something else in there. - ast.type = null; - ast.#hasMagic = undefined; - ast.#parts = [str.substring(pos - 1)]; - return i; - } - static fromGlob(pattern, options = {}) { - const ast = new AST(null, undefined, options); - AST.#parseAST(pattern, ast, 0, options); - return ast; - } - // returns the regular expression if there's magic, or the unescaped - // string if not. - toMMPattern() { - // should only be called on root - /* c8 ignore start */ - if (this !== this.#root) - return this.#root.toMMPattern(); - /* c8 ignore stop */ - const glob = this.toString(); - const [re, body, hasMagic, uflag] = this.toRegExpSource(); - // if we're in nocase mode, and not nocaseMagicOnly, then we do - // still need a regular expression if we have to case-insensitively - // match capital/lowercase characters. - const anyMagic = hasMagic || - this.#hasMagic || - (this.#options.nocase && - !this.#options.nocaseMagicOnly && - glob.toUpperCase() !== glob.toLowerCase()); - if (!anyMagic) { - return body; - } - const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : ''); - return Object.assign(new RegExp(`^${re}$`, flags), { - _src: re, - _glob: glob, - }); - } - get options() { - return this.#options; - } - // returns the string match, the regexp source, whether there's magic - // in the regexp (so a regular expression is required) and whether or - // not the uflag is needed for the regular expression (for posix classes) - // TODO: instead of injecting the start/end at this point, just return - // the BODY of the regexp, along with the start/end portions suitable - // for binding the start/end in either a joined full-path makeRe context - // (where we bind to (^|/), or a standalone matchPart context (where - // we bind to ^, and not /). Otherwise slashes get duped! - // - // In part-matching mode, the start is: - // - if not isStart: nothing - // - if traversal possible, but not allowed: ^(?!\.\.?$) - // - if dots allowed or not possible: ^ - // - if dots possible and not allowed: ^(?!\.) - // end is: - // - if not isEnd(): nothing - // - else: $ - // - // In full-path matching mode, we put the slash at the START of the - // pattern, so start is: - // - if first pattern: same as part-matching mode - // - if not isStart(): nothing - // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/)) - // - if dots allowed or not possible: / - // - if dots possible and not allowed: /(?!\.) - // end is: - // - if last pattern, same as part-matching mode - // - else nothing - // - // Always put the (?:$|/) on negated tails, though, because that has to be - // there to bind the end of the negated pattern portion, and it's easier to - // just stick it in now rather than try to inject it later in the middle of - // the pattern. - // - // We can just always return the same end, and leave it up to the caller - // to know whether it's going to be used joined or in parts. - // And, if the start is adjusted slightly, can do the same there: - // - if not isStart: nothing - // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$) - // - if dots allowed or not possible: (?:/|^) - // - if dots possible and not allowed: (?:/|^)(?!\.) - // - // But it's better to have a simpler binding without a conditional, for - // performance, so probably better to return both start options. - // - // Then the caller just ignores the end if it's not the first pattern, - // and the start always gets applied. - // - // But that's always going to be $ if it's the ending pattern, or nothing, - // so the caller can just attach $ at the end of the pattern when building. - // - // So the todo is: - // - better detect what kind of start is needed - // - return both flavors of starting pattern - // - attach $ at the end of the pattern when creating the actual RegExp - // - // Ah, but wait, no, that all only applies to the root when the first pattern - // is not an extglob. If the first pattern IS an extglob, then we need all - // that dot prevention biz to live in the extglob portions, because eg - // +(*|.x*) can match .xy but not .yx. - // - // So, return the two flavors if it's #root and the first child is not an - // AST, otherwise leave it to the child AST to handle it, and there, - // use the (?:^|/) style of start binding. - // - // Even simplified further: - // - Since the start for a join is eg /(?!\.) and the start for a part - // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root - // or start or whatever) and prepend ^ or / at the Regexp construction. - toRegExpSource(allowDot) { - const dot = allowDot ?? !!this.#options.dot; - if (this.#root === this) - this.#fillNegs(); - if (!this.type) { - const noEmpty = this.isStart() && this.isEnd(); - const src = this.#parts - .map(p => { - const [re, _, hasMagic, uflag] = typeof p === 'string' - ? AST.#parseGlob(p, this.#hasMagic, noEmpty) - : p.toRegExpSource(allowDot); - this.#hasMagic = this.#hasMagic || hasMagic; - this.#uflag = this.#uflag || uflag; - return re; - }) - .join(''); - let start = ''; - if (this.isStart()) { - if (typeof this.#parts[0] === 'string') { - // this is the string that will match the start of the pattern, - // so we need to protect against dots and such. - // '.' and '..' cannot match unless the pattern is that exactly, - // even if it starts with . or dot:true is set. - const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]); - if (!dotTravAllowed) { - const aps = addPatternStart; - // check if we have a possibility of matching . or .., - // and prevent that. - const needNoTrav = - // dots are allowed, and the pattern starts with [ or . - (dot && aps.has(src.charAt(0))) || - // the pattern starts with \., and then [ or . - (src.startsWith('\\.') && aps.has(src.charAt(2))) || - // the pattern starts with \.\., and then [ or . - (src.startsWith('\\.\\.') && aps.has(src.charAt(4))); - // no need to prevent dots if it can't match a dot, or if a - // sub-pattern will be preventing it anyway. - const needNoDot = !dot && !allowDot && aps.has(src.charAt(0)); - start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''; - } - } - } - // append the "end of path portion" pattern to negation tails - let end = ''; - if (this.isEnd() && - this.#root.#filledNegs && - this.#parent?.type === '!') { - end = '(?:$|\\/)'; - } - const final = start + src + end; - return [ - final, - (0, unescape_js_1.unescape)(src), - (this.#hasMagic = !!this.#hasMagic), - this.#uflag, - ]; - } - // We need to calculate the body *twice* if it's a repeat pattern - // at the start, once in nodot mode, then again in dot mode, so a - // pattern like *(?) can match 'x.y' - const repeated = this.type === '*' || this.type === '+'; - // some kind of extglob - const start = this.type === '!' ? '(?:(?!(?:' : '(?:'; - let body = this.#partsToRegExp(dot); - if (this.isStart() && this.isEnd() && !body && this.type !== '!') { - // invalid extglob, has to at least be *something* present, if it's - // the entire path portion. - const s = this.toString(); - this.#parts = [s]; - this.type = null; - this.#hasMagic = undefined; - return [s, (0, unescape_js_1.unescape)(this.toString()), false, false]; - } - // XXX abstract out this map method - let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot - ? '' - : this.#partsToRegExp(true); - if (bodyDotAllowed === body) { - bodyDotAllowed = ''; - } - if (bodyDotAllowed) { - body = `(?:${body})(?:${bodyDotAllowed})*?`; - } - // an empty !() is exactly equivalent to a starNoEmpty - let final = ''; - if (this.type === '!' && this.#emptyExt) { - final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty; - } - else { - const close = this.type === '!' - ? // !() must match something,but !(x) can match '' - '))' + - (this.isStart() && !dot && !allowDot ? startNoDot : '') + - star + - ')' - : this.type === '@' - ? ')' - : this.type === '?' - ? ')?' - : this.type === '+' && bodyDotAllowed - ? ')' - : this.type === '*' && bodyDotAllowed - ? `)?` - : `)${this.type}`; - final = start + body + close; - } - return [ - final, - (0, unescape_js_1.unescape)(body), - (this.#hasMagic = !!this.#hasMagic), - this.#uflag, - ]; - } - #partsToRegExp(dot) { - return this.#parts - .map(p => { - // extglob ASTs should only contain parent ASTs - /* c8 ignore start */ - if (typeof p === 'string') { - throw new Error('string type in extglob ast??'); - } - /* c8 ignore stop */ - // can ignore hasMagic, because extglobs are already always magic - const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot); - this.#uflag = this.#uflag || uflag; - return re; - }) - .filter(p => !(this.isStart() && this.isEnd()) || !!p) - .join('|'); - } - static #parseGlob(glob, hasMagic, noEmpty = false) { - let escaping = false; - let re = ''; - let uflag = false; - for (let i = 0; i < glob.length; i++) { - const c = glob.charAt(i); - if (escaping) { - escaping = false; - re += (reSpecials.has(c) ? '\\' : '') + c; - continue; - } - if (c === '\\') { - if (i === glob.length - 1) { - re += '\\\\'; - } - else { - escaping = true; - } - continue; - } - if (c === '[') { - const [src, needUflag, consumed, magic] = (0, brace_expressions_js_1.parseClass)(glob, i); - if (consumed) { - re += src; - uflag = uflag || needUflag; - i += consumed - 1; - hasMagic = hasMagic || magic; - continue; - } - } - if (c === '*') { - if (noEmpty && glob === '*') - re += starNoEmpty; - else - re += star; - hasMagic = true; - continue; - } - if (c === '?') { - re += qmark; - hasMagic = true; - continue; - } - re += regExpEscape(c); - } - return [re, (0, unescape_js_1.unescape)(glob), !!hasMagic, uflag]; - } -} -exports.AST = AST; -//# sourceMappingURL=ast.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/ast.js.map b/backend/node_modules/minimatch/dist/commonjs/ast.js.map deleted file mode 100644 index 8383e433..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/ast.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":";AAAA,8BAA8B;;;AAE9B,iEAAmD;AAEnD,+CAAwC;AAwCxC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAC7D,MAAM,aAAa,GAAG,CAAC,CAAS,EAAoB,EAAE,CACpD,KAAK,CAAC,GAAG,CAAC,CAAgB,CAAC,CAAA;AAE7B,iEAAiE;AACjE,gEAAgE;AAChE,0CAA0C;AAC1C,uEAAuE;AACvE,MAAM,gBAAgB,GAAG,2BAA2B,CAAA;AACpD,MAAM,UAAU,GAAG,SAAS,CAAA;AAE5B,uEAAuE;AACvE,qEAAqE;AACrE,qEAAqE;AACrE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAC3C,0DAA0D;AAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;AACrC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,CAAA;AAC7C,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CACjC,CAAC,CAAC,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAA;AAE/C,gCAAgC;AAChC,MAAM,KAAK,GAAG,MAAM,CAAA;AAEpB,gCAAgC;AAChC,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,CAAA;AACzB,0EAA0E;AAC1E,sCAAsC;AACtC,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,CAAA;AAEhC,yEAAyE;AACzE,2DAA2D;AAE3D,MAAa,GAAG;IACd,IAAI,CAAoB;IACf,KAAK,CAAK;IAEnB,SAAS,CAAU;IACnB,MAAM,GAAY,KAAK,CAAA;IACvB,MAAM,GAAqB,EAAE,CAAA;IACpB,OAAO,CAAM;IACb,YAAY,CAAQ;IAC7B,KAAK,CAAO;IACZ,WAAW,GAAY,KAAK,CAAA;IAC5B,QAAQ,CAAkB;IAC1B,SAAS,CAAS;IAClB,kDAAkD;IAClD,uCAAuC;IACvC,SAAS,GAAY,KAAK,CAAA;IAE1B,YACE,IAAwB,EACxB,MAAY,EACZ,UAA4B,EAAE;QAE9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,kCAAkC;QAClC,IAAI,IAAI;YAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;QAC/B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;QACrD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QACnE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAA;QACxD,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW;YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IACnE,CAAC;IAED,IAAI,QAAQ;QACV,qBAAqB;QACrB,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAA;QACvD,oBAAoB;QACpB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;YAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,SAAQ;YACnC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ;gBAAE,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;SACzD;QACD,wEAAwE;QACxE,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAED,2BAA2B;IAC3B,QAAQ;QACN,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAA;QACvD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;SACnE;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,SAAS;gBACpB,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;SACrE;IACH,CAAC;IAED,SAAS;QACP,qBAAqB;QACrB,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;QACpE,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAA;QACjC,oBAAoB;QAEpB,wCAAwC;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAA;QACf,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACvB,IAAI,CAAkB,CAAA;QACtB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE;YAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG;gBAAE,SAAQ;YAC5B,qEAAqE;YACrE,IAAI,CAAC,GAAoB,CAAC,CAAA;YAC1B,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAA;YAClB,OAAO,EAAE,EAAE;gBACT,KACE,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,EAC1B,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAChC,CAAC,EAAE,EACH;oBACA,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE;wBAC3B,qBAAqB;wBACrB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;4BAC5B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;yBAChD;wBACD,oBAAoB;wBACpB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;qBAC1B;iBACF;gBACD,CAAC,GAAG,EAAE,CAAA;gBACN,EAAE,GAAG,CAAC,CAAC,OAAO,CAAA;aACf;SACF;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC,GAAG,KAAuB;QAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE;YACrB,IAAI,CAAC,KAAK,EAAE;gBAAE,SAAQ;YACtB,qBAAqB;YACrB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE;gBACtE,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAA;aACtC;YACD,oBAAoB;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SACpB;IACH,CAAC;IAED,MAAM;QACJ,MAAM,GAAG,GACP,IAAI,CAAC,IAAI,KAAK,IAAI;YAChB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAC/D,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACjD,IACE,IAAI,CAAC,KAAK,EAAE;YACZ,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK;gBAClB,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,GAAG,CAAC,CAAC,EACzD;YACA,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;SACb;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QACpC,kDAAkD;QAClD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE;YAAE,OAAO,KAAK,CAAA;QAC1C,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QACxC,yEAAyE;QACzE,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACtB,IAAI,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;gBAC3C,OAAO,KAAK,CAAA;aACb;SACF;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QACpC,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA;QAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE;YAAE,OAAO,KAAK,CAAA;QACxC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;QAC5C,0CAA0C;QAC1C,qBAAqB;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACxD,oBAAoB;QACpB,OAAO,IAAI,CAAC,YAAY,KAAK,EAAE,GAAG,CAAC,CAAA;IACrC,CAAC;IAED,MAAM,CAAC,IAAkB;QACvB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;;YACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,MAAW;QACf,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACpC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;YAC3B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;SACZ;QACD,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM,CAAC,SAAS,CACd,GAAW,EACX,GAAQ,EACR,GAAW,EACX,GAAqB;QAErB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,UAAU,GAAG,CAAC,CAAC,CAAA;QACnB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE;YACrB,qDAAqD;YACrD,IAAI,CAAC,GAAG,GAAG,CAAA;YACX,IAAI,GAAG,GAAG,EAAE,CAAA;YACZ,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE;gBACrB,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;gBACzB,2DAA2D;gBAC3D,0BAA0B;gBAC1B,IAAI,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE;oBAC1B,QAAQ,GAAG,CAAC,QAAQ,CAAA;oBACpB,GAAG,IAAI,CAAC,CAAA;oBACR,SAAQ;iBACT;gBAED,IAAI,OAAO,EAAE;oBACX,IAAI,CAAC,KAAK,UAAU,GAAG,CAAC,EAAE;wBACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE;4BAC1B,QAAQ,GAAG,IAAI,CAAA;yBAChB;qBACF;yBAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,CAAC,IAAI,QAAQ,CAAC,EAAE;wBAC3D,OAAO,GAAG,KAAK,CAAA;qBAChB;oBACD,GAAG,IAAI,CAAC,CAAA;oBACR,SAAQ;iBACT;qBAAM,IAAI,CAAC,KAAK,GAAG,EAAE;oBACpB,OAAO,GAAG,IAAI,CAAA;oBACd,UAAU,GAAG,CAAC,CAAA;oBACd,QAAQ,GAAG,KAAK,CAAA;oBAChB,GAAG,IAAI,CAAC,CAAA;oBACR,SAAQ;iBACT;gBAED,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBAC3D,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBACb,GAAG,GAAG,EAAE,CAAA;oBACR,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;oBAC3B,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;oBACnC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;iBACT;gBACD,GAAG,IAAI,CAAC,CAAA;aACT;YACD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACb,OAAO,CAAC,CAAA;SACT;QAED,wCAAwC;QACxC,uBAAuB;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;QACf,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC7B,MAAM,KAAK,GAAU,EAAE,CAAA;QACvB,IAAI,GAAG,GAAG,EAAE,CAAA;QACZ,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE;YACrB,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;YACzB,2DAA2D;YAC3D,0BAA0B;YAC1B,IAAI,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE;gBAC1B,QAAQ,GAAG,CAAC,QAAQ,CAAA;gBACpB,GAAG,IAAI,CAAC,CAAA;gBACR,SAAQ;aACT;YAED,IAAI,OAAO,EAAE;gBACX,IAAI,CAAC,KAAK,UAAU,GAAG,CAAC,EAAE;oBACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE;wBAC1B,QAAQ,GAAG,IAAI,CAAA;qBAChB;iBACF;qBAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,CAAC,IAAI,QAAQ,CAAC,EAAE;oBAC3D,OAAO,GAAG,KAAK,CAAA;iBAChB;gBACD,GAAG,IAAI,CAAC,CAAA;gBACR,SAAQ;aACT;iBAAM,IAAI,CAAC,KAAK,GAAG,EAAE;gBACpB,OAAO,GAAG,IAAI,CAAA;gBACd,UAAU,GAAG,CAAC,CAAA;gBACd,QAAQ,GAAG,KAAK,CAAA;gBAChB,GAAG,IAAI,CAAC,CAAA;gBACR,SAAQ;aACT;YAED,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;gBAC7C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,GAAG,GAAG,EAAE,CAAA;gBACR,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;gBAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;gBACnC,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,GAAG,GAAG,EAAE,CAAA;gBACR,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAChB,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;gBACzB,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;oBACzC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAA;iBACrB;gBACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,GAAG,GAAG,EAAE,CAAA;gBACR,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAA;gBACxB,OAAO,CAAC,CAAA;aACT;YACD,GAAG,IAAI,CAAC,CAAA;SACT;QAED,qBAAqB;QACrB,kEAAkE;QAClE,iCAAiC;QACjC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAA;QACf,GAAG,CAAC,SAAS,GAAG,SAAS,CAAA;QACzB,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;QACrC,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAe,EAAE,UAA4B,EAAE;QAC7D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QAC7C,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAA;QACvC,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,oEAAoE;IACpE,iBAAiB;IACjB,WAAW;QACT,gCAAgC;QAChC,qBAAqB;QACrB,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA;QACxD,oBAAoB;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;QAC5B,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;QACzD,+DAA+D;QAC/D,mEAAmE;QACnE,sCAAsC;QACtC,MAAM,QAAQ,GACZ,QAAQ;YACR,IAAI,CAAC,SAAS;YACd,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM;gBACnB,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe;gBAC9B,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QAC9C,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO,IAAI,CAAA;SACZ;QAED,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACpE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE;YACjD,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,qEAAqE;IACrE,qEAAqE;IACrE,yEAAyE;IACzE,sEAAsE;IACtE,qEAAqE;IACrE,wEAAwE;IACxE,oEAAoE;IACpE,0DAA0D;IAC1D,EAAE;IACF,uCAAuC;IACvC,4BAA4B;IAC5B,wDAAwD;IACxD,uCAAuC;IACvC,8CAA8C;IAC9C,UAAU;IACV,4BAA4B;IAC5B,YAAY;IACZ,EAAE;IACF,mEAAmE;IACnE,wBAAwB;IACxB,iDAAiD;IACjD,8BAA8B;IAC9B,8DAA8D;IAC9D,uCAAuC;IACvC,8CAA8C;IAC9C,UAAU;IACV,gDAAgD;IAChD,iBAAiB;IACjB,EAAE;IACF,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,eAAe;IACf,EAAE;IACF,wEAAwE;IACxE,4DAA4D;IAC5D,iEAAiE;IACjE,4BAA4B;IAC5B,8DAA8D;IAC9D,6CAA6C;IAC7C,oDAAoD;IACpD,EAAE;IACF,uEAAuE;IACvE,gEAAgE;IAChE,EAAE;IACF,sEAAsE;IACtE,qCAAqC;IACrC,EAAE;IACF,0EAA0E;IAC1E,2EAA2E;IAC3E,EAAE;IACF,kBAAkB;IAClB,+CAA+C;IAC/C,4CAA4C;IAC5C,uEAAuE;IACvE,EAAE;IACF,6EAA6E;IAC7E,0EAA0E;IAC1E,sEAAsE;IACtE,sCAAsC;IACtC,EAAE;IACF,yEAAyE;IACzE,oEAAoE;IACpE,0CAA0C;IAC1C,EAAE;IACF,2BAA2B;IAC3B,sEAAsE;IACtE,qEAAqE;IACrE,uEAAuE;IACvE,cAAc,CACZ,QAAkB;QAElB,MAAM,GAAG,GAAG,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAA;QAC3C,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,IAAI,CAAC,SAAS,EAAE,CAAA;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAA;YAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM;iBACpB,GAAG,CAAC,CAAC,CAAC,EAAE;gBACP,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,GAC5B,OAAO,CAAC,KAAK,QAAQ;oBACnB,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;oBAC5C,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;gBAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAA;gBAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;gBAClC,OAAO,EAAE,CAAA;YACX,CAAC,CAAC;iBACD,IAAI,CAAC,EAAE,CAAC,CAAA;YAEX,IAAI,KAAK,GAAG,EAAE,CAAA;YACd,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;gBAClB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;oBACtC,+DAA+D;oBAC/D,+CAA+C;oBAE/C,gEAAgE;oBAChE,+CAA+C;oBAC/C,MAAM,cAAc,GAClB,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;oBAC1D,IAAI,CAAC,cAAc,EAAE;wBACnB,MAAM,GAAG,GAAG,eAAe,CAAA;wBAC3B,sDAAsD;wBACtD,oBAAoB;wBACpB,MAAM,UAAU;wBACd,uDAAuD;wBACvD,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC/B,8CAA8C;4BAC9C,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;4BACjD,gDAAgD;4BAChD,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;wBACtD,2DAA2D;wBAC3D,4CAA4C;wBAC5C,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;wBAE7D,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;qBACpE;iBACF;aACF;YAED,6DAA6D;YAC7D,IAAI,GAAG,GAAG,EAAE,CAAA;YACZ,IACE,IAAI,CAAC,KAAK,EAAE;gBACZ,IAAI,CAAC,KAAK,CAAC,WAAW;gBACtB,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,GAAG,EAC1B;gBACA,GAAG,GAAG,WAAW,CAAA;aAClB;YACD,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,GAAG,GAAG,CAAA;YAC/B,OAAO;gBACL,KAAK;gBACL,IAAA,sBAAQ,EAAC,GAAG,CAAC;gBACb,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;gBACnC,IAAI,CAAC,MAAM;aACZ,CAAA;SACF;QAED,iEAAiE;QACjE,iEAAiE;QACjE,oCAAoC;QAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,CAAA;QACvD,uBAAuB;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAA;QACrD,IAAI,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QAEnC,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,EAAE;YAChE,mEAAmE;YACnE,2BAA2B;YAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;YACzB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;YACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;YAChB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;YAC1B,OAAO,CAAC,CAAC,EAAE,IAAA,sBAAQ,EAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;SACpD;QAED,mCAAmC;QACnC,IAAI,cAAc,GAChB,CAAC,QAAQ,IAAI,QAAQ,IAAI,GAAG,IAAI,CAAC,UAAU;YACzC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAC/B,IAAI,cAAc,KAAK,IAAI,EAAE;YAC3B,cAAc,GAAG,EAAE,CAAA;SACpB;QACD,IAAI,cAAc,EAAE;YAClB,IAAI,GAAG,MAAM,IAAI,OAAO,cAAc,KAAK,CAAA;SAC5C;QAED,sDAAsD;QACtD,IAAI,KAAK,GAAG,EAAE,CAAA;QACd,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE;YACvC,KAAK,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAA;SACjE;aAAM;YACL,MAAM,KAAK,GACT,IAAI,CAAC,IAAI,KAAK,GAAG;gBACf,CAAC,CAAC,iDAAiD;oBACjD,IAAI;wBACJ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;wBACvD,IAAI;wBACJ,GAAG;gBACL,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG;oBACnB,CAAC,CAAC,GAAG;oBACL,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG;wBACnB,CAAC,CAAC,IAAI;wBACN,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,cAAc;4BACrC,CAAC,CAAC,GAAG;4BACL,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,cAAc;gCACrC,CAAC,CAAC,IAAI;gCACN,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAA;YACrB,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAA;SAC7B;QACD,OAAO;YACL,KAAK;YACL,IAAA,sBAAQ,EAAC,IAAI,CAAC;YACd,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;YACnC,IAAI,CAAC,MAAM;SACZ,CAAA;IACH,CAAC;IAED,cAAc,CAAC,GAAY;QACzB,OAAO,IAAI,CAAC,MAAM;aACf,GAAG,CAAC,CAAC,CAAC,EAAE;YACP,+CAA+C;YAC/C,qBAAqB;YACrB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;gBACzB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;aAChD;YACD,oBAAoB;YACpB,iEAAiE;YACjE,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;YACvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;YAClC,OAAO,EAAE,CAAA;QACX,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACrD,IAAI,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;IAED,MAAM,CAAC,UAAU,CACf,IAAY,EACZ,QAA6B,EAC7B,UAAmB,KAAK;QAExB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,EAAE,GAAG,EAAE,CAAA;QACX,IAAI,KAAK,GAAG,KAAK,CAAA;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACpC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACxB,IAAI,QAAQ,EAAE;gBACZ,QAAQ,GAAG,KAAK,CAAA;gBAChB,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBACzC,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,IAAI,EAAE;gBACd,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;oBACzB,EAAE,IAAI,MAAM,CAAA;iBACb;qBAAM;oBACL,QAAQ,GAAG,IAAI,CAAA;iBAChB;gBACD,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,IAAA,iCAAU,EAAC,IAAI,EAAE,CAAC,CAAC,CAAA;gBAC7D,IAAI,QAAQ,EAAE;oBACZ,EAAE,IAAI,GAAG,CAAA;oBACT,KAAK,GAAG,KAAK,IAAI,SAAS,CAAA;oBAC1B,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAA;oBACjB,QAAQ,GAAG,QAAQ,IAAI,KAAK,CAAA;oBAC5B,SAAQ;iBACT;aACF;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,IAAI,OAAO,IAAI,IAAI,KAAK,GAAG;oBAAE,EAAE,IAAI,WAAW,CAAA;;oBACzC,EAAE,IAAI,IAAI,CAAA;gBACf,QAAQ,GAAG,IAAI,CAAA;gBACf,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,EAAE,IAAI,KAAK,CAAA;gBACX,QAAQ,GAAG,IAAI,CAAA;gBACf,SAAQ;aACT;YACD,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,CAAA;SACtB;QACD,OAAO,CAAC,EAAE,EAAE,IAAA,sBAAQ,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAChD,CAAC;CACF;AA/kBD,kBA+kBC","sourcesContent":["// parse a single path portion\n\nimport { parseClass } from './brace-expressions.js'\nimport { MinimatchOptions, MMRegExp } from './index.js'\nimport { unescape } from './unescape.js'\n\n// classes [] are handled by the parseClass method\n// for positive extglobs, we sub-parse the contents, and combine,\n// with the appropriate regexp close.\n// for negative extglobs, we sub-parse the contents, but then\n// have to include the rest of the pattern, then the parent, etc.,\n// as the thing that cannot be because RegExp negative lookaheads\n// are different from globs.\n//\n// So for example:\n// a@(i|w!(x|y)z|j)b => ^a(i|w((!?(x|y)zb).*)z|j)b$\n// 1 2 3 4 5 6 1 2 3 46 5 6\n//\n// Assembling the extglob requires not just the negated patterns themselves,\n// but also anything following the negative patterns up to the boundary\n// of the current pattern, plus anything following in the parent pattern.\n//\n//\n// So, first, we parse the string into an AST of extglobs, without turning\n// anything into regexps yet.\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y']}, 'z'], ['j']]}, 'b']\n//\n// Then, for all the negative extglobs, we append whatever comes after in\n// each parent as their tail\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y'], 'z', 'b'}, 'z'], ['j']]}, 'b']\n//\n// Lastly, we turn each of these pieces into a regexp, and join\n//\n// v----- .* because there's more following,\n// v v otherwise, .+ because it must be\n// v v *something* there.\n// ['^a', {@ ['i', 'w(?:(!?(?:x|y).*zb$).*)z', 'j' ]}, 'b$']\n// copy what follows into here--^^^^^\n// ['^a', '(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)', 'b$']\n// ['^a(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)b$']\n\nexport type ExtglobType = '!' | '?' | '+' | '*' | '@'\nconst types = new Set(['!', '?', '+', '*', '@'])\nconst isExtglobType = (c: string): c is ExtglobType =>\n types.has(c as ExtglobType)\n\n// Patterns that get prepended to bind to the start of either the\n// entire string, or just a single path portion, to prevent dots\n// and/or traversal patterns, when needed.\n// Exts don't need the ^ or / bit, because the root binds that already.\nconst startNoTraversal = '(?!(?:^|/)\\\\.\\\\.?(?:$|/))'\nconst startNoDot = '(?!\\\\.)'\n\n// characters that indicate a start of pattern needs the \"no dots\" bit,\n// because a dot *might* be matched. ( is not in the list, because in\n// the case of a child extglob, it will handle the prevention itself.\nconst addPatternStart = new Set(['[', '.'])\n// cases where traversal is A-OK, no dot prevention needed\nconst justDots = new Set(['..', '.'])\nconst reSpecials = new Set('().*{}+?[]^$\\\\!')\nconst regExpEscape = (s: string) =>\n s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// any single thing other than /\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n// use + when we need to ensure that *something* matches, because the * is\n// the only thing in the path portion.\nconst starNoEmpty = qmark + '+?'\n\n// remove the \\ chars that we added if we end up doing a nonmagic compare\n// const deslash = (s: string) => s.replace(/\\\\(.)/g, '$1')\n\nexport class AST {\n type: ExtglobType | null\n readonly #root: AST\n\n #hasMagic?: boolean\n #uflag: boolean = false\n #parts: (string | AST)[] = []\n readonly #parent?: AST\n readonly #parentIndex: number\n #negs: AST[]\n #filledNegs: boolean = false\n #options: MinimatchOptions\n #toString?: string\n // set to true if it's an extglob with no children\n // (which really means one child of '')\n #emptyExt: boolean = false\n\n constructor(\n type: ExtglobType | null,\n parent?: AST,\n options: MinimatchOptions = {}\n ) {\n this.type = type\n // extglobs are inherently magical\n if (type) this.#hasMagic = true\n this.#parent = parent\n this.#root = this.#parent ? this.#parent.#root : this\n this.#options = this.#root === this ? options : this.#root.#options\n this.#negs = this.#root === this ? [] : this.#root.#negs\n if (type === '!' && !this.#root.#filledNegs) this.#negs.push(this)\n this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0\n }\n\n get hasMagic(): boolean | undefined {\n /* c8 ignore start */\n if (this.#hasMagic !== undefined) return this.#hasMagic\n /* c8 ignore stop */\n for (const p of this.#parts) {\n if (typeof p === 'string') continue\n if (p.type || p.hasMagic) return (this.#hasMagic = true)\n }\n // note: will be undefined until we generate the regexp src and find out\n return this.#hasMagic\n }\n\n // reconstructs the pattern\n toString(): string {\n if (this.#toString !== undefined) return this.#toString\n if (!this.type) {\n return (this.#toString = this.#parts.map(p => String(p)).join(''))\n } else {\n return (this.#toString =\n this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')')\n }\n }\n\n #fillNegs() {\n /* c8 ignore start */\n if (this !== this.#root) throw new Error('should only call on root')\n if (this.#filledNegs) return this\n /* c8 ignore stop */\n\n // call toString() once to fill this out\n this.toString()\n this.#filledNegs = true\n let n: AST | undefined\n while ((n = this.#negs.pop())) {\n if (n.type !== '!') continue\n // walk up the tree, appending everthing that comes AFTER parentIndex\n let p: AST | undefined = n\n let pp = p.#parent\n while (pp) {\n for (\n let i = p.#parentIndex + 1;\n !pp.type && i < pp.#parts.length;\n i++\n ) {\n for (const part of n.#parts) {\n /* c8 ignore start */\n if (typeof part === 'string') {\n throw new Error('string part in extglob AST??')\n }\n /* c8 ignore stop */\n part.copyIn(pp.#parts[i])\n }\n }\n p = pp\n pp = p.#parent\n }\n }\n return this\n }\n\n push(...parts: (string | AST)[]) {\n for (const p of parts) {\n if (p === '') continue\n /* c8 ignore start */\n if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {\n throw new Error('invalid part: ' + p)\n }\n /* c8 ignore stop */\n this.#parts.push(p)\n }\n }\n\n toJSON() {\n const ret: any[] =\n this.type === null\n ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))\n : [this.type, ...this.#parts.map(p => (p as AST).toJSON())]\n if (this.isStart() && !this.type) ret.unshift([])\n if (\n this.isEnd() &&\n (this === this.#root ||\n (this.#root.#filledNegs && this.#parent?.type === '!'))\n ) {\n ret.push({})\n }\n return ret\n }\n\n isStart(): boolean {\n if (this.#root === this) return true\n // if (this.type) return !!this.#parent?.isStart()\n if (!this.#parent?.isStart()) return false\n if (this.#parentIndex === 0) return true\n // if everything AHEAD of this is a negation, then it's still the \"start\"\n const p = this.#parent\n for (let i = 0; i < this.#parentIndex; i++) {\n const pp = p.#parts[i]\n if (!(pp instanceof AST && pp.type === '!')) {\n return false\n }\n }\n return true\n }\n\n isEnd(): boolean {\n if (this.#root === this) return true\n if (this.#parent?.type === '!') return true\n if (!this.#parent?.isEnd()) return false\n if (!this.type) return this.#parent?.isEnd()\n // if not root, it'll always have a parent\n /* c8 ignore start */\n const pl = this.#parent ? this.#parent.#parts.length : 0\n /* c8 ignore stop */\n return this.#parentIndex === pl - 1\n }\n\n copyIn(part: AST | string) {\n if (typeof part === 'string') this.push(part)\n else this.push(part.clone(this))\n }\n\n clone(parent: AST) {\n const c = new AST(this.type, parent)\n for (const p of this.#parts) {\n c.copyIn(p)\n }\n return c\n }\n\n static #parseAST(\n str: string,\n ast: AST,\n pos: number,\n opt: MinimatchOptions\n ): number {\n let escaping = false\n let inBrace = false\n let braceStart = -1\n let braceNeg = false\n if (ast.type === null) {\n // outside of a extglob, append until we find a start\n let i = pos\n let acc = ''\n while (i < str.length) {\n const c = str.charAt(i++)\n // still accumulate escapes at this point, but we do ignore\n // starts that are escaped\n if (escaping || c === '\\\\') {\n escaping = !escaping\n acc += c\n continue\n }\n\n if (inBrace) {\n if (i === braceStart + 1) {\n if (c === '^' || c === '!') {\n braceNeg = true\n }\n } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n inBrace = false\n }\n acc += c\n continue\n } else if (c === '[') {\n inBrace = true\n braceStart = i\n braceNeg = false\n acc += c\n continue\n }\n\n if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {\n ast.push(acc)\n acc = ''\n const ext = new AST(c, ast)\n i = AST.#parseAST(str, ext, i, opt)\n ast.push(ext)\n continue\n }\n acc += c\n }\n ast.push(acc)\n return i\n }\n\n // some kind of extglob, pos is at the (\n // find the next | or )\n let i = pos + 1\n let part = new AST(null, ast)\n const parts: AST[] = []\n let acc = ''\n while (i < str.length) {\n const c = str.charAt(i++)\n // still accumulate escapes at this point, but we do ignore\n // starts that are escaped\n if (escaping || c === '\\\\') {\n escaping = !escaping\n acc += c\n continue\n }\n\n if (inBrace) {\n if (i === braceStart + 1) {\n if (c === '^' || c === '!') {\n braceNeg = true\n }\n } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n inBrace = false\n }\n acc += c\n continue\n } else if (c === '[') {\n inBrace = true\n braceStart = i\n braceNeg = false\n acc += c\n continue\n }\n\n if (isExtglobType(c) && str.charAt(i) === '(') {\n part.push(acc)\n acc = ''\n const ext = new AST(c, part)\n part.push(ext)\n i = AST.#parseAST(str, ext, i, opt)\n continue\n }\n if (c === '|') {\n part.push(acc)\n acc = ''\n parts.push(part)\n part = new AST(null, ast)\n continue\n }\n if (c === ')') {\n if (acc === '' && ast.#parts.length === 0) {\n ast.#emptyExt = true\n }\n part.push(acc)\n acc = ''\n ast.push(...parts, part)\n return i\n }\n acc += c\n }\n\n // unfinished extglob\n // if we got here, it was a malformed extglob! not an extglob, but\n // maybe something else in there.\n ast.type = null\n ast.#hasMagic = undefined\n ast.#parts = [str.substring(pos - 1)]\n return i\n }\n\n static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n const ast = new AST(null, undefined, options)\n AST.#parseAST(pattern, ast, 0, options)\n return ast\n }\n\n // returns the regular expression if there's magic, or the unescaped\n // string if not.\n toMMPattern(): MMRegExp | string {\n // should only be called on root\n /* c8 ignore start */\n if (this !== this.#root) return this.#root.toMMPattern()\n /* c8 ignore stop */\n const glob = this.toString()\n const [re, body, hasMagic, uflag] = this.toRegExpSource()\n // if we're in nocase mode, and not nocaseMagicOnly, then we do\n // still need a regular expression if we have to case-insensitively\n // match capital/lowercase characters.\n const anyMagic =\n hasMagic ||\n this.#hasMagic ||\n (this.#options.nocase &&\n !this.#options.nocaseMagicOnly &&\n glob.toUpperCase() !== glob.toLowerCase())\n if (!anyMagic) {\n return body\n }\n\n const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '')\n return Object.assign(new RegExp(`^${re}$`, flags), {\n _src: re,\n _glob: glob,\n })\n }\n\n get options() {\n return this.#options\n }\n\n // returns the string match, the regexp source, whether there's magic\n // in the regexp (so a regular expression is required) and whether or\n // not the uflag is needed for the regular expression (for posix classes)\n // TODO: instead of injecting the start/end at this point, just return\n // the BODY of the regexp, along with the start/end portions suitable\n // for binding the start/end in either a joined full-path makeRe context\n // (where we bind to (^|/), or a standalone matchPart context (where\n // we bind to ^, and not /). Otherwise slashes get duped!\n //\n // In part-matching mode, the start is:\n // - if not isStart: nothing\n // - if traversal possible, but not allowed: ^(?!\\.\\.?$)\n // - if dots allowed or not possible: ^\n // - if dots possible and not allowed: ^(?!\\.)\n // end is:\n // - if not isEnd(): nothing\n // - else: $\n //\n // In full-path matching mode, we put the slash at the START of the\n // pattern, so start is:\n // - if first pattern: same as part-matching mode\n // - if not isStart(): nothing\n // - if traversal possible, but not allowed: /(?!\\.\\.?(?:$|/))\n // - if dots allowed or not possible: /\n // - if dots possible and not allowed: /(?!\\.)\n // end is:\n // - if last pattern, same as part-matching mode\n // - else nothing\n //\n // Always put the (?:$|/) on negated tails, though, because that has to be\n // there to bind the end of the negated pattern portion, and it's easier to\n // just stick it in now rather than try to inject it later in the middle of\n // the pattern.\n //\n // We can just always return the same end, and leave it up to the caller\n // to know whether it's going to be used joined or in parts.\n // And, if the start is adjusted slightly, can do the same there:\n // - if not isStart: nothing\n // - if traversal possible, but not allowed: (?:/|^)(?!\\.\\.?$)\n // - if dots allowed or not possible: (?:/|^)\n // - if dots possible and not allowed: (?:/|^)(?!\\.)\n //\n // But it's better to have a simpler binding without a conditional, for\n // performance, so probably better to return both start options.\n //\n // Then the caller just ignores the end if it's not the first pattern,\n // and the start always gets applied.\n //\n // But that's always going to be $ if it's the ending pattern, or nothing,\n // so the caller can just attach $ at the end of the pattern when building.\n //\n // So the todo is:\n // - better detect what kind of start is needed\n // - return both flavors of starting pattern\n // - attach $ at the end of the pattern when creating the actual RegExp\n //\n // Ah, but wait, no, that all only applies to the root when the first pattern\n // is not an extglob. If the first pattern IS an extglob, then we need all\n // that dot prevention biz to live in the extglob portions, because eg\n // +(*|.x*) can match .xy but not .yx.\n //\n // So, return the two flavors if it's #root and the first child is not an\n // AST, otherwise leave it to the child AST to handle it, and there,\n // use the (?:^|/) style of start binding.\n //\n // Even simplified further:\n // - Since the start for a join is eg /(?!\\.) and the start for a part\n // is ^(?!\\.), we can just prepend (?!\\.) to the pattern (either root\n // or start or whatever) and prepend ^ or / at the Regexp construction.\n toRegExpSource(\n allowDot?: boolean\n ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n const dot = allowDot ?? !!this.#options.dot\n if (this.#root === this) this.#fillNegs()\n if (!this.type) {\n const noEmpty = this.isStart() && this.isEnd()\n const src = this.#parts\n .map(p => {\n const [re, _, hasMagic, uflag] =\n typeof p === 'string'\n ? AST.#parseGlob(p, this.#hasMagic, noEmpty)\n : p.toRegExpSource(allowDot)\n this.#hasMagic = this.#hasMagic || hasMagic\n this.#uflag = this.#uflag || uflag\n return re\n })\n .join('')\n\n let start = ''\n if (this.isStart()) {\n if (typeof this.#parts[0] === 'string') {\n // this is the string that will match the start of the pattern,\n // so we need to protect against dots and such.\n\n // '.' and '..' cannot match unless the pattern is that exactly,\n // even if it starts with . or dot:true is set.\n const dotTravAllowed =\n this.#parts.length === 1 && justDots.has(this.#parts[0])\n if (!dotTravAllowed) {\n const aps = addPatternStart\n // check if we have a possibility of matching . or ..,\n // and prevent that.\n const needNoTrav =\n // dots are allowed, and the pattern starts with [ or .\n (dot && aps.has(src.charAt(0))) ||\n // the pattern starts with \\., and then [ or .\n (src.startsWith('\\\\.') && aps.has(src.charAt(2))) ||\n // the pattern starts with \\.\\., and then [ or .\n (src.startsWith('\\\\.\\\\.') && aps.has(src.charAt(4)))\n // no need to prevent dots if it can't match a dot, or if a\n // sub-pattern will be preventing it anyway.\n const needNoDot = !dot && !allowDot && aps.has(src.charAt(0))\n\n start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''\n }\n }\n }\n\n // append the \"end of path portion\" pattern to negation tails\n let end = ''\n if (\n this.isEnd() &&\n this.#root.#filledNegs &&\n this.#parent?.type === '!'\n ) {\n end = '(?:$|\\\\/)'\n }\n const final = start + src + end\n return [\n final,\n unescape(src),\n (this.#hasMagic = !!this.#hasMagic),\n this.#uflag,\n ]\n }\n\n // We need to calculate the body *twice* if it's a repeat pattern\n // at the start, once in nodot mode, then again in dot mode, so a\n // pattern like *(?) can match 'x.y'\n\n const repeated = this.type === '*' || this.type === '+'\n // some kind of extglob\n const start = this.type === '!' ? '(?:(?!(?:' : '(?:'\n let body = this.#partsToRegExp(dot)\n\n if (this.isStart() && this.isEnd() && !body && this.type !== '!') {\n // invalid extglob, has to at least be *something* present, if it's\n // the entire path portion.\n const s = this.toString()\n this.#parts = [s]\n this.type = null\n this.#hasMagic = undefined\n return [s, unescape(this.toString()), false, false]\n }\n\n // XXX abstract out this map method\n let bodyDotAllowed =\n !repeated || allowDot || dot || !startNoDot\n ? ''\n : this.#partsToRegExp(true)\n if (bodyDotAllowed === body) {\n bodyDotAllowed = ''\n }\n if (bodyDotAllowed) {\n body = `(?:${body})(?:${bodyDotAllowed})*?`\n }\n\n // an empty !() is exactly equivalent to a starNoEmpty\n let final = ''\n if (this.type === '!' && this.#emptyExt) {\n final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty\n } else {\n const close =\n this.type === '!'\n ? // !() must match something,but !(x) can match ''\n '))' +\n (this.isStart() && !dot && !allowDot ? startNoDot : '') +\n star +\n ')'\n : this.type === '@'\n ? ')'\n : this.type === '?'\n ? ')?'\n : this.type === '+' && bodyDotAllowed\n ? ')'\n : this.type === '*' && bodyDotAllowed\n ? `)?`\n : `)${this.type}`\n final = start + body + close\n }\n return [\n final,\n unescape(body),\n (this.#hasMagic = !!this.#hasMagic),\n this.#uflag,\n ]\n }\n\n #partsToRegExp(dot: boolean) {\n return this.#parts\n .map(p => {\n // extglob ASTs should only contain parent ASTs\n /* c8 ignore start */\n if (typeof p === 'string') {\n throw new Error('string type in extglob ast??')\n }\n /* c8 ignore stop */\n // can ignore hasMagic, because extglobs are already always magic\n const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot)\n this.#uflag = this.#uflag || uflag\n return re\n })\n .filter(p => !(this.isStart() && this.isEnd()) || !!p)\n .join('|')\n }\n\n static #parseGlob(\n glob: string,\n hasMagic: boolean | undefined,\n noEmpty: boolean = false\n ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n let escaping = false\n let re = ''\n let uflag = false\n for (let i = 0; i < glob.length; i++) {\n const c = glob.charAt(i)\n if (escaping) {\n escaping = false\n re += (reSpecials.has(c) ? '\\\\' : '') + c\n continue\n }\n if (c === '\\\\') {\n if (i === glob.length - 1) {\n re += '\\\\\\\\'\n } else {\n escaping = true\n }\n continue\n }\n if (c === '[') {\n const [src, needUflag, consumed, magic] = parseClass(glob, i)\n if (consumed) {\n re += src\n uflag = uflag || needUflag\n i += consumed - 1\n hasMagic = hasMagic || magic\n continue\n }\n }\n if (c === '*') {\n if (noEmpty && glob === '*') re += starNoEmpty\n else re += star\n hasMagic = true\n continue\n }\n if (c === '?') {\n re += qmark\n hasMagic = true\n continue\n }\n re += regExpEscape(c)\n }\n return [re, unescape(glob), !!hasMagic, uflag]\n }\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts deleted file mode 100644 index b1572deb..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type ParseClassResult = [ - src: string, - uFlag: boolean, - consumed: number, - hasMagic: boolean -]; -export declare const parseClass: (glob: string, position: number) => ParseClassResult; -//# sourceMappingURL=brace-expressions.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map deleted file mode 100644 index d3949648..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,SACf,MAAM,YACF,MAAM,qBA8HjB,CAAA"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js deleted file mode 100644 index 0e13eefc..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js +++ /dev/null @@ -1,152 +0,0 @@ -"use strict"; -// translate the various posix character classes into unicode properties -// this works across all unicode locales -Object.defineProperty(exports, "__esModule", { value: true }); -exports.parseClass = void 0; -// { : [, /u flag required, negated] -const posixClasses = { - '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true], - '[:alpha:]': ['\\p{L}\\p{Nl}', true], - '[:ascii:]': ['\\x' + '00-\\x' + '7f', false], - '[:blank:]': ['\\p{Zs}\\t', true], - '[:cntrl:]': ['\\p{Cc}', true], - '[:digit:]': ['\\p{Nd}', true], - '[:graph:]': ['\\p{Z}\\p{C}', true, true], - '[:lower:]': ['\\p{Ll}', true], - '[:print:]': ['\\p{C}', true], - '[:punct:]': ['\\p{P}', true], - '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true], - '[:upper:]': ['\\p{Lu}', true], - '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true], - '[:xdigit:]': ['A-Fa-f0-9', false], -}; -// only need to escape a few things inside of brace expressions -// escapes: [ \ ] - -const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&'); -// escape all regexp magic characters -const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -// everything has already been escaped, we just have to join -const rangesToString = (ranges) => ranges.join(''); -// takes a glob string at a posix brace expression, and returns -// an equivalent regular expression source, and boolean indicating -// whether the /u flag needs to be applied, and the number of chars -// consumed to parse the character class. -// This also removes out of order ranges, and returns ($.) if the -// entire class just no good. -const parseClass = (glob, position) => { - const pos = position; - /* c8 ignore start */ - if (glob.charAt(pos) !== '[') { - throw new Error('not in a brace expression'); - } - /* c8 ignore stop */ - const ranges = []; - const negs = []; - let i = pos + 1; - let sawStart = false; - let uflag = false; - let escaping = false; - let negate = false; - let endPos = pos; - let rangeStart = ''; - WHILE: while (i < glob.length) { - const c = glob.charAt(i); - if ((c === '!' || c === '^') && i === pos + 1) { - negate = true; - i++; - continue; - } - if (c === ']' && sawStart && !escaping) { - endPos = i + 1; - break; - } - sawStart = true; - if (c === '\\') { - if (!escaping) { - escaping = true; - i++; - continue; - } - // escaped \ char, fall through and treat like normal char - } - if (c === '[' && !escaping) { - // either a posix class, a collation equivalent, or just a [ - for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) { - if (glob.startsWith(cls, i)) { - // invalid, [a-[] is fine, but not [a-[:alpha]] - if (rangeStart) { - return ['$.', false, glob.length - pos, true]; - } - i += cls.length; - if (neg) - negs.push(unip); - else - ranges.push(unip); - uflag = uflag || u; - continue WHILE; - } - } - } - // now it's just a normal character, effectively - escaping = false; - if (rangeStart) { - // throw this range away if it's not valid, but others - // can still match. - if (c > rangeStart) { - ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c)); - } - else if (c === rangeStart) { - ranges.push(braceEscape(c)); - } - rangeStart = ''; - i++; - continue; - } - // now might be the start of a range. - // can be either c-d or c-] or c] or c] at this point - if (glob.startsWith('-]', i + 1)) { - ranges.push(braceEscape(c + '-')); - i += 2; - continue; - } - if (glob.startsWith('-', i + 1)) { - rangeStart = c; - i += 2; - continue; - } - // not the start of a range, just a single character - ranges.push(braceEscape(c)); - i++; - } - if (endPos < i) { - // didn't see the end of the class, not a valid class, - // but might still be valid as a literal match. - return ['', false, 0, false]; - } - // if we got no ranges and no negates, then we have a range that - // cannot possibly match anything, and that poisons the whole glob - if (!ranges.length && !negs.length) { - return ['$.', false, glob.length - pos, true]; - } - // if we got one positive range, and it's a single character, then that's - // not actually a magic pattern, it's just that one literal character. - // we should not treat that as "magic", we should just return the literal - // character. [_] is a perfectly valid way to escape glob magic chars. - if (negs.length === 0 && - ranges.length === 1 && - /^\\?.$/.test(ranges[0]) && - !negate) { - const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]; - return [regexpEscape(r), false, endPos - pos, false]; - } - const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'; - const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'; - const comb = ranges.length && negs.length - ? '(' + sranges + '|' + snegs + ')' - : ranges.length - ? sranges - : snegs; - return [comb, uflag, endPos - pos, true]; -}; -exports.parseClass = parseClass; -//# sourceMappingURL=brace-expressions.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map b/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map deleted file mode 100644 index 86b04756..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"brace-expressions.js","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"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","sourcesContent":["// translate the various posix character classes into unicode properties\n// this works across all unicode locales\n\n// { : [, /u flag required, negated]\nconst posixClasses: { [k: string]: [e: string, u: boolean, n?: boolean] } = {\n '[:alnum:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}', true],\n '[:alpha:]': ['\\\\p{L}\\\\p{Nl}', true],\n '[:ascii:]': ['\\\\x' + '00-\\\\x' + '7f', false],\n '[:blank:]': ['\\\\p{Zs}\\\\t', true],\n '[:cntrl:]': ['\\\\p{Cc}', true],\n '[:digit:]': ['\\\\p{Nd}', true],\n '[:graph:]': ['\\\\p{Z}\\\\p{C}', true, true],\n '[:lower:]': ['\\\\p{Ll}', true],\n '[:print:]': ['\\\\p{C}', true],\n '[:punct:]': ['\\\\p{P}', true],\n '[:space:]': ['\\\\p{Z}\\\\t\\\\r\\\\n\\\\v\\\\f', true],\n '[:upper:]': ['\\\\p{Lu}', true],\n '[:word:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}\\\\p{Pc}', true],\n '[:xdigit:]': ['A-Fa-f0-9', false],\n}\n\n// only need to escape a few things inside of brace expressions\n// escapes: [ \\ ] -\nconst braceEscape = (s: string) => s.replace(/[[\\]\\\\-]/g, '\\\\$&')\n// escape all regexp magic characters\nconst regexpEscape = (s: string) =>\n s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// everything has already been escaped, we just have to join\nconst rangesToString = (ranges: string[]): string => ranges.join('')\n\nexport type ParseClassResult = [\n src: string,\n uFlag: boolean,\n consumed: number,\n hasMagic: boolean\n]\n\n// takes a glob string at a posix brace expression, and returns\n// an equivalent regular expression source, and boolean indicating\n// whether the /u flag needs to be applied, and the number of chars\n// consumed to parse the character class.\n// This also removes out of order ranges, and returns ($.) if the\n// entire class just no good.\nexport const parseClass = (\n glob: string,\n position: number\n): ParseClassResult => {\n const pos = position\n /* c8 ignore start */\n if (glob.charAt(pos) !== '[') {\n throw new Error('not in a brace expression')\n }\n /* c8 ignore stop */\n const ranges: string[] = []\n const negs: string[] = []\n\n let i = pos + 1\n let sawStart = false\n let uflag = false\n let escaping = false\n let negate = false\n let endPos = pos\n let rangeStart = ''\n WHILE: while (i < glob.length) {\n const c = glob.charAt(i)\n if ((c === '!' || c === '^') && i === pos + 1) {\n negate = true\n i++\n continue\n }\n\n if (c === ']' && sawStart && !escaping) {\n endPos = i + 1\n break\n }\n\n sawStart = true\n if (c === '\\\\') {\n if (!escaping) {\n escaping = true\n i++\n continue\n }\n // escaped \\ char, fall through and treat like normal char\n }\n if (c === '[' && !escaping) {\n // either a posix class, a collation equivalent, or just a [\n for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {\n if (glob.startsWith(cls, i)) {\n // invalid, [a-[] is fine, but not [a-[:alpha]]\n if (rangeStart) {\n return ['$.', false, glob.length - pos, true]\n }\n i += cls.length\n if (neg) negs.push(unip)\n else ranges.push(unip)\n uflag = uflag || u\n continue WHILE\n }\n }\n }\n\n // now it's just a normal character, effectively\n escaping = false\n if (rangeStart) {\n // throw this range away if it's not valid, but others\n // can still match.\n if (c > rangeStart) {\n ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c))\n } else if (c === rangeStart) {\n ranges.push(braceEscape(c))\n }\n rangeStart = ''\n i++\n continue\n }\n\n // now might be the start of a range.\n // can be either c-d or c-] or c] or c] at this point\n if (glob.startsWith('-]', i + 1)) {\n ranges.push(braceEscape(c + '-'))\n i += 2\n continue\n }\n if (glob.startsWith('-', i + 1)) {\n rangeStart = c\n i += 2\n continue\n }\n\n // not the start of a range, just a single character\n ranges.push(braceEscape(c))\n i++\n }\n\n if (endPos < i) {\n // didn't see the end of the class, not a valid class,\n // but might still be valid as a literal match.\n return ['', false, 0, false]\n }\n\n // if we got no ranges and no negates, then we have a range that\n // cannot possibly match anything, and that poisons the whole glob\n if (!ranges.length && !negs.length) {\n return ['$.', false, glob.length - pos, true]\n }\n\n // if we got one positive range, and it's a single character, then that's\n // not actually a magic pattern, it's just that one literal character.\n // we should not treat that as \"magic\", we should just return the literal\n // character. [_] is a perfectly valid way to escape glob magic chars.\n if (\n negs.length === 0 &&\n ranges.length === 1 &&\n /^\\\\?.$/.test(ranges[0]) &&\n !negate\n ) {\n const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]\n return [regexpEscape(r), false, endPos - pos, false]\n }\n\n const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'\n const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'\n const comb =\n ranges.length && negs.length\n ? '(' + sranges + '|' + snegs + ')'\n : ranges.length\n ? sranges\n : snegs\n\n return [comb, uflag, endPos - pos, true]\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.d.ts b/backend/node_modules/minimatch/dist/commonjs/escape.d.ts deleted file mode 100644 index dc3e3163..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/escape.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { MinimatchOptions } from './index.js'; -/** - * Escape all magic characters in a glob pattern. - * - * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape} - * option is used, then characters are escaped by wrapping in `[]`, because - * a magic character wrapped in a character class can only be satisfied by - * that exact character. In this mode, `\` is _not_ escaped, because it is - * not interpreted as a magic character, but instead as a path separator. - */ -export declare const escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string; -//# sourceMappingURL=escape.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map deleted file mode 100644 index 0779dae7..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/escape.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,MACd,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAQlD,CAAA"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.js b/backend/node_modules/minimatch/dist/commonjs/escape.js deleted file mode 100644 index 02a4f8a8..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/escape.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.escape = void 0; -/** - * Escape all magic characters in a glob pattern. - * - * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape} - * option is used, then characters are escaped by wrapping in `[]`, because - * a magic character wrapped in a character class can only be satisfied by - * that exact character. In this mode, `\` is _not_ escaped, because it is - * not interpreted as a magic character, but instead as a path separator. - */ -const escape = (s, { windowsPathsNoEscape = false, } = {}) => { - // don't need to escape +@! because we escape the parens - // that make those magic, and escaping ! as [!] isn't valid, - // because [!]] is a valid glob class meaning not ']'. - return windowsPathsNoEscape - ? s.replace(/[?*()[\]]/g, '[$&]') - : s.replace(/[?*()[\]\\]/g, '\\$&'); -}; -exports.escape = escape; -//# sourceMappingURL=escape.js.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/escape.js.map b/backend/node_modules/minimatch/dist/commonjs/escape.js.map deleted file mode 100644 index 264b2ea5..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/escape.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":";;;AACA;;;;;;;;GAQG;AACI,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA;AAZY,QAAA,MAAM,UAYlB","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character. In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n */\nexport const escape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n }: Pick = {}\n) => {\n // don't need to escape +@! because we escape the parens\n // that make those magic, and escaping ! as [!] isn't valid,\n // because [!]] is a valid glob class meaning not ']'.\n return windowsPathsNoEscape\n ? s.replace(/[?*()[\\]]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/index.d.ts b/backend/node_modules/minimatch/dist/commonjs/index.d.ts deleted file mode 100644 index 41d16a98..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/index.d.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { AST } from './ast.js'; -type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd'; -export interface MinimatchOptions { - nobrace?: boolean; - nocomment?: boolean; - nonegate?: boolean; - debug?: boolean; - noglobstar?: boolean; - noext?: boolean; - nonull?: boolean; - windowsPathsNoEscape?: boolean; - allowWindowsEscape?: boolean; - partial?: boolean; - dot?: boolean; - nocase?: boolean; - nocaseMagicOnly?: boolean; - magicalBraces?: boolean; - matchBase?: boolean; - flipNegate?: boolean; - preserveMultipleSlashes?: boolean; - optimizationLevel?: number; - platform?: Platform; - windowsNoMagicRoot?: boolean; -} -export declare const minimatch: { - (p: string, pattern: string, options?: MinimatchOptions): boolean; - sep: Sep; - GLOBSTAR: typeof GLOBSTAR; - filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean; - defaults: (def: MinimatchOptions) => typeof minimatch; - braceExpand: (pattern: string, options?: MinimatchOptions) => string[]; - makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp; - match: (list: string[], pattern: string, options?: MinimatchOptions) => string[]; - AST: typeof AST; - Minimatch: typeof Minimatch; - escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string; - unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string; -}; -type Sep = '\\' | '/'; -export declare const sep: Sep; -export declare const GLOBSTAR: unique symbol; -export declare const filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean; -export declare const defaults: (def: MinimatchOptions) => typeof minimatch; -export declare const braceExpand: (pattern: string, options?: MinimatchOptions) => string[]; -export declare const makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp; -export declare const match: (list: string[], pattern: string, options?: MinimatchOptions) => string[]; -export type MMRegExp = RegExp & { - _src?: string; - _glob?: string; -}; -export type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR; -export type ParseReturn = ParseReturnFiltered | false; -export declare class Minimatch { - options: MinimatchOptions; - set: ParseReturnFiltered[][]; - pattern: string; - windowsPathsNoEscape: boolean; - nonegate: boolean; - negate: boolean; - comment: boolean; - empty: boolean; - preserveMultipleSlashes: boolean; - partial: boolean; - globSet: string[]; - globParts: string[][]; - nocase: boolean; - isWindows: boolean; - platform: Platform; - windowsNoMagicRoot: boolean; - regexp: false | null | MMRegExp; - constructor(pattern: string, options?: MinimatchOptions); - hasMagic(): boolean; - debug(..._: any[]): void; - make(): void; - preprocess(globParts: string[][]): string[][]; - adjascentGlobstarOptimize(globParts: string[][]): string[][]; - levelOneOptimize(globParts: string[][]): string[][]; - levelTwoFileOptimize(parts: string | string[]): string[]; - firstPhasePreProcess(globParts: string[][]): string[][]; - secondPhasePreProcess(globParts: string[][]): string[][]; - partsMatch(a: string[], b: string[], emptyGSMatch?: boolean): false | string[]; - parseNegate(): void; - matchOne(file: string[], pattern: ParseReturn[], partial?: boolean): boolean; - braceExpand(): string[]; - parse(pattern: string): ParseReturn; - makeRe(): false | MMRegExp; - slashSplit(p: string): string[]; - match(f: string, partial?: boolean): boolean; - static defaults(def: MinimatchOptions): typeof Minimatch; -} -export { AST } from './ast.js'; -export { escape } from './escape.js'; -export { unescape } from './unescape.js'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/index.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/index.d.ts.map deleted file mode 100644 index 195491d8..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/backend/node_modules/minimatch/dist/commonjs/index.js b/backend/node_modules/minimatch/dist/commonjs/index.js deleted file mode 100644 index 64a0f1f8..00000000 --- a/backend/node_modules/minimatch/dist/commonjs/index.js +++ /dev/null @@ -1,1017 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.unescape = exports.escape = exports.AST = exports.Minimatch = exports.match = exports.makeRe = exports.braceExpand = exports.defaults = exports.filter = exports.GLOBSTAR = exports.sep = exports.minimatch = void 0; -const brace_expansion_1 = __importDefault(require("brace-expansion")); -const assert_valid_pattern_js_1 = require("./assert-valid-pattern.js"); -const ast_js_1 = require("./ast.js"); -const escape_js_1 = require("./escape.js"); -const unescape_js_1 = require("./unescape.js"); -const minimatch = (p, pattern, options = {}) => { - (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false; - } - return new Minimatch(pattern, options).match(p); -}; -exports.minimatch = minimatch; -// Optimized checking for the most common glob patterns. -const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; -const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext); -const starDotExtTestDot = (ext) => (f) => f.endsWith(ext); -const starDotExtTestNocase = (ext) => { - ext = ext.toLowerCase(); - return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext); -}; -const starDotExtTestNocaseDot = (ext) => { - ext = ext.toLowerCase(); - return (f) => f.toLowerCase().endsWith(ext); -}; -const starDotStarRE = /^\*+\.\*+$/; -const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.'); -const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.'); -const dotStarRE = /^\.\*+$/; -const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.'); -const starRE = /^\*+$/; -const starTest = (f) => f.length !== 0 && !f.startsWith('.'); -const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..'; -const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; -const qmarksTestNocase = ([$0, ext = '']) => { - const noext = qmarksTestNoExt([$0]); - if (!ext) - return noext; - ext = ext.toLowerCase(); - return (f) => noext(f) && f.toLowerCase().endsWith(ext); -}; -const qmarksTestNocaseDot = ([$0, ext = '']) => { - const noext = qmarksTestNoExtDot([$0]); - if (!ext) - return noext; - ext = ext.toLowerCase(); - return (f) => noext(f) && f.toLowerCase().endsWith(ext); -}; -const qmarksTestDot = ([$0, ext = '']) => { - const noext = qmarksTestNoExtDot([$0]); - return !ext ? noext : (f) => noext(f) && f.endsWith(ext); -}; -const qmarksTest = ([$0, ext = '']) => { - const noext = qmarksTestNoExt([$0]); - return !ext ? noext : (f) => noext(f) && f.endsWith(ext); -}; -const qmarksTestNoExt = ([$0]) => { - const len = $0.length; - return (f) => f.length === len && !f.startsWith('.'); -}; -const qmarksTestNoExtDot = ([$0]) => { - const len = $0.length; - return (f) => f.length === len && f !== '.' && f !== '..'; -}; -/* c8 ignore start */ -const defaultPlatform = (typeof process === 'object' && process - ? (typeof process.env === 'object' && - process.env && - process.env.__MINIMATCH_TESTING_PLATFORM__) || - process.platform - : 'posix'); -const path = { - win32: { sep: '\\' }, - posix: { sep: '/' }, -}; -/* c8 ignore stop */ -exports.sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep; -exports.minimatch.sep = exports.sep; -exports.GLOBSTAR = Symbol('globstar **'); -exports.minimatch.GLOBSTAR = exports.GLOBSTAR; -// any single thing other than / -// don't need to escape / when using new RegExp() -const qmark = '[^/]'; -// * => any number of characters -const star = qmark + '*?'; -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?'; -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?'; -const filter = (pattern, options = {}) => (p) => (0, exports.minimatch)(p, pattern, options); -exports.filter = filter; -exports.minimatch.filter = exports.filter; -const ext = (a, b = {}) => Object.assign({}, a, b); -const defaults = (def) => { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return exports.minimatch; - } - const orig = exports.minimatch; - const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options)); - return Object.assign(m, { - Minimatch: class Minimatch extends orig.Minimatch { - constructor(pattern, options = {}) { - super(pattern, ext(def, options)); - } - static defaults(options) { - return orig.defaults(ext(def, options)).Minimatch; - } - }, - AST: class AST extends orig.AST { - /* c8 ignore start */ - constructor(type, parent, options = {}) { - super(type, parent, ext(def, options)); - } - /* c8 ignore stop */ - static fromGlob(pattern, options = {}) { - return orig.AST.fromGlob(pattern, ext(def, options)); - } - }, - unescape: (s, options = {}) => orig.unescape(s, ext(def, options)), - escape: (s, options = {}) => orig.escape(s, ext(def, options)), - filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), - defaults: (options) => orig.defaults(ext(def, options)), - makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), - braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), - match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), - sep: orig.sep, - GLOBSTAR: exports.GLOBSTAR, - }); -}; -exports.defaults = defaults; -exports.minimatch.defaults = exports.defaults; -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -const braceExpand = (pattern, options = {}) => { - (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); - // Thanks to Yeting Li for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { - // shortcut. no need to expand. - return [pattern]; - } - return (0, brace_expansion_1.default)(pattern); -}; -exports.braceExpand = braceExpand; -exports.minimatch.braceExpand = exports.braceExpand; -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); -exports.makeRe = makeRe; -exports.minimatch.makeRe = exports.makeRe; -const match = (list, pattern, options = {}) => { - const mm = new Minimatch(pattern, options); - list = list.filter(f => mm.match(f)); - if (mm.options.nonull && !list.length) { - list.push(pattern); - } - return list; -}; -exports.match = match; -exports.minimatch.match = exports.match; -// replace stuff like \* with * -const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; -const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -class Minimatch { - options; - set; - pattern; - windowsPathsNoEscape; - nonegate; - negate; - comment; - empty; - preserveMultipleSlashes; - partial; - globSet; - globParts; - nocase; - isWindows; - platform; - windowsNoMagicRoot; - regexp; - constructor(pattern, options = {}) { - (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); - options = options || {}; - this.options = options; - this.pattern = pattern; - this.platform = options.platform || defaultPlatform; - this.isWindows = this.platform === 'win32'; - this.windowsPathsNoEscape = - !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; - if (this.windowsPathsNoEscape) { - this.pattern = this.pattern.replace(/\\/g, '/'); - } - this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; - this.regexp = null; - this.negate = false; - this.nonegate = !!options.nonegate; - this.comment = false; - this.empty = false; - this.partial = !!options.partial; - this.nocase = !!this.options.nocase; - this.windowsNoMagicRoot = - options.windowsNoMagicRoot !== undefined - ? options.windowsNoMagicRoot - : !!(this.isWindows && this.nocase); - this.globSet = []; - this.globParts = []; - this.set = []; - // make the set of regexps etc. - this.make(); - } - hasMagic() { - if (this.options.magicalBraces && this.set.length > 1) { - return true; - } - for (const pattern of this.set) { - for (const part of pattern) { - if (typeof part !== 'string') - return true; - } - } - return false; - } - debug(..._) { } - make() { - const pattern = this.pattern; - const options = this.options; - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true; - return; - } - if (!pattern) { - this.empty = true; - return; - } - // step 1: figure out negation, etc. - this.parseNegate(); - // step 2: expand braces - this.globSet = [...new Set(this.braceExpand())]; - if (options.debug) { - this.debug = (...args) => console.error(...args); - } - this.debug(this.pattern, this.globSet); - // step 3: now we have a set, so turn each one into a series of - // path-portion matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - // - // First, we preprocess to make the glob pattern sets a bit simpler - // and deduped. There are some perf-killing patterns that can cause - // problems with a glob walk, but we can simplify them down a bit. - const rawGlobParts = this.globSet.map(s => this.slashSplit(s)); - this.globParts = this.preprocess(rawGlobParts); - this.debug(this.pattern, this.globParts); - // glob --> regexps - let set = this.globParts.map((s, _, __) => { - if (this.isWindows && this.windowsNoMagicRoot) { - // check if it's a drive or unc path. - const isUNC = s[0] === '' && - s[1] === '' && - (s[2] === '?' || !globMagic.test(s[2])) && - !globMagic.test(s[3]); - const isDrive = /^[a-z]:/i.test(s[0]); - if (isUNC) { - return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]; - } - else if (isDrive) { - return [s[0], ...s.slice(1).map(ss => this.parse(ss))]; - } - } - return s.map(ss => this.parse(ss)); - }); - this.debug(this.pattern, set); - // filter out everything that didn't compile properly. - this.set = set.filter(s => s.indexOf(false) === -1); - // do not treat the ? in UNC paths as magic - if (this.isWindows) { - for (let i = 0; i < this.set.length; i++) { - const p = this.set[i]; - if (p[0] === '' && - p[1] === '' && - this.globParts[i][2] === '?' && - typeof p[3] === 'string' && - /^[a-z]:$/i.test(p[3])) { - p[2] = '?'; - } - } - } - this.debug(this.pattern, this.set); - } - // various transforms to equivalent pattern sets that are - // faster to process in a filesystem walk. The goal is to - // eliminate what we can, and push all ** patterns as far - // to the right as possible, even if it increases the number - // of patterns that we have to process. - preprocess(globParts) { - // if we're not in globstar mode, then turn all ** into * - if (this.options.noglobstar) { - for (let i = 0; i < globParts.length; i++) { - for (let j = 0; j < globParts[i].length; j++) { - if (globParts[i][j] === '**') { - globParts[i][j] = '*'; - } - } - } - } - const { optimizationLevel = 1 } = this.options; - if (optimizationLevel >= 2) { - // aggressive optimization for the purpose of fs walking - globParts = this.firstPhasePreProcess(globParts); - globParts = this.secondPhasePreProcess(globParts); - } - else if (optimizationLevel >= 1) { - // just basic optimizations to remove some .. parts - globParts = this.levelOneOptimize(globParts); - } - else { - // just collapse multiple ** portions into one - globParts = this.adjascentGlobstarOptimize(globParts); - } - return globParts; - } - // just get rid of adjascent ** portions - adjascentGlobstarOptimize(globParts) { - return globParts.map(parts => { - let gs = -1; - while (-1 !== (gs = parts.indexOf('**', gs + 1))) { - let i = gs; - while (parts[i + 1] === '**') { - i++; - } - if (i !== gs) { - parts.splice(gs, i - gs); - } - } - return parts; - }); - } - // get rid of adjascent ** and resolve .. portions - levelOneOptimize(globParts) { - return globParts.map(parts => { - parts = parts.reduce((set, part) => { - const prev = set[set.length - 1]; - if (part === '**' && prev === '**') { - return set; - } - if (part === '..') { - if (prev && prev !== '..' && prev !== '.' && prev !== '**') { - set.pop(); - return set; - } - } - set.push(part); - return set; - }, []); - return parts.length === 0 ? [''] : parts; - }); - } - levelTwoFileOptimize(parts) { - if (!Array.isArray(parts)) { - parts = this.slashSplit(parts); - } - let didSomething = false; - do { - didSomething = false; - //

// -> 
/
-            if (!this.preserveMultipleSlashes) {
-                for (let i = 1; i < parts.length - 1; i++) {
-                    const p = parts[i];
-                    // don't squeeze out UNC patterns
-                    if (i === 1 && p === '' && parts[0] === '')
-                        continue;
-                    if (p === '.' || p === '') {
-                        didSomething = true;
-                        parts.splice(i, 1);
-                        i--;
-                    }
-                }
-                if (parts[0] === '.' &&
-                    parts.length === 2 &&
-                    (parts[1] === '.' || parts[1] === '')) {
-                    didSomething = true;
-                    parts.pop();
-                }
-            }
-            // 
/

/../ ->

/
-            let dd = 0;
-            while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
-                const p = parts[dd - 1];
-                if (p && p !== '.' && p !== '..' && p !== '**') {
-                    didSomething = true;
-                    parts.splice(dd - 1, 2);
-                    dd -= 2;
-                }
-            }
-        } while (didSomething);
-        return parts.length === 0 ? [''] : parts;
-    }
-    // First phase: single-pattern processing
-    // 
 is 1 or more portions
-    //  is 1 or more portions
-    // 

is any portion other than ., .., '', or ** - // is . or '' - // - // **/.. is *brutal* for filesystem walking performance, because - // it effectively resets the recursive walk each time it occurs, - // and ** cannot be reduced out by a .. pattern part like a regexp - // or most strings (other than .., ., and '') can be. - // - //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/} - //

// -> 
/
-    // 
/

/../ ->

/
-    // **/**/ -> **/
-    //
-    // **/*/ -> */**/ <== not valid because ** doesn't follow
-    // this WOULD be allowed if ** did follow symlinks, or * didn't
-    firstPhasePreProcess(globParts) {
-        let didSomething = false;
-        do {
-            didSomething = false;
-            // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/} - for (let parts of globParts) { - let gs = -1; - while (-1 !== (gs = parts.indexOf('**', gs + 1))) { - let gss = gs; - while (parts[gss + 1] === '**') { - //

/**/**/ -> 
/**/
-                        gss++;
-                    }
-                    // eg, if gs is 2 and gss is 4, that means we have 3 **
-                    // parts, and can remove 2 of them.
-                    if (gss > gs) {
-                        parts.splice(gs + 1, gss - gs);
-                    }
-                    let next = parts[gs + 1];
-                    const p = parts[gs + 2];
-                    const p2 = parts[gs + 3];
-                    if (next !== '..')
-                        continue;
-                    if (!p ||
-                        p === '.' ||
-                        p === '..' ||
-                        !p2 ||
-                        p2 === '.' ||
-                        p2 === '..') {
-                        continue;
-                    }
-                    didSomething = true;
-                    // edit parts in place, and push the new one
-                    parts.splice(gs, 1);
-                    const other = parts.slice(0);
-                    other[gs] = '**';
-                    globParts.push(other);
-                    gs--;
-                }
-                // 
// -> 
/
-                if (!this.preserveMultipleSlashes) {
-                    for (let i = 1; i < parts.length - 1; i++) {
-                        const p = parts[i];
-                        // don't squeeze out UNC patterns
-                        if (i === 1 && p === '' && parts[0] === '')
-                            continue;
-                        if (p === '.' || p === '') {
-                            didSomething = true;
-                            parts.splice(i, 1);
-                            i--;
-                        }
-                    }
-                    if (parts[0] === '.' &&
-                        parts.length === 2 &&
-                        (parts[1] === '.' || parts[1] === '')) {
-                        didSomething = true;
-                        parts.pop();
-                    }
-                }
-                // 
/

/../ ->

/
-                let dd = 0;
-                while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
-                    const p = parts[dd - 1];
-                    if (p && p !== '.' && p !== '..' && p !== '**') {
-                        didSomething = true;
-                        const needDot = dd === 1 && parts[dd + 1] === '**';
-                        const splin = needDot ? ['.'] : [];
-                        parts.splice(dd - 1, 2, ...splin);
-                        if (parts.length === 0)
-                            parts.push('');
-                        dd -= 2;
-                    }
-                }
-            }
-        } while (didSomething);
-        return globParts;
-    }
-    // second phase: multi-pattern dedupes
-    // {
/*/,
/

/} ->

/*/
-    // {
/,
/} -> 
/
-    // {
/**/,
/} -> 
/**/
-    //
-    // {
/**/,
/**/

/} ->

/**/
-    // ^-- not valid because ** doens't follow symlinks
-    secondPhasePreProcess(globParts) {
-        for (let i = 0; i < globParts.length - 1; i++) {
-            for (let j = i + 1; j < globParts.length; j++) {
-                const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
-                if (matched) {
-                    globParts[i] = [];
-                    globParts[j] = matched;
-                    break;
-                }
-            }
-        }
-        return globParts.filter(gs => gs.length);
-    }
-    partsMatch(a, b, emptyGSMatch = false) {
-        let ai = 0;
-        let bi = 0;
-        let result = [];
-        let which = '';
-        while (ai < a.length && bi < b.length) {
-            if (a[ai] === b[bi]) {
-                result.push(which === 'b' ? b[bi] : a[ai]);
-                ai++;
-                bi++;
-            }
-            else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
-                result.push(a[ai]);
-                ai++;
-            }
-            else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
-                result.push(b[bi]);
-                bi++;
-            }
-            else if (a[ai] === '*' &&
-                b[bi] &&
-                (this.options.dot || !b[bi].startsWith('.')) &&
-                b[bi] !== '**') {
-                if (which === 'b')
-                    return false;
-                which = 'a';
-                result.push(a[ai]);
-                ai++;
-                bi++;
-            }
-            else if (b[bi] === '*' &&
-                a[ai] &&
-                (this.options.dot || !a[ai].startsWith('.')) &&
-                a[ai] !== '**') {
-                if (which === 'a')
-                    return false;
-                which = 'b';
-                result.push(b[bi]);
-                ai++;
-                bi++;
-            }
-            else {
-                return false;
-            }
-        }
-        // if we fall out of the loop, it means they two are identical
-        // as long as their lengths match
-        return a.length === b.length && result;
-    }
-    parseNegate() {
-        if (this.nonegate)
-            return;
-        const pattern = this.pattern;
-        let negate = false;
-        let negateOffset = 0;
-        for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
-            negate = !negate;
-            negateOffset++;
-        }
-        if (negateOffset)
-            this.pattern = pattern.slice(negateOffset);
-        this.negate = negate;
-    }
-    // set partial to true to test if, for example,
-    // "/a/b" matches the start of "/*/b/*/d"
-    // Partial means, if you run out of file before you run
-    // out of pattern, then that's fine, as long as all
-    // the parts match.
-    matchOne(file, pattern, partial = false) {
-        const options = this.options;
-        // UNC paths like //?/X:/... can match X:/... and vice versa
-        // Drive letters in absolute drive or unc paths are always compared
-        // case-insensitively.
-        if (this.isWindows) {
-            const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
-            const fileUNC = !fileDrive &&
-                file[0] === '' &&
-                file[1] === '' &&
-                file[2] === '?' &&
-                /^[a-z]:$/i.test(file[3]);
-            const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
-            const patternUNC = !patternDrive &&
-                pattern[0] === '' &&
-                pattern[1] === '' &&
-                pattern[2] === '?' &&
-                typeof pattern[3] === 'string' &&
-                /^[a-z]:$/i.test(pattern[3]);
-            const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
-            const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
-            if (typeof fdi === 'number' && typeof pdi === 'number') {
-                const [fd, pd] = [file[fdi], pattern[pdi]];
-                if (fd.toLowerCase() === pd.toLowerCase()) {
-                    pattern[pdi] = fd;
-                    if (pdi > fdi) {
-                        pattern = pattern.slice(pdi);
-                    }
-                    else if (fdi > pdi) {
-                        file = file.slice(fdi);
-                    }
-                }
-            }
-        }
-        // resolve and reduce . and .. portions in the file as well.
-        // dont' need to do the second phase, because it's only one string[]
-        const { optimizationLevel = 1 } = this.options;
-        if (optimizationLevel >= 2) {
-            file = this.levelTwoFileOptimize(file);
-        }
-        this.debug('matchOne', this, { file, pattern });
-        this.debug('matchOne', file.length, pattern.length);
-        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
-            this.debug('matchOne loop');
-            var p = pattern[pi];
-            var f = file[fi];
-            this.debug(pattern, p, f);
-            // should be impossible.
-            // some invalid regexp stuff in the set.
-            /* c8 ignore start */
-            if (p === false) {
-                return false;
-            }
-            /* c8 ignore stop */
-            if (p === exports.GLOBSTAR) {
-                this.debug('GLOBSTAR', [pattern, p, f]);
-                // "**"
-                // a/**/b/**/c would match the following:
-                // a/b/x/y/z/c
-                // a/x/y/z/b/c
-                // a/b/x/b/x/c
-                // a/b/c
-                // To do this, take the rest of the pattern after
-                // the **, and see if it would match the file remainder.
-                // If so, return success.
-                // If not, the ** "swallows" a segment, and try again.
-                // This is recursively awful.
-                //
-                // a/**/b/**/c matching a/b/x/y/z/c
-                // - a matches a
-                // - doublestar
-                //   - matchOne(b/x/y/z/c, b/**/c)
-                //     - b matches b
-                //     - doublestar
-                //       - matchOne(x/y/z/c, c) -> no
-                //       - matchOne(y/z/c, c) -> no
-                //       - matchOne(z/c, c) -> no
-                //       - matchOne(c, c) yes, hit
-                var fr = fi;
-                var pr = pi + 1;
-                if (pr === pl) {
-                    this.debug('** at the end');
-                    // a ** at the end will just swallow the rest.
-                    // We have found a match.
-                    // however, it will not swallow /.x, unless
-                    // options.dot is set.
-                    // . and .. are *never* matched by **, for explosively
-                    // exponential reasons.
-                    for (; fi < fl; fi++) {
-                        if (file[fi] === '.' ||
-                            file[fi] === '..' ||
-                            (!options.dot && file[fi].charAt(0) === '.'))
-                            return false;
-                    }
-                    return true;
-                }
-                // ok, let's see if we can swallow whatever we can.
-                while (fr < fl) {
-                    var swallowee = file[fr];
-                    this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
-                    // XXX remove this slice.  Just pass the start index.
-                    if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
-                        this.debug('globstar found match!', fr, fl, swallowee);
-                        // found a match.
-                        return true;
-                    }
-                    else {
-                        // can't swallow "." or ".." ever.
-                        // can only swallow ".foo" when explicitly asked.
-                        if (swallowee === '.' ||
-                            swallowee === '..' ||
-                            (!options.dot && swallowee.charAt(0) === '.')) {
-                            this.debug('dot detected!', file, fr, pattern, pr);
-                            break;
-                        }
-                        // ** swallows a segment, and continue.
-                        this.debug('globstar swallow a segment, and continue');
-                        fr++;
-                    }
-                }
-                // no match was found.
-                // However, in partial mode, we can't say this is necessarily over.
-                /* c8 ignore start */
-                if (partial) {
-                    // ran out of file
-                    this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
-                    if (fr === fl) {
-                        return true;
-                    }
-                }
-                /* c8 ignore stop */
-                return false;
-            }
-            // something other than **
-            // non-magic patterns just have to match exactly
-            // patterns with magic have been turned into regexps.
-            let hit;
-            if (typeof p === 'string') {
-                hit = f === p;
-                this.debug('string match', p, f, hit);
-            }
-            else {
-                hit = p.test(f);
-                this.debug('pattern match', p, f, hit);
-            }
-            if (!hit)
-                return false;
-        }
-        // Note: ending in / means that we'll get a final ""
-        // at the end of the pattern.  This can only match a
-        // corresponding "" at the end of the file.
-        // If the file ends in /, then it can only match a
-        // a pattern that ends in /, unless the pattern just
-        // doesn't have any more for it. But, a/b/ should *not*
-        // match "a/b/*", even though "" matches against the
-        // [^/]*? pattern, except in partial mode, where it might
-        // simply not be reached yet.
-        // However, a/b/ should still satisfy a/*
-        // now either we fell off the end of the pattern, or we're done.
-        if (fi === fl && pi === pl) {
-            // ran out of pattern and filename at the same time.
-            // an exact hit!
-            return true;
-        }
-        else if (fi === fl) {
-            // ran out of file, but still had pattern left.
-            // this is ok if we're doing the match as part of
-            // a glob fs traversal.
-            return partial;
-        }
-        else if (pi === pl) {
-            // ran out of pattern, still have file left.
-            // this is only acceptable if we're on the very last
-            // empty segment of a file with a trailing slash.
-            // a/* should match a/b/
-            return fi === fl - 1 && file[fi] === '';
-            /* c8 ignore start */
-        }
-        else {
-            // should be unreachable.
-            throw new Error('wtf?');
-        }
-        /* c8 ignore stop */
-    }
-    braceExpand() {
-        return (0, exports.braceExpand)(this.pattern, this.options);
-    }
-    parse(pattern) {
-        (0, assert_valid_pattern_js_1.assertValidPattern)(pattern);
-        const options = this.options;
-        // shortcuts
-        if (pattern === '**')
-            return exports.GLOBSTAR;
-        if (pattern === '')
-            return '';
-        // far and away, the most common glob pattern parts are
-        // *, *.*, and *.  Add a fast check method for those.
-        let m;
-        let fastTest = null;
-        if ((m = pattern.match(starRE))) {
-            fastTest = options.dot ? starTestDot : starTest;
-        }
-        else if ((m = pattern.match(starDotExtRE))) {
-            fastTest = (options.nocase
-                ? options.dot
-                    ? starDotExtTestNocaseDot
-                    : starDotExtTestNocase
-                : options.dot
-                    ? starDotExtTestDot
-                    : starDotExtTest)(m[1]);
-        }
-        else if ((m = pattern.match(qmarksRE))) {
-            fastTest = (options.nocase
-                ? options.dot
-                    ? qmarksTestNocaseDot
-                    : qmarksTestNocase
-                : options.dot
-                    ? qmarksTestDot
-                    : qmarksTest)(m);
-        }
-        else if ((m = pattern.match(starDotStarRE))) {
-            fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
-        }
-        else if ((m = pattern.match(dotStarRE))) {
-            fastTest = dotStarTest;
-        }
-        const re = ast_js_1.AST.fromGlob(pattern, this.options).toMMPattern();
-        if (fastTest && typeof re === 'object') {
-            // Avoids overriding in frozen environments
-            Reflect.defineProperty(re, 'test', { value: fastTest });
-        }
-        return re;
-    }
-    makeRe() {
-        if (this.regexp || this.regexp === false)
-            return this.regexp;
-        // at this point, this.set is a 2d array of partial
-        // pattern strings, or "**".
-        //
-        // It's better to use .match().  This function shouldn't
-        // be used, really, but it's pretty convenient sometimes,
-        // when you just want to work with a regex.
-        const set = this.set;
-        if (!set.length) {
-            this.regexp = false;
-            return this.regexp;
-        }
-        const options = this.options;
-        const twoStar = options.noglobstar
-            ? star
-            : options.dot
-                ? twoStarDot
-                : twoStarNoDot;
-        const flags = new Set(options.nocase ? ['i'] : []);
-        // regexpify non-globstar patterns
-        // if ** is only item, then we just do one twoStar
-        // if ** is first, and there are more, prepend (\/|twoStar\/)? to next
-        // if ** is last, append (\/twoStar|) to previous
-        // if ** is in the middle, append (\/|\/twoStar\/) to previous
-        // then filter out GLOBSTAR symbols
-        let re = set
-            .map(pattern => {
-            const pp = pattern.map(p => {
-                if (p instanceof RegExp) {
-                    for (const f of p.flags.split(''))
-                        flags.add(f);
-                }
-                return typeof p === 'string'
-                    ? regExpEscape(p)
-                    : p === exports.GLOBSTAR
-                        ? exports.GLOBSTAR
-                        : p._src;
-            });
-            pp.forEach((p, i) => {
-                const next = pp[i + 1];
-                const prev = pp[i - 1];
-                if (p !== exports.GLOBSTAR || prev === exports.GLOBSTAR) {
-                    return;
-                }
-                if (prev === undefined) {
-                    if (next !== undefined && next !== exports.GLOBSTAR) {
-                        pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next;
-                    }
-                    else {
-                        pp[i] = twoStar;
-                    }
-                }
-                else if (next === undefined) {
-                    pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
-                }
-                else if (next !== exports.GLOBSTAR) {
-                    pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
-                    pp[i + 1] = exports.GLOBSTAR;
-                }
-            });
-            return pp.filter(p => p !== exports.GLOBSTAR).join('/');
-        })
-            .join('|');
-        // need to wrap in parens if we had more than one thing with |,
-        // otherwise only the first will be anchored to ^ and the last to $
-        const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
-        // must match entire pattern
-        // ending in a * or ** will make it less strict.
-        re = '^' + open + re + close + '$';
-        // can match anything, as long as it's not this.
-        if (this.negate)
-            re = '^(?!' + re + ').+$';
-        try {
-            this.regexp = new RegExp(re, [...flags].join(''));
-            /* c8 ignore start */
-        }
-        catch (ex) {
-            // should be impossible
-            this.regexp = false;
-        }
-        /* c8 ignore stop */
-        return this.regexp;
-    }
-    slashSplit(p) {
-        // if p starts with // on windows, we preserve that
-        // so that UNC paths aren't broken.  Otherwise, any number of
-        // / characters are coalesced into one, unless
-        // preserveMultipleSlashes is set to true.
-        if (this.preserveMultipleSlashes) {
-            return p.split('/');
-        }
-        else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
-            // add an extra '' for the one we lose
-            return ['', ...p.split(/\/+/)];
-        }
-        else {
-            return p.split(/\/+/);
-        }
-    }
-    match(f, partial = this.partial) {
-        this.debug('match', f, this.pattern);
-        // short-circuit in the case of busted things.
-        // comments, etc.
-        if (this.comment) {
-            return false;
-        }
-        if (this.empty) {
-            return f === '';
-        }
-        if (f === '/' && partial) {
-            return true;
-        }
-        const options = this.options;
-        // windows: need to use /, not \
-        if (this.isWindows) {
-            f = f.split('\\').join('/');
-        }
-        // treat the test path as a set of pathparts.
-        const ff = this.slashSplit(f);
-        this.debug(this.pattern, 'split', ff);
-        // just ONE of the pattern sets in this.set needs to match
-        // in order for it to be valid.  If negating, then just one
-        // match means that we have failed.
-        // Either way, return on the first hit.
-        const set = this.set;
-        this.debug(this.pattern, 'set', set);
-        // Find the basename of the path by looking for the last non-empty segment
-        let filename = ff[ff.length - 1];
-        if (!filename) {
-            for (let i = ff.length - 2; !filename && i >= 0; i--) {
-                filename = ff[i];
-            }
-        }
-        for (let i = 0; i < set.length; i++) {
-            const pattern = set[i];
-            let file = ff;
-            if (options.matchBase && pattern.length === 1) {
-                file = [filename];
-            }
-            const hit = this.matchOne(file, pattern, partial);
-            if (hit) {
-                if (options.flipNegate) {
-                    return true;
-                }
-                return !this.negate;
-            }
-        }
-        // didn't get any hits.  this is success if it's a negative
-        // pattern, failure otherwise.
-        if (options.flipNegate) {
-            return false;
-        }
-        return this.negate;
-    }
-    static defaults(def) {
-        return exports.minimatch.defaults(def).Minimatch;
-    }
-}
-exports.Minimatch = Minimatch;
-/* c8 ignore start */
-var ast_js_2 = require("./ast.js");
-Object.defineProperty(exports, "AST", { enumerable: true, get: function () { return ast_js_2.AST; } });
-var escape_js_2 = require("./escape.js");
-Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return escape_js_2.escape; } });
-var unescape_js_2 = require("./unescape.js");
-Object.defineProperty(exports, "unescape", { enumerable: true, get: function () { return unescape_js_2.unescape; } });
-/* c8 ignore stop */
-exports.minimatch.AST = ast_js_1.AST;
-exports.minimatch.Minimatch = Minimatch;
-exports.minimatch.escape = escape_js_1.escape;
-exports.minimatch.unescape = unescape_js_1.unescape;
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/index.js.map b/backend/node_modules/minimatch/dist/commonjs/index.js.map
deleted file mode 100644
index d4f6a870..00000000
--- a/backend/node_modules/minimatch/dist/commonjs/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import expand from 'brace-expansion'\nimport { assertValidPattern } from './assert-valid-pattern.js'\nimport { AST, ExtglobType } from './ast.js'\nimport { escape } from './escape.js'\nimport { unescape } from './unescape.js'\n\ntype Platform =\n  | 'aix'\n  | 'android'\n  | 'darwin'\n  | 'freebsd'\n  | 'haiku'\n  | 'linux'\n  | 'openbsd'\n  | 'sunos'\n  | 'win32'\n  | 'cygwin'\n  | 'netbsd'\n\nexport interface MinimatchOptions {\n  nobrace?: boolean\n  nocomment?: boolean\n  nonegate?: boolean\n  debug?: boolean\n  noglobstar?: boolean\n  noext?: boolean\n  nonull?: boolean\n  windowsPathsNoEscape?: boolean\n  allowWindowsEscape?: boolean\n  partial?: boolean\n  dot?: boolean\n  nocase?: boolean\n  nocaseMagicOnly?: boolean\n  magicalBraces?: boolean\n  matchBase?: boolean\n  flipNegate?: boolean\n  preserveMultipleSlashes?: boolean\n  optimizationLevel?: number\n  platform?: Platform\n  windowsNoMagicRoot?: boolean\n}\n\nexport const minimatch = (\n  p: string,\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // shortcut: comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    return false\n  }\n\n  return new Minimatch(pattern, options).match(p)\n}\n\n// Optimized checking for the most common glob patterns.\nconst starDotExtRE = /^\\*+([^+@!?\\*\\[\\(]*)$/\nconst starDotExtTest = (ext: string) => (f: string) =>\n  !f.startsWith('.') && f.endsWith(ext)\nconst starDotExtTestDot = (ext: string) => (f: string) => f.endsWith(ext)\nconst starDotExtTestNocase = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => !f.startsWith('.') && f.toLowerCase().endsWith(ext)\n}\nconst starDotExtTestNocaseDot = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => f.toLowerCase().endsWith(ext)\n}\nconst starDotStarRE = /^\\*+\\.\\*+$/\nconst starDotStarTest = (f: string) => !f.startsWith('.') && f.includes('.')\nconst starDotStarTestDot = (f: string) =>\n  f !== '.' && f !== '..' && f.includes('.')\nconst dotStarRE = /^\\.\\*+$/\nconst dotStarTest = (f: string) => f !== '.' && f !== '..' && f.startsWith('.')\nconst starRE = /^\\*+$/\nconst starTest = (f: string) => f.length !== 0 && !f.startsWith('.')\nconst starTestDot = (f: string) => f.length !== 0 && f !== '.' && f !== '..'\nconst qmarksRE = /^\\?+([^+@!?\\*\\[\\(]*)?$/\nconst qmarksTestNocase = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestNocaseDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTest = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTestNoExt = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && !f.startsWith('.')\n}\nconst qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && f !== '.' && f !== '..'\n}\n\n/* c8 ignore start */\nconst defaultPlatform: Platform = (\n  typeof process === 'object' && process\n    ? (typeof process.env === 'object' &&\n        process.env &&\n        process.env.__MINIMATCH_TESTING_PLATFORM__) ||\n      process.platform\n    : 'posix'\n) as Platform\ntype Sep = '\\\\' | '/'\nconst path: { [k: string]: { sep: Sep } } = {\n  win32: { sep: '\\\\' },\n  posix: { sep: '/' },\n}\n/* c8 ignore stop */\n\nexport const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep\nminimatch.sep = sep\n\nexport const GLOBSTAR = Symbol('globstar **')\nminimatch.GLOBSTAR = GLOBSTAR\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n\n// ** when dots are allowed.  Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nconst twoStarDot = '(?:(?!(?:\\\\/|^)(?:\\\\.{1,2})($|\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nconst twoStarNoDot = '(?:(?!(?:\\\\/|^)\\\\.).)*?'\n\nexport const filter =\n  (pattern: string, options: MinimatchOptions = {}) =>\n  (p: string) =>\n    minimatch(p, pattern, options)\nminimatch.filter = filter\n\nconst ext = (a: MinimatchOptions, b: MinimatchOptions = {}) =>\n  Object.assign({}, a, b)\n\nexport const defaults = (def: MinimatchOptions): typeof minimatch => {\n  if (!def || typeof def !== 'object' || !Object.keys(def).length) {\n    return minimatch\n  }\n\n  const orig = minimatch\n\n  const m = (p: string, pattern: string, options: MinimatchOptions = {}) =>\n    orig(p, pattern, ext(def, options))\n\n  return Object.assign(m, {\n    Minimatch: class Minimatch extends orig.Minimatch {\n      constructor(pattern: string, options: MinimatchOptions = {}) {\n        super(pattern, ext(def, options))\n      }\n      static defaults(options: MinimatchOptions) {\n        return orig.defaults(ext(def, options)).Minimatch\n      }\n    },\n\n    AST: class AST extends orig.AST {\n      /* c8 ignore start */\n      constructor(\n        type: ExtglobType | null,\n        parent?: AST,\n        options: MinimatchOptions = {}\n      ) {\n        super(type, parent, ext(def, options))\n      }\n      /* c8 ignore stop */\n\n      static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n        return orig.AST.fromGlob(pattern, ext(def, options))\n      }\n    },\n\n    unescape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.unescape(s, ext(def, options)),\n\n    escape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.escape(s, ext(def, options)),\n\n    filter: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.filter(pattern, ext(def, options)),\n\n    defaults: (options: MinimatchOptions) => orig.defaults(ext(def, options)),\n\n    makeRe: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.makeRe(pattern, ext(def, options)),\n\n    braceExpand: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.braceExpand(pattern, ext(def, options)),\n\n    match: (list: string[], pattern: string, options: MinimatchOptions = {}) =>\n      orig.match(list, pattern, ext(def, options)),\n\n    sep: orig.sep,\n    GLOBSTAR: GLOBSTAR as typeof GLOBSTAR,\n  })\n}\nminimatch.defaults = defaults\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nexport const braceExpand = (\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // Thanks to Yeting Li  for\n  // improving this regexp to avoid a ReDOS vulnerability.\n  if (options.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(pattern)) {\n    // shortcut. no need to expand.\n    return [pattern]\n  }\n\n  return expand(pattern)\n}\nminimatch.braceExpand = braceExpand\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion.  Otherwise, any series\n// of * is equivalent to a single *.  Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\n\nexport const makeRe = (pattern: string, options: MinimatchOptions = {}) =>\n  new Minimatch(pattern, options).makeRe()\nminimatch.makeRe = makeRe\n\nexport const match = (\n  list: string[],\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  const mm = new Minimatch(pattern, options)\n  list = list.filter(f => mm.match(f))\n  if (mm.options.nonull && !list.length) {\n    list.push(pattern)\n  }\n  return list\n}\nminimatch.match = match\n\n// replace stuff like \\* with *\nconst globMagic = /[?*]|[+@!]\\(.*?\\)|\\[|\\]/\nconst regExpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\nexport type MMRegExp = RegExp & {\n  _src?: string\n  _glob?: string\n}\n\nexport type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR\nexport type ParseReturn = ParseReturnFiltered | false\n\nexport class Minimatch {\n  options: MinimatchOptions\n  set: ParseReturnFiltered[][]\n  pattern: string\n\n  windowsPathsNoEscape: boolean\n  nonegate: boolean\n  negate: boolean\n  comment: boolean\n  empty: boolean\n  preserveMultipleSlashes: boolean\n  partial: boolean\n  globSet: string[]\n  globParts: string[][]\n  nocase: boolean\n\n  isWindows: boolean\n  platform: Platform\n  windowsNoMagicRoot: boolean\n\n  regexp: false | null | MMRegExp\n  constructor(pattern: string, options: MinimatchOptions = {}) {\n    assertValidPattern(pattern)\n\n    options = options || {}\n    this.options = options\n    this.pattern = pattern\n    this.platform = options.platform || defaultPlatform\n    this.isWindows = this.platform === 'win32'\n    this.windowsPathsNoEscape =\n      !!options.windowsPathsNoEscape || options.allowWindowsEscape === false\n    if (this.windowsPathsNoEscape) {\n      this.pattern = this.pattern.replace(/\\\\/g, '/')\n    }\n    this.preserveMultipleSlashes = !!options.preserveMultipleSlashes\n    this.regexp = null\n    this.negate = false\n    this.nonegate = !!options.nonegate\n    this.comment = false\n    this.empty = false\n    this.partial = !!options.partial\n    this.nocase = !!this.options.nocase\n    this.windowsNoMagicRoot =\n      options.windowsNoMagicRoot !== undefined\n        ? options.windowsNoMagicRoot\n        : !!(this.isWindows && this.nocase)\n\n    this.globSet = []\n    this.globParts = []\n    this.set = []\n\n    // make the set of regexps etc.\n    this.make()\n  }\n\n  hasMagic(): boolean {\n    if (this.options.magicalBraces && this.set.length > 1) {\n      return true\n    }\n    for (const pattern of this.set) {\n      for (const part of pattern) {\n        if (typeof part !== 'string') return true\n      }\n    }\n    return false\n  }\n\n  debug(..._: any[]) {}\n\n  make() {\n    const pattern = this.pattern\n    const options = this.options\n\n    // empty patterns and comments match nothing.\n    if (!options.nocomment && pattern.charAt(0) === '#') {\n      this.comment = true\n      return\n    }\n\n    if (!pattern) {\n      this.empty = true\n      return\n    }\n\n    // step 1: figure out negation, etc.\n    this.parseNegate()\n\n    // step 2: expand braces\n    this.globSet = [...new Set(this.braceExpand())]\n\n    if (options.debug) {\n      this.debug = (...args: any[]) => console.error(...args)\n    }\n\n    this.debug(this.pattern, this.globSet)\n\n    // step 3: now we have a set, so turn each one into a series of\n    // path-portion matching patterns.\n    // These will be regexps, except in the case of \"**\", which is\n    // set to the GLOBSTAR object for globstar behavior,\n    // and will not contain any / characters\n    //\n    // First, we preprocess to make the glob pattern sets a bit simpler\n    // and deduped.  There are some perf-killing patterns that can cause\n    // problems with a glob walk, but we can simplify them down a bit.\n    const rawGlobParts = this.globSet.map(s => this.slashSplit(s))\n    this.globParts = this.preprocess(rawGlobParts)\n    this.debug(this.pattern, this.globParts)\n\n    // glob --> regexps\n    let set = this.globParts.map((s, _, __) => {\n      if (this.isWindows && this.windowsNoMagicRoot) {\n        // check if it's a drive or unc path.\n        const isUNC =\n          s[0] === '' &&\n          s[1] === '' &&\n          (s[2] === '?' || !globMagic.test(s[2])) &&\n          !globMagic.test(s[3])\n        const isDrive = /^[a-z]:/i.test(s[0])\n        if (isUNC) {\n          return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]\n        } else if (isDrive) {\n          return [s[0], ...s.slice(1).map(ss => this.parse(ss))]\n        }\n      }\n      return s.map(ss => this.parse(ss))\n    })\n\n    this.debug(this.pattern, set)\n\n    // filter out everything that didn't compile properly.\n    this.set = set.filter(\n      s => s.indexOf(false) === -1\n    ) as ParseReturnFiltered[][]\n\n    // do not treat the ? in UNC paths as magic\n    if (this.isWindows) {\n      for (let i = 0; i < this.set.length; i++) {\n        const p = this.set[i]\n        if (\n          p[0] === '' &&\n          p[1] === '' &&\n          this.globParts[i][2] === '?' &&\n          typeof p[3] === 'string' &&\n          /^[a-z]:$/i.test(p[3])\n        ) {\n          p[2] = '?'\n        }\n      }\n    }\n\n    this.debug(this.pattern, this.set)\n  }\n\n  // various transforms to equivalent pattern sets that are\n  // faster to process in a filesystem walk.  The goal is to\n  // eliminate what we can, and push all ** patterns as far\n  // to the right as possible, even if it increases the number\n  // of patterns that we have to process.\n  preprocess(globParts: string[][]) {\n    // if we're not in globstar mode, then turn all ** into *\n    if (this.options.noglobstar) {\n      for (let i = 0; i < globParts.length; i++) {\n        for (let j = 0; j < globParts[i].length; j++) {\n          if (globParts[i][j] === '**') {\n            globParts[i][j] = '*'\n          }\n        }\n      }\n    }\n\n    const { optimizationLevel = 1 } = this.options\n\n    if (optimizationLevel >= 2) {\n      // aggressive optimization for the purpose of fs walking\n      globParts = this.firstPhasePreProcess(globParts)\n      globParts = this.secondPhasePreProcess(globParts)\n    } else if (optimizationLevel >= 1) {\n      // just basic optimizations to remove some .. parts\n      globParts = this.levelOneOptimize(globParts)\n    } else {\n      // just collapse multiple ** portions into one\n      globParts = this.adjascentGlobstarOptimize(globParts)\n    }\n\n    return globParts\n  }\n\n  // just get rid of adjascent ** portions\n  adjascentGlobstarOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      let gs: number = -1\n      while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n        let i = gs\n        while (parts[i + 1] === '**') {\n          i++\n        }\n        if (i !== gs) {\n          parts.splice(gs, i - gs)\n        }\n      }\n      return parts\n    })\n  }\n\n  // get rid of adjascent ** and resolve .. portions\n  levelOneOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      parts = parts.reduce((set: string[], part) => {\n        const prev = set[set.length - 1]\n        if (part === '**' && prev === '**') {\n          return set\n        }\n        if (part === '..') {\n          if (prev && prev !== '..' && prev !== '.' && prev !== '**') {\n            set.pop()\n            return set\n          }\n        }\n        set.push(part)\n        return set\n      }, [])\n      return parts.length === 0 ? [''] : parts\n    })\n  }\n\n  levelTwoFileOptimize(parts: string | string[]) {\n    if (!Array.isArray(parts)) {\n      parts = this.slashSplit(parts)\n    }\n    let didSomething: boolean = false\n    do {\n      didSomething = false\n      // 
// -> 
/\n      if (!this.preserveMultipleSlashes) {\n        for (let i = 1; i < parts.length - 1; i++) {\n          const p = parts[i]\n          // don't squeeze out UNC patterns\n          if (i === 1 && p === '' && parts[0] === '') continue\n          if (p === '.' || p === '') {\n            didSomething = true\n            parts.splice(i, 1)\n            i--\n          }\n        }\n        if (\n          parts[0] === '.' &&\n          parts.length === 2 &&\n          (parts[1] === '.' || parts[1] === '')\n        ) {\n          didSomething = true\n          parts.pop()\n        }\n      }\n\n      // 
/

/../ ->

/\n      let dd: number = 0\n      while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n        const p = parts[dd - 1]\n        if (p && p !== '.' && p !== '..' && p !== '**') {\n          didSomething = true\n          parts.splice(dd - 1, 2)\n          dd -= 2\n        }\n      }\n    } while (didSomething)\n    return parts.length === 0 ? [''] : parts\n  }\n\n  // First phase: single-pattern processing\n  // 
 is 1 or more portions\n  //  is 1 or more portions\n  // 

is any portion other than ., .., '', or **\n // is . or ''\n //\n // **/.. is *brutal* for filesystem walking performance, because\n // it effectively resets the recursive walk each time it occurs,\n // and ** cannot be reduced out by a .. pattern part like a regexp\n // or most strings (other than .., ., and '') can be.\n //\n //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n //

// -> 
/\n  // 
/

/../ ->

/\n  // **/**/ -> **/\n  //\n  // **/*/ -> */**/ <== not valid because ** doesn't follow\n  // this WOULD be allowed if ** did follow symlinks, or * didn't\n  firstPhasePreProcess(globParts: string[][]) {\n    let didSomething = false\n    do {\n      didSomething = false\n      // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n for (let parts of globParts) {\n let gs: number = -1\n while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n let gss: number = gs\n while (parts[gss + 1] === '**') {\n //

/**/**/ -> 
/**/\n            gss++\n          }\n          // eg, if gs is 2 and gss is 4, that means we have 3 **\n          // parts, and can remove 2 of them.\n          if (gss > gs) {\n            parts.splice(gs + 1, gss - gs)\n          }\n\n          let next = parts[gs + 1]\n          const p = parts[gs + 2]\n          const p2 = parts[gs + 3]\n          if (next !== '..') continue\n          if (\n            !p ||\n            p === '.' ||\n            p === '..' ||\n            !p2 ||\n            p2 === '.' ||\n            p2 === '..'\n          ) {\n            continue\n          }\n          didSomething = true\n          // edit parts in place, and push the new one\n          parts.splice(gs, 1)\n          const other = parts.slice(0)\n          other[gs] = '**'\n          globParts.push(other)\n          gs--\n        }\n\n        // 
// -> 
/\n        if (!this.preserveMultipleSlashes) {\n          for (let i = 1; i < parts.length - 1; i++) {\n            const p = parts[i]\n            // don't squeeze out UNC patterns\n            if (i === 1 && p === '' && parts[0] === '') continue\n            if (p === '.' || p === '') {\n              didSomething = true\n              parts.splice(i, 1)\n              i--\n            }\n          }\n          if (\n            parts[0] === '.' &&\n            parts.length === 2 &&\n            (parts[1] === '.' || parts[1] === '')\n          ) {\n            didSomething = true\n            parts.pop()\n          }\n        }\n\n        // 
/

/../ ->

/\n        let dd: number = 0\n        while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n          const p = parts[dd - 1]\n          if (p && p !== '.' && p !== '..' && p !== '**') {\n            didSomething = true\n            const needDot = dd === 1 && parts[dd + 1] === '**'\n            const splin = needDot ? ['.'] : []\n            parts.splice(dd - 1, 2, ...splin)\n            if (parts.length === 0) parts.push('')\n            dd -= 2\n          }\n        }\n      }\n    } while (didSomething)\n\n    return globParts\n  }\n\n  // second phase: multi-pattern dedupes\n  // {
/*/,
/

/} ->

/*/\n  // {
/,
/} -> 
/\n  // {
/**/,
/} -> 
/**/\n  //\n  // {
/**/,
/**/

/} ->

/**/\n  // ^-- not valid because ** doens't follow symlinks\n  secondPhasePreProcess(globParts: string[][]): string[][] {\n    for (let i = 0; i < globParts.length - 1; i++) {\n      for (let j = i + 1; j < globParts.length; j++) {\n        const matched = this.partsMatch(\n          globParts[i],\n          globParts[j],\n          !this.preserveMultipleSlashes\n        )\n        if (matched) {\n          globParts[i] = []\n          globParts[j] = matched\n          break\n        }\n      }\n    }\n    return globParts.filter(gs => gs.length)\n  }\n\n  partsMatch(\n    a: string[],\n    b: string[],\n    emptyGSMatch: boolean = false\n  ): false | string[] {\n    let ai = 0\n    let bi = 0\n    let result: string[] = []\n    let which: string = ''\n    while (ai < a.length && bi < b.length) {\n      if (a[ai] === b[bi]) {\n        result.push(which === 'b' ? b[bi] : a[ai])\n        ai++\n        bi++\n      } else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {\n        result.push(a[ai])\n        ai++\n      } else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {\n        result.push(b[bi])\n        bi++\n      } else if (\n        a[ai] === '*' &&\n        b[bi] &&\n        (this.options.dot || !b[bi].startsWith('.')) &&\n        b[bi] !== '**'\n      ) {\n        if (which === 'b') return false\n        which = 'a'\n        result.push(a[ai])\n        ai++\n        bi++\n      } else if (\n        b[bi] === '*' &&\n        a[ai] &&\n        (this.options.dot || !a[ai].startsWith('.')) &&\n        a[ai] !== '**'\n      ) {\n        if (which === 'a') return false\n        which = 'b'\n        result.push(b[bi])\n        ai++\n        bi++\n      } else {\n        return false\n      }\n    }\n    // if we fall out of the loop, it means they two are identical\n    // as long as their lengths match\n    return a.length === b.length && result\n  }\n\n  parseNegate() {\n    if (this.nonegate) return\n\n    const pattern = this.pattern\n    let negate = false\n    let negateOffset = 0\n\n    for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {\n      negate = !negate\n      negateOffset++\n    }\n\n    if (negateOffset) this.pattern = pattern.slice(negateOffset)\n    this.negate = negate\n  }\n\n  // set partial to true to test if, for example,\n  // \"/a/b\" matches the start of \"/*/b/*/d\"\n  // Partial means, if you run out of file before you run\n  // out of pattern, then that's fine, as long as all\n  // the parts match.\n  matchOne(file: string[], pattern: ParseReturn[], partial: boolean = false) {\n    const options = this.options\n\n    // UNC paths like //?/X:/... can match X:/... and vice versa\n    // Drive letters in absolute drive or unc paths are always compared\n    // case-insensitively.\n    if (this.isWindows) {\n      const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0])\n      const fileUNC =\n        !fileDrive &&\n        file[0] === '' &&\n        file[1] === '' &&\n        file[2] === '?' &&\n        /^[a-z]:$/i.test(file[3])\n\n      const patternDrive =\n        typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0])\n      const patternUNC =\n        !patternDrive &&\n        pattern[0] === '' &&\n        pattern[1] === '' &&\n        pattern[2] === '?' &&\n        typeof pattern[3] === 'string' &&\n        /^[a-z]:$/i.test(pattern[3])\n\n      const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined\n      const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined\n      if (typeof fdi === 'number' && typeof pdi === 'number') {\n        const [fd, pd]: [string, string] = [file[fdi], pattern[pdi] as string]\n        if (fd.toLowerCase() === pd.toLowerCase()) {\n          pattern[pdi] = fd\n          if (pdi > fdi) {\n            pattern = pattern.slice(pdi)\n          } else if (fdi > pdi) {\n            file = file.slice(fdi)\n          }\n        }\n      }\n    }\n\n    // resolve and reduce . and .. portions in the file as well.\n    // dont' need to do the second phase, because it's only one string[]\n    const { optimizationLevel = 1 } = this.options\n    if (optimizationLevel >= 2) {\n      file = this.levelTwoFileOptimize(file)\n    }\n\n    this.debug('matchOne', this, { file, pattern })\n    this.debug('matchOne', file.length, pattern.length)\n\n    for (\n      var fi = 0, pi = 0, fl = file.length, pl = pattern.length;\n      fi < fl && pi < pl;\n      fi++, pi++\n    ) {\n      this.debug('matchOne loop')\n      var p = pattern[pi]\n      var f = file[fi]\n\n      this.debug(pattern, p, f)\n\n      // should be impossible.\n      // some invalid regexp stuff in the set.\n      /* c8 ignore start */\n      if (p === false) {\n        return false\n      }\n      /* c8 ignore stop */\n\n      if (p === GLOBSTAR) {\n        this.debug('GLOBSTAR', [pattern, p, f])\n\n        // \"**\"\n        // a/**/b/**/c would match the following:\n        // a/b/x/y/z/c\n        // a/x/y/z/b/c\n        // a/b/x/b/x/c\n        // a/b/c\n        // To do this, take the rest of the pattern after\n        // the **, and see if it would match the file remainder.\n        // If so, return success.\n        // If not, the ** \"swallows\" a segment, and try again.\n        // This is recursively awful.\n        //\n        // a/**/b/**/c matching a/b/x/y/z/c\n        // - a matches a\n        // - doublestar\n        //   - matchOne(b/x/y/z/c, b/**/c)\n        //     - b matches b\n        //     - doublestar\n        //       - matchOne(x/y/z/c, c) -> no\n        //       - matchOne(y/z/c, c) -> no\n        //       - matchOne(z/c, c) -> no\n        //       - matchOne(c, c) yes, hit\n        var fr = fi\n        var pr = pi + 1\n        if (pr === pl) {\n          this.debug('** at the end')\n          // a ** at the end will just swallow the rest.\n          // We have found a match.\n          // however, it will not swallow /.x, unless\n          // options.dot is set.\n          // . and .. are *never* matched by **, for explosively\n          // exponential reasons.\n          for (; fi < fl; fi++) {\n            if (\n              file[fi] === '.' ||\n              file[fi] === '..' ||\n              (!options.dot && file[fi].charAt(0) === '.')\n            )\n              return false\n          }\n          return true\n        }\n\n        // ok, let's see if we can swallow whatever we can.\n        while (fr < fl) {\n          var swallowee = file[fr]\n\n          this.debug('\\nglobstar while', file, fr, pattern, pr, swallowee)\n\n          // XXX remove this slice.  Just pass the start index.\n          if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {\n            this.debug('globstar found match!', fr, fl, swallowee)\n            // found a match.\n            return true\n          } else {\n            // can't swallow \".\" or \"..\" ever.\n            // can only swallow \".foo\" when explicitly asked.\n            if (\n              swallowee === '.' ||\n              swallowee === '..' ||\n              (!options.dot && swallowee.charAt(0) === '.')\n            ) {\n              this.debug('dot detected!', file, fr, pattern, pr)\n              break\n            }\n\n            // ** swallows a segment, and continue.\n            this.debug('globstar swallow a segment, and continue')\n            fr++\n          }\n        }\n\n        // no match was found.\n        // However, in partial mode, we can't say this is necessarily over.\n        /* c8 ignore start */\n        if (partial) {\n          // ran out of file\n          this.debug('\\n>>> no match, partial?', file, fr, pattern, pr)\n          if (fr === fl) {\n            return true\n          }\n        }\n        /* c8 ignore stop */\n        return false\n      }\n\n      // something other than **\n      // non-magic patterns just have to match exactly\n      // patterns with magic have been turned into regexps.\n      let hit: boolean\n      if (typeof p === 'string') {\n        hit = f === p\n        this.debug('string match', p, f, hit)\n      } else {\n        hit = p.test(f)\n        this.debug('pattern match', p, f, hit)\n      }\n\n      if (!hit) return false\n    }\n\n    // Note: ending in / means that we'll get a final \"\"\n    // at the end of the pattern.  This can only match a\n    // corresponding \"\" at the end of the file.\n    // If the file ends in /, then it can only match a\n    // a pattern that ends in /, unless the pattern just\n    // doesn't have any more for it. But, a/b/ should *not*\n    // match \"a/b/*\", even though \"\" matches against the\n    // [^/]*? pattern, except in partial mode, where it might\n    // simply not be reached yet.\n    // However, a/b/ should still satisfy a/*\n\n    // now either we fell off the end of the pattern, or we're done.\n    if (fi === fl && pi === pl) {\n      // ran out of pattern and filename at the same time.\n      // an exact hit!\n      return true\n    } else if (fi === fl) {\n      // ran out of file, but still had pattern left.\n      // this is ok if we're doing the match as part of\n      // a glob fs traversal.\n      return partial\n    } else if (pi === pl) {\n      // ran out of pattern, still have file left.\n      // this is only acceptable if we're on the very last\n      // empty segment of a file with a trailing slash.\n      // a/* should match a/b/\n      return fi === fl - 1 && file[fi] === ''\n\n      /* c8 ignore start */\n    } else {\n      // should be unreachable.\n      throw new Error('wtf?')\n    }\n    /* c8 ignore stop */\n  }\n\n  braceExpand() {\n    return braceExpand(this.pattern, this.options)\n  }\n\n  parse(pattern: string): ParseReturn {\n    assertValidPattern(pattern)\n\n    const options = this.options\n\n    // shortcuts\n    if (pattern === '**') return GLOBSTAR\n    if (pattern === '') return ''\n\n    // far and away, the most common glob pattern parts are\n    // *, *.*, and *.  Add a fast check method for those.\n    let m: RegExpMatchArray | null\n    let fastTest: null | ((f: string) => boolean) = null\n    if ((m = pattern.match(starRE))) {\n      fastTest = options.dot ? starTestDot : starTest\n    } else if ((m = pattern.match(starDotExtRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? starDotExtTestNocaseDot\n            : starDotExtTestNocase\n          : options.dot\n          ? starDotExtTestDot\n          : starDotExtTest\n      )(m[1])\n    } else if ((m = pattern.match(qmarksRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? qmarksTestNocaseDot\n            : qmarksTestNocase\n          : options.dot\n          ? qmarksTestDot\n          : qmarksTest\n      )(m)\n    } else if ((m = pattern.match(starDotStarRE))) {\n      fastTest = options.dot ? starDotStarTestDot : starDotStarTest\n    } else if ((m = pattern.match(dotStarRE))) {\n      fastTest = dotStarTest\n    }\n\n    const re = AST.fromGlob(pattern, this.options).toMMPattern()\n    if (fastTest && typeof re === 'object') {\n      // Avoids overriding in frozen environments\n      Reflect.defineProperty(re, 'test', { value: fastTest })\n    }\n    return re\n  }\n\n  makeRe() {\n    if (this.regexp || this.regexp === false) return this.regexp\n\n    // at this point, this.set is a 2d array of partial\n    // pattern strings, or \"**\".\n    //\n    // It's better to use .match().  This function shouldn't\n    // be used, really, but it's pretty convenient sometimes,\n    // when you just want to work with a regex.\n    const set = this.set\n\n    if (!set.length) {\n      this.regexp = false\n      return this.regexp\n    }\n    const options = this.options\n\n    const twoStar = options.noglobstar\n      ? star\n      : options.dot\n      ? twoStarDot\n      : twoStarNoDot\n    const flags = new Set(options.nocase ? ['i'] : [])\n\n    // regexpify non-globstar patterns\n    // if ** is only item, then we just do one twoStar\n    // if ** is first, and there are more, prepend (\\/|twoStar\\/)? to next\n    // if ** is last, append (\\/twoStar|) to previous\n    // if ** is in the middle, append (\\/|\\/twoStar\\/) to previous\n    // then filter out GLOBSTAR symbols\n    let re = set\n      .map(pattern => {\n        const pp: (string | typeof GLOBSTAR)[] = pattern.map(p => {\n          if (p instanceof RegExp) {\n            for (const f of p.flags.split('')) flags.add(f)\n          }\n          return typeof p === 'string'\n            ? regExpEscape(p)\n            : p === GLOBSTAR\n            ? GLOBSTAR\n            : p._src\n        }) as (string | typeof GLOBSTAR)[]\n        pp.forEach((p, i) => {\n          const next = pp[i + 1]\n          const prev = pp[i - 1]\n          if (p !== GLOBSTAR || prev === GLOBSTAR) {\n            return\n          }\n          if (prev === undefined) {\n            if (next !== undefined && next !== GLOBSTAR) {\n              pp[i + 1] = '(?:\\\\/|' + twoStar + '\\\\/)?' + next\n            } else {\n              pp[i] = twoStar\n            }\n          } else if (next === undefined) {\n            pp[i - 1] = prev + '(?:\\\\/|' + twoStar + ')?'\n          } else if (next !== GLOBSTAR) {\n            pp[i - 1] = prev + '(?:\\\\/|\\\\/' + twoStar + '\\\\/)' + next\n            pp[i + 1] = GLOBSTAR\n          }\n        })\n        return pp.filter(p => p !== GLOBSTAR).join('/')\n      })\n      .join('|')\n\n    // need to wrap in parens if we had more than one thing with |,\n    // otherwise only the first will be anchored to ^ and the last to $\n    const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']\n    // must match entire pattern\n    // ending in a * or ** will make it less strict.\n    re = '^' + open + re + close + '$'\n\n    // can match anything, as long as it's not this.\n    if (this.negate) re = '^(?!' + re + ').+$'\n\n    try {\n      this.regexp = new RegExp(re, [...flags].join(''))\n      /* c8 ignore start */\n    } catch (ex) {\n      // should be impossible\n      this.regexp = false\n    }\n    /* c8 ignore stop */\n    return this.regexp\n  }\n\n  slashSplit(p: string) {\n    // if p starts with // on windows, we preserve that\n    // so that UNC paths aren't broken.  Otherwise, any number of\n    // / characters are coalesced into one, unless\n    // preserveMultipleSlashes is set to true.\n    if (this.preserveMultipleSlashes) {\n      return p.split('/')\n    } else if (this.isWindows && /^\\/\\/[^\\/]+/.test(p)) {\n      // add an extra '' for the one we lose\n      return ['', ...p.split(/\\/+/)]\n    } else {\n      return p.split(/\\/+/)\n    }\n  }\n\n  match(f: string, partial = this.partial) {\n    this.debug('match', f, this.pattern)\n    // short-circuit in the case of busted things.\n    // comments, etc.\n    if (this.comment) {\n      return false\n    }\n    if (this.empty) {\n      return f === ''\n    }\n\n    if (f === '/' && partial) {\n      return true\n    }\n\n    const options = this.options\n\n    // windows: need to use /, not \\\n    if (this.isWindows) {\n      f = f.split('\\\\').join('/')\n    }\n\n    // treat the test path as a set of pathparts.\n    const ff = this.slashSplit(f)\n    this.debug(this.pattern, 'split', ff)\n\n    // just ONE of the pattern sets in this.set needs to match\n    // in order for it to be valid.  If negating, then just one\n    // match means that we have failed.\n    // Either way, return on the first hit.\n\n    const set = this.set\n    this.debug(this.pattern, 'set', set)\n\n    // Find the basename of the path by looking for the last non-empty segment\n    let filename: string = ff[ff.length - 1]\n    if (!filename) {\n      for (let i = ff.length - 2; !filename && i >= 0; i--) {\n        filename = ff[i]\n      }\n    }\n\n    for (let i = 0; i < set.length; i++) {\n      const pattern = set[i]\n      let file = ff\n      if (options.matchBase && pattern.length === 1) {\n        file = [filename]\n      }\n      const hit = this.matchOne(file, pattern, partial)\n      if (hit) {\n        if (options.flipNegate) {\n          return true\n        }\n        return !this.negate\n      }\n    }\n\n    // didn't get any hits.  this is success if it's a negative\n    // pattern, failure otherwise.\n    if (options.flipNegate) {\n      return false\n    }\n    return this.negate\n  }\n\n  static defaults(def: MinimatchOptions) {\n    return minimatch.defaults(def).Minimatch\n  }\n}\n/* c8 ignore start */\nexport { AST } from './ast.js'\nexport { escape } from './escape.js'\nexport { unescape } from './unescape.js'\n/* c8 ignore stop */\nminimatch.AST = AST\nminimatch.Minimatch = Minimatch\nminimatch.escape = escape\nminimatch.unescape = unescape\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/package.json b/backend/node_modules/minimatch/dist/commonjs/package.json
deleted file mode 100644
index 5bbefffb..00000000
--- a/backend/node_modules/minimatch/dist/commonjs/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "type": "commonjs"
-}
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts b/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts
deleted file mode 100644
index 23a7b387..00000000
--- a/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { MinimatchOptions } from './index.js';
-/**
- * Un-escape a string that has been escaped with {@link escape}.
- *
- * If the {@link windowsPathsNoEscape} option is used, then square-brace
- * escapes are removed, but not backslash escapes.  For example, it will turn
- * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
- * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
- *
- * When `windowsPathsNoEscape` is not set, then both brace escapes and
- * backslash escapes are removed.
- *
- * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
- * or unescaped.
- */
-export declare const unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
-//# sourceMappingURL=unescape.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map b/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map
deleted file mode 100644
index 7ace0701..00000000
--- a/backend/node_modules/minimatch/dist/commonjs/unescape.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,MAChB,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAKlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.js b/backend/node_modules/minimatch/dist/commonjs/unescape.js
deleted file mode 100644
index 47c36bce..00000000
--- a/backend/node_modules/minimatch/dist/commonjs/unescape.js
+++ /dev/null
@@ -1,24 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.unescape = void 0;
-/**
- * Un-escape a string that has been escaped with {@link escape}.
- *
- * If the {@link windowsPathsNoEscape} option is used, then square-brace
- * escapes are removed, but not backslash escapes.  For example, it will turn
- * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
- * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
- *
- * When `windowsPathsNoEscape` is not set, then both brace escapes and
- * backslash escapes are removed.
- *
- * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
- * or unescaped.
- */
-const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
-    return windowsPathsNoEscape
-        ? s.replace(/\[([^\/\\])\]/g, '$1')
-        : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
-};
-exports.unescape = unescape;
-//# sourceMappingURL=unescape.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/commonjs/unescape.js.map b/backend/node_modules/minimatch/dist/commonjs/unescape.js.map
deleted file mode 100644
index 353d3aa0..00000000
--- a/backend/node_modules/minimatch/dist/commonjs/unescape.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":";;;AACA;;;;;;;;;;;;;GAaG;AACI,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAA;AATY,QAAA,QAAQ,YASpB","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link windowsPathsNoEscape} option is used, then square-brace\n * escapes are removed, but not backslash escapes.  For example, it will turn\n * the string `'[*]'` into `*`, but it will not turn `'\\\\*'` into `'*'`,\n * becuase `\\` is a path separator in `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both brace escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n */\nexport const unescape = (\n  s: string,\n  {\n    windowsPathsNoEscape = false,\n  }: Pick = {}\n) => {\n  return windowsPathsNoEscape\n    ? s.replace(/\\[([^\\/\\\\])\\]/g, '$1')\n    : s.replace(/((?!\\\\).|^)\\[([^\\/\\\\])\\]/g, '$1$2').replace(/\\\\([^\\/])/g, '$1')\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts
deleted file mode 100644
index 8e318b23..00000000
--- a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export declare const assertValidPattern: (pattern: any) => void;
-//# sourceMappingURL=assert-valid-pattern.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map
deleted file mode 100644
index c61c0310..00000000
--- a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAUlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js
deleted file mode 100644
index 7b534fc3..00000000
--- a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js
+++ /dev/null
@@ -1,10 +0,0 @@
-const MAX_PATTERN_LENGTH = 1024 * 64;
-export const assertValidPattern = (pattern) => {
-    if (typeof pattern !== 'string') {
-        throw new TypeError('invalid pattern');
-    }
-    if (pattern.length > MAX_PATTERN_LENGTH) {
-        throw new TypeError('pattern is too long');
-    }
-};
-//# sourceMappingURL=assert-valid-pattern.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map b/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map
deleted file mode 100644
index b1a5a0b9..00000000
--- a/backend/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAA2B,CACxD,OAAY,EACe,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;KACvC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE;QACvC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;KAC3C;AACH,CAAC,CAAA","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: any) => void = (\n  pattern: any\n): asserts pattern is string => {\n  if (typeof pattern !== 'string') {\n    throw new TypeError('invalid pattern')\n  }\n\n  if (pattern.length > MAX_PATTERN_LENGTH) {\n    throw new TypeError('pattern is too long')\n  }\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.d.ts b/backend/node_modules/minimatch/dist/esm/ast.d.ts
deleted file mode 100644
index b8c1e544..00000000
--- a/backend/node_modules/minimatch/dist/esm/ast.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { MinimatchOptions, MMRegExp } from './index.js';
-export type ExtglobType = '!' | '?' | '+' | '*' | '@';
-export declare class AST {
-    #private;
-    type: ExtglobType | null;
-    constructor(type: ExtglobType | null, parent?: AST, options?: MinimatchOptions);
-    get hasMagic(): boolean | undefined;
-    toString(): string;
-    push(...parts: (string | AST)[]): void;
-    toJSON(): any[];
-    isStart(): boolean;
-    isEnd(): boolean;
-    copyIn(part: AST | string): void;
-    clone(parent: AST): AST;
-    static fromGlob(pattern: string, options?: MinimatchOptions): AST;
-    toMMPattern(): MMRegExp | string;
-    get options(): MinimatchOptions;
-    toRegExpSource(allowDot?: boolean): [re: string, body: string, hasMagic: boolean, uflag: boolean];
-}
-//# sourceMappingURL=ast.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.d.ts.map b/backend/node_modules/minimatch/dist/esm/ast.d.ts.map
deleted file mode 100644
index 9e7bfb9a..00000000
--- a/backend/node_modules/minimatch/dist/esm/ast.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwCvD,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAkCrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;gBAiBtB,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IA+ClB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAY/B,MAAM;IAgBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsIjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CAiMjE"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.js b/backend/node_modules/minimatch/dist/esm/ast.js
deleted file mode 100644
index 2d2bced6..00000000
--- a/backend/node_modules/minimatch/dist/esm/ast.js
+++ /dev/null
@@ -1,588 +0,0 @@
-// parse a single path portion
-import { parseClass } from './brace-expressions.js';
-import { unescape } from './unescape.js';
-const types = new Set(['!', '?', '+', '*', '@']);
-const isExtglobType = (c) => types.has(c);
-// Patterns that get prepended to bind to the start of either the
-// entire string, or just a single path portion, to prevent dots
-// and/or traversal patterns, when needed.
-// Exts don't need the ^ or / bit, because the root binds that already.
-const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))';
-const startNoDot = '(?!\\.)';
-// characters that indicate a start of pattern needs the "no dots" bit,
-// because a dot *might* be matched. ( is not in the list, because in
-// the case of a child extglob, it will handle the prevention itself.
-const addPatternStart = new Set(['[', '.']);
-// cases where traversal is A-OK, no dot prevention needed
-const justDots = new Set(['..', '.']);
-const reSpecials = new Set('().*{}+?[]^$\\!');
-const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-// any single thing other than /
-const qmark = '[^/]';
-// * => any number of characters
-const star = qmark + '*?';
-// use + when we need to ensure that *something* matches, because the * is
-// the only thing in the path portion.
-const starNoEmpty = qmark + '+?';
-// remove the \ chars that we added if we end up doing a nonmagic compare
-// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
-export class AST {
-    type;
-    #root;
-    #hasMagic;
-    #uflag = false;
-    #parts = [];
-    #parent;
-    #parentIndex;
-    #negs;
-    #filledNegs = false;
-    #options;
-    #toString;
-    // set to true if it's an extglob with no children
-    // (which really means one child of '')
-    #emptyExt = false;
-    constructor(type, parent, options = {}) {
-        this.type = type;
-        // extglobs are inherently magical
-        if (type)
-            this.#hasMagic = true;
-        this.#parent = parent;
-        this.#root = this.#parent ? this.#parent.#root : this;
-        this.#options = this.#root === this ? options : this.#root.#options;
-        this.#negs = this.#root === this ? [] : this.#root.#negs;
-        if (type === '!' && !this.#root.#filledNegs)
-            this.#negs.push(this);
-        this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;
-    }
-    get hasMagic() {
-        /* c8 ignore start */
-        if (this.#hasMagic !== undefined)
-            return this.#hasMagic;
-        /* c8 ignore stop */
-        for (const p of this.#parts) {
-            if (typeof p === 'string')
-                continue;
-            if (p.type || p.hasMagic)
-                return (this.#hasMagic = true);
-        }
-        // note: will be undefined until we generate the regexp src and find out
-        return this.#hasMagic;
-    }
-    // reconstructs the pattern
-    toString() {
-        if (this.#toString !== undefined)
-            return this.#toString;
-        if (!this.type) {
-            return (this.#toString = this.#parts.map(p => String(p)).join(''));
-        }
-        else {
-            return (this.#toString =
-                this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')');
-        }
-    }
-    #fillNegs() {
-        /* c8 ignore start */
-        if (this !== this.#root)
-            throw new Error('should only call on root');
-        if (this.#filledNegs)
-            return this;
-        /* c8 ignore stop */
-        // call toString() once to fill this out
-        this.toString();
-        this.#filledNegs = true;
-        let n;
-        while ((n = this.#negs.pop())) {
-            if (n.type !== '!')
-                continue;
-            // walk up the tree, appending everthing that comes AFTER parentIndex
-            let p = n;
-            let pp = p.#parent;
-            while (pp) {
-                for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {
-                    for (const part of n.#parts) {
-                        /* c8 ignore start */
-                        if (typeof part === 'string') {
-                            throw new Error('string part in extglob AST??');
-                        }
-                        /* c8 ignore stop */
-                        part.copyIn(pp.#parts[i]);
-                    }
-                }
-                p = pp;
-                pp = p.#parent;
-            }
-        }
-        return this;
-    }
-    push(...parts) {
-        for (const p of parts) {
-            if (p === '')
-                continue;
-            /* c8 ignore start */
-            if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {
-                throw new Error('invalid part: ' + p);
-            }
-            /* c8 ignore stop */
-            this.#parts.push(p);
-        }
-    }
-    toJSON() {
-        const ret = this.type === null
-            ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))
-            : [this.type, ...this.#parts.map(p => p.toJSON())];
-        if (this.isStart() && !this.type)
-            ret.unshift([]);
-        if (this.isEnd() &&
-            (this === this.#root ||
-                (this.#root.#filledNegs && this.#parent?.type === '!'))) {
-            ret.push({});
-        }
-        return ret;
-    }
-    isStart() {
-        if (this.#root === this)
-            return true;
-        // if (this.type) return !!this.#parent?.isStart()
-        if (!this.#parent?.isStart())
-            return false;
-        if (this.#parentIndex === 0)
-            return true;
-        // if everything AHEAD of this is a negation, then it's still the "start"
-        const p = this.#parent;
-        for (let i = 0; i < this.#parentIndex; i++) {
-            const pp = p.#parts[i];
-            if (!(pp instanceof AST && pp.type === '!')) {
-                return false;
-            }
-        }
-        return true;
-    }
-    isEnd() {
-        if (this.#root === this)
-            return true;
-        if (this.#parent?.type === '!')
-            return true;
-        if (!this.#parent?.isEnd())
-            return false;
-        if (!this.type)
-            return this.#parent?.isEnd();
-        // if not root, it'll always have a parent
-        /* c8 ignore start */
-        const pl = this.#parent ? this.#parent.#parts.length : 0;
-        /* c8 ignore stop */
-        return this.#parentIndex === pl - 1;
-    }
-    copyIn(part) {
-        if (typeof part === 'string')
-            this.push(part);
-        else
-            this.push(part.clone(this));
-    }
-    clone(parent) {
-        const c = new AST(this.type, parent);
-        for (const p of this.#parts) {
-            c.copyIn(p);
-        }
-        return c;
-    }
-    static #parseAST(str, ast, pos, opt) {
-        let escaping = false;
-        let inBrace = false;
-        let braceStart = -1;
-        let braceNeg = false;
-        if (ast.type === null) {
-            // outside of a extglob, append until we find a start
-            let i = pos;
-            let acc = '';
-            while (i < str.length) {
-                const c = str.charAt(i++);
-                // still accumulate escapes at this point, but we do ignore
-                // starts that are escaped
-                if (escaping || c === '\\') {
-                    escaping = !escaping;
-                    acc += c;
-                    continue;
-                }
-                if (inBrace) {
-                    if (i === braceStart + 1) {
-                        if (c === '^' || c === '!') {
-                            braceNeg = true;
-                        }
-                    }
-                    else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
-                        inBrace = false;
-                    }
-                    acc += c;
-                    continue;
-                }
-                else if (c === '[') {
-                    inBrace = true;
-                    braceStart = i;
-                    braceNeg = false;
-                    acc += c;
-                    continue;
-                }
-                if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {
-                    ast.push(acc);
-                    acc = '';
-                    const ext = new AST(c, ast);
-                    i = AST.#parseAST(str, ext, i, opt);
-                    ast.push(ext);
-                    continue;
-                }
-                acc += c;
-            }
-            ast.push(acc);
-            return i;
-        }
-        // some kind of extglob, pos is at the (
-        // find the next | or )
-        let i = pos + 1;
-        let part = new AST(null, ast);
-        const parts = [];
-        let acc = '';
-        while (i < str.length) {
-            const c = str.charAt(i++);
-            // still accumulate escapes at this point, but we do ignore
-            // starts that are escaped
-            if (escaping || c === '\\') {
-                escaping = !escaping;
-                acc += c;
-                continue;
-            }
-            if (inBrace) {
-                if (i === braceStart + 1) {
-                    if (c === '^' || c === '!') {
-                        braceNeg = true;
-                    }
-                }
-                else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
-                    inBrace = false;
-                }
-                acc += c;
-                continue;
-            }
-            else if (c === '[') {
-                inBrace = true;
-                braceStart = i;
-                braceNeg = false;
-                acc += c;
-                continue;
-            }
-            if (isExtglobType(c) && str.charAt(i) === '(') {
-                part.push(acc);
-                acc = '';
-                const ext = new AST(c, part);
-                part.push(ext);
-                i = AST.#parseAST(str, ext, i, opt);
-                continue;
-            }
-            if (c === '|') {
-                part.push(acc);
-                acc = '';
-                parts.push(part);
-                part = new AST(null, ast);
-                continue;
-            }
-            if (c === ')') {
-                if (acc === '' && ast.#parts.length === 0) {
-                    ast.#emptyExt = true;
-                }
-                part.push(acc);
-                acc = '';
-                ast.push(...parts, part);
-                return i;
-            }
-            acc += c;
-        }
-        // unfinished extglob
-        // if we got here, it was a malformed extglob! not an extglob, but
-        // maybe something else in there.
-        ast.type = null;
-        ast.#hasMagic = undefined;
-        ast.#parts = [str.substring(pos - 1)];
-        return i;
-    }
-    static fromGlob(pattern, options = {}) {
-        const ast = new AST(null, undefined, options);
-        AST.#parseAST(pattern, ast, 0, options);
-        return ast;
-    }
-    // returns the regular expression if there's magic, or the unescaped
-    // string if not.
-    toMMPattern() {
-        // should only be called on root
-        /* c8 ignore start */
-        if (this !== this.#root)
-            return this.#root.toMMPattern();
-        /* c8 ignore stop */
-        const glob = this.toString();
-        const [re, body, hasMagic, uflag] = this.toRegExpSource();
-        // if we're in nocase mode, and not nocaseMagicOnly, then we do
-        // still need a regular expression if we have to case-insensitively
-        // match capital/lowercase characters.
-        const anyMagic = hasMagic ||
-            this.#hasMagic ||
-            (this.#options.nocase &&
-                !this.#options.nocaseMagicOnly &&
-                glob.toUpperCase() !== glob.toLowerCase());
-        if (!anyMagic) {
-            return body;
-        }
-        const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '');
-        return Object.assign(new RegExp(`^${re}$`, flags), {
-            _src: re,
-            _glob: glob,
-        });
-    }
-    get options() {
-        return this.#options;
-    }
-    // returns the string match, the regexp source, whether there's magic
-    // in the regexp (so a regular expression is required) and whether or
-    // not the uflag is needed for the regular expression (for posix classes)
-    // TODO: instead of injecting the start/end at this point, just return
-    // the BODY of the regexp, along with the start/end portions suitable
-    // for binding the start/end in either a joined full-path makeRe context
-    // (where we bind to (^|/), or a standalone matchPart context (where
-    // we bind to ^, and not /).  Otherwise slashes get duped!
-    //
-    // In part-matching mode, the start is:
-    // - if not isStart: nothing
-    // - if traversal possible, but not allowed: ^(?!\.\.?$)
-    // - if dots allowed or not possible: ^
-    // - if dots possible and not allowed: ^(?!\.)
-    // end is:
-    // - if not isEnd(): nothing
-    // - else: $
-    //
-    // In full-path matching mode, we put the slash at the START of the
-    // pattern, so start is:
-    // - if first pattern: same as part-matching mode
-    // - if not isStart(): nothing
-    // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
-    // - if dots allowed or not possible: /
-    // - if dots possible and not allowed: /(?!\.)
-    // end is:
-    // - if last pattern, same as part-matching mode
-    // - else nothing
-    //
-    // Always put the (?:$|/) on negated tails, though, because that has to be
-    // there to bind the end of the negated pattern portion, and it's easier to
-    // just stick it in now rather than try to inject it later in the middle of
-    // the pattern.
-    //
-    // We can just always return the same end, and leave it up to the caller
-    // to know whether it's going to be used joined or in parts.
-    // And, if the start is adjusted slightly, can do the same there:
-    // - if not isStart: nothing
-    // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
-    // - if dots allowed or not possible: (?:/|^)
-    // - if dots possible and not allowed: (?:/|^)(?!\.)
-    //
-    // But it's better to have a simpler binding without a conditional, for
-    // performance, so probably better to return both start options.
-    //
-    // Then the caller just ignores the end if it's not the first pattern,
-    // and the start always gets applied.
-    //
-    // But that's always going to be $ if it's the ending pattern, or nothing,
-    // so the caller can just attach $ at the end of the pattern when building.
-    //
-    // So the todo is:
-    // - better detect what kind of start is needed
-    // - return both flavors of starting pattern
-    // - attach $ at the end of the pattern when creating the actual RegExp
-    //
-    // Ah, but wait, no, that all only applies to the root when the first pattern
-    // is not an extglob. If the first pattern IS an extglob, then we need all
-    // that dot prevention biz to live in the extglob portions, because eg
-    // +(*|.x*) can match .xy but not .yx.
-    //
-    // So, return the two flavors if it's #root and the first child is not an
-    // AST, otherwise leave it to the child AST to handle it, and there,
-    // use the (?:^|/) style of start binding.
-    //
-    // Even simplified further:
-    // - Since the start for a join is eg /(?!\.) and the start for a part
-    // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
-    // or start or whatever) and prepend ^ or / at the Regexp construction.
-    toRegExpSource(allowDot) {
-        const dot = allowDot ?? !!this.#options.dot;
-        if (this.#root === this)
-            this.#fillNegs();
-        if (!this.type) {
-            const noEmpty = this.isStart() && this.isEnd();
-            const src = this.#parts
-                .map(p => {
-                const [re, _, hasMagic, uflag] = typeof p === 'string'
-                    ? AST.#parseGlob(p, this.#hasMagic, noEmpty)
-                    : p.toRegExpSource(allowDot);
-                this.#hasMagic = this.#hasMagic || hasMagic;
-                this.#uflag = this.#uflag || uflag;
-                return re;
-            })
-                .join('');
-            let start = '';
-            if (this.isStart()) {
-                if (typeof this.#parts[0] === 'string') {
-                    // this is the string that will match the start of the pattern,
-                    // so we need to protect against dots and such.
-                    // '.' and '..' cannot match unless the pattern is that exactly,
-                    // even if it starts with . or dot:true is set.
-                    const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
-                    if (!dotTravAllowed) {
-                        const aps = addPatternStart;
-                        // check if we have a possibility of matching . or ..,
-                        // and prevent that.
-                        const needNoTrav = 
-                        // dots are allowed, and the pattern starts with [ or .
-                        (dot && aps.has(src.charAt(0))) ||
-                            // the pattern starts with \., and then [ or .
-                            (src.startsWith('\\.') && aps.has(src.charAt(2))) ||
-                            // the pattern starts with \.\., and then [ or .
-                            (src.startsWith('\\.\\.') && aps.has(src.charAt(4)));
-                        // no need to prevent dots if it can't match a dot, or if a
-                        // sub-pattern will be preventing it anyway.
-                        const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
-                        start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : '';
-                    }
-                }
-            }
-            // append the "end of path portion" pattern to negation tails
-            let end = '';
-            if (this.isEnd() &&
-                this.#root.#filledNegs &&
-                this.#parent?.type === '!') {
-                end = '(?:$|\\/)';
-            }
-            const final = start + src + end;
-            return [
-                final,
-                unescape(src),
-                (this.#hasMagic = !!this.#hasMagic),
-                this.#uflag,
-            ];
-        }
-        // We need to calculate the body *twice* if it's a repeat pattern
-        // at the start, once in nodot mode, then again in dot mode, so a
-        // pattern like *(?) can match 'x.y'
-        const repeated = this.type === '*' || this.type === '+';
-        // some kind of extglob
-        const start = this.type === '!' ? '(?:(?!(?:' : '(?:';
-        let body = this.#partsToRegExp(dot);
-        if (this.isStart() && this.isEnd() && !body && this.type !== '!') {
-            // invalid extglob, has to at least be *something* present, if it's
-            // the entire path portion.
-            const s = this.toString();
-            this.#parts = [s];
-            this.type = null;
-            this.#hasMagic = undefined;
-            return [s, unescape(this.toString()), false, false];
-        }
-        // XXX abstract out this map method
-        let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot
-            ? ''
-            : this.#partsToRegExp(true);
-        if (bodyDotAllowed === body) {
-            bodyDotAllowed = '';
-        }
-        if (bodyDotAllowed) {
-            body = `(?:${body})(?:${bodyDotAllowed})*?`;
-        }
-        // an empty !() is exactly equivalent to a starNoEmpty
-        let final = '';
-        if (this.type === '!' && this.#emptyExt) {
-            final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty;
-        }
-        else {
-            const close = this.type === '!'
-                ? // !() must match something,but !(x) can match ''
-                    '))' +
-                        (this.isStart() && !dot && !allowDot ? startNoDot : '') +
-                        star +
-                        ')'
-                : this.type === '@'
-                    ? ')'
-                    : this.type === '?'
-                        ? ')?'
-                        : this.type === '+' && bodyDotAllowed
-                            ? ')'
-                            : this.type === '*' && bodyDotAllowed
-                                ? `)?`
-                                : `)${this.type}`;
-            final = start + body + close;
-        }
-        return [
-            final,
-            unescape(body),
-            (this.#hasMagic = !!this.#hasMagic),
-            this.#uflag,
-        ];
-    }
-    #partsToRegExp(dot) {
-        return this.#parts
-            .map(p => {
-            // extglob ASTs should only contain parent ASTs
-            /* c8 ignore start */
-            if (typeof p === 'string') {
-                throw new Error('string type in extglob ast??');
-            }
-            /* c8 ignore stop */
-            // can ignore hasMagic, because extglobs are already always magic
-            const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
-            this.#uflag = this.#uflag || uflag;
-            return re;
-        })
-            .filter(p => !(this.isStart() && this.isEnd()) || !!p)
-            .join('|');
-    }
-    static #parseGlob(glob, hasMagic, noEmpty = false) {
-        let escaping = false;
-        let re = '';
-        let uflag = false;
-        for (let i = 0; i < glob.length; i++) {
-            const c = glob.charAt(i);
-            if (escaping) {
-                escaping = false;
-                re += (reSpecials.has(c) ? '\\' : '') + c;
-                continue;
-            }
-            if (c === '\\') {
-                if (i === glob.length - 1) {
-                    re += '\\\\';
-                }
-                else {
-                    escaping = true;
-                }
-                continue;
-            }
-            if (c === '[') {
-                const [src, needUflag, consumed, magic] = parseClass(glob, i);
-                if (consumed) {
-                    re += src;
-                    uflag = uflag || needUflag;
-                    i += consumed - 1;
-                    hasMagic = hasMagic || magic;
-                    continue;
-                }
-            }
-            if (c === '*') {
-                if (noEmpty && glob === '*')
-                    re += starNoEmpty;
-                else
-                    re += star;
-                hasMagic = true;
-                continue;
-            }
-            if (c === '?') {
-                re += qmark;
-                hasMagic = true;
-                continue;
-            }
-            re += regExpEscape(c);
-        }
-        return [re, unescape(glob), !!hasMagic, uflag];
-    }
-}
-//# sourceMappingURL=ast.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/ast.js.map b/backend/node_modules/minimatch/dist/esm/ast.js.map
deleted file mode 100644
index f1f8b34c..00000000
--- a/backend/node_modules/minimatch/dist/esm/ast.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAwCxC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAC7D,MAAM,aAAa,GAAG,CAAC,CAAS,EAAoB,EAAE,CACpD,KAAK,CAAC,GAAG,CAAC,CAAgB,CAAC,CAAA;AAE7B,iEAAiE;AACjE,gEAAgE;AAChE,0CAA0C;AAC1C,uEAAuE;AACvE,MAAM,gBAAgB,GAAG,2BAA2B,CAAA;AACpD,MAAM,UAAU,GAAG,SAAS,CAAA;AAE5B,uEAAuE;AACvE,qEAAqE;AACrE,qEAAqE;AACrE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAC3C,0DAA0D;AAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;AACrC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,CAAA;AAC7C,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CACjC,CAAC,CAAC,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAA;AAE/C,gCAAgC;AAChC,MAAM,KAAK,GAAG,MAAM,CAAA;AAEpB,gCAAgC;AAChC,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,CAAA;AACzB,0EAA0E;AAC1E,sCAAsC;AACtC,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,CAAA;AAEhC,yEAAyE;AACzE,2DAA2D;AAE3D,MAAM,OAAO,GAAG;IACd,IAAI,CAAoB;IACf,KAAK,CAAK;IAEnB,SAAS,CAAU;IACnB,MAAM,GAAY,KAAK,CAAA;IACvB,MAAM,GAAqB,EAAE,CAAA;IACpB,OAAO,CAAM;IACb,YAAY,CAAQ;IAC7B,KAAK,CAAO;IACZ,WAAW,GAAY,KAAK,CAAA;IAC5B,QAAQ,CAAkB;IAC1B,SAAS,CAAS;IAClB,kDAAkD;IAClD,uCAAuC;IACvC,SAAS,GAAY,KAAK,CAAA;IAE1B,YACE,IAAwB,EACxB,MAAY,EACZ,UAA4B,EAAE;QAE9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,kCAAkC;QAClC,IAAI,IAAI;YAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;QAC/B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;QACrD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QACnE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAA;QACxD,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW;YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IACnE,CAAC;IAED,IAAI,QAAQ;QACV,qBAAqB;QACrB,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAA;QACvD,oBAAoB;QACpB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;YAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,SAAQ;YACnC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ;gBAAE,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;SACzD;QACD,wEAAwE;QACxE,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAED,2BAA2B;IAC3B,QAAQ;QACN,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAA;QACvD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;SACnE;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,SAAS;gBACpB,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;SACrE;IACH,CAAC;IAED,SAAS;QACP,qBAAqB;QACrB,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;QACpE,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAA;QACjC,oBAAoB;QAEpB,wCAAwC;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAA;QACf,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACvB,IAAI,CAAkB,CAAA;QACtB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE;YAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG;gBAAE,SAAQ;YAC5B,qEAAqE;YACrE,IAAI,CAAC,GAAoB,CAAC,CAAA;YAC1B,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAA;YAClB,OAAO,EAAE,EAAE;gBACT,KACE,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,EAC1B,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAChC,CAAC,EAAE,EACH;oBACA,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE;wBAC3B,qBAAqB;wBACrB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;4BAC5B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;yBAChD;wBACD,oBAAoB;wBACpB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;qBAC1B;iBACF;gBACD,CAAC,GAAG,EAAE,CAAA;gBACN,EAAE,GAAG,CAAC,CAAC,OAAO,CAAA;aACf;SACF;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC,GAAG,KAAuB;QAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE;YACrB,IAAI,CAAC,KAAK,EAAE;gBAAE,SAAQ;YACtB,qBAAqB;YACrB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE;gBACtE,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAA;aACtC;YACD,oBAAoB;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SACpB;IACH,CAAC;IAED,MAAM;QACJ,MAAM,GAAG,GACP,IAAI,CAAC,IAAI,KAAK,IAAI;YAChB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAC/D,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACjD,IACE,IAAI,CAAC,KAAK,EAAE;YACZ,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK;gBAClB,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,GAAG,CAAC,CAAC,EACzD;YACA,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;SACb;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QACpC,kDAAkD;QAClD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE;YAAE,OAAO,KAAK,CAAA;QAC1C,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QACxC,yEAAyE;QACzE,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACtB,IAAI,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;gBAC3C,OAAO,KAAK,CAAA;aACb;SACF;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QACpC,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA;QAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE;YAAE,OAAO,KAAK,CAAA;QACxC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;QAC5C,0CAA0C;QAC1C,qBAAqB;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACxD,oBAAoB;QACpB,OAAO,IAAI,CAAC,YAAY,KAAK,EAAE,GAAG,CAAC,CAAA;IACrC,CAAC;IAED,MAAM,CAAC,IAAkB;QACvB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;;YACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,MAAW;QACf,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACpC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;YAC3B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;SACZ;QACD,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM,CAAC,SAAS,CACd,GAAW,EACX,GAAQ,EACR,GAAW,EACX,GAAqB;QAErB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,UAAU,GAAG,CAAC,CAAC,CAAA;QACnB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE;YACrB,qDAAqD;YACrD,IAAI,CAAC,GAAG,GAAG,CAAA;YACX,IAAI,GAAG,GAAG,EAAE,CAAA;YACZ,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE;gBACrB,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;gBACzB,2DAA2D;gBAC3D,0BAA0B;gBAC1B,IAAI,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE;oBAC1B,QAAQ,GAAG,CAAC,QAAQ,CAAA;oBACpB,GAAG,IAAI,CAAC,CAAA;oBACR,SAAQ;iBACT;gBAED,IAAI,OAAO,EAAE;oBACX,IAAI,CAAC,KAAK,UAAU,GAAG,CAAC,EAAE;wBACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE;4BAC1B,QAAQ,GAAG,IAAI,CAAA;yBAChB;qBACF;yBAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,CAAC,IAAI,QAAQ,CAAC,EAAE;wBAC3D,OAAO,GAAG,KAAK,CAAA;qBAChB;oBACD,GAAG,IAAI,CAAC,CAAA;oBACR,SAAQ;iBACT;qBAAM,IAAI,CAAC,KAAK,GAAG,EAAE;oBACpB,OAAO,GAAG,IAAI,CAAA;oBACd,UAAU,GAAG,CAAC,CAAA;oBACd,QAAQ,GAAG,KAAK,CAAA;oBAChB,GAAG,IAAI,CAAC,CAAA;oBACR,SAAQ;iBACT;gBAED,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBAC3D,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBACb,GAAG,GAAG,EAAE,CAAA;oBACR,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;oBAC3B,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;oBACnC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;iBACT;gBACD,GAAG,IAAI,CAAC,CAAA;aACT;YACD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACb,OAAO,CAAC,CAAA;SACT;QAED,wCAAwC;QACxC,uBAAuB;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;QACf,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC7B,MAAM,KAAK,GAAU,EAAE,CAAA;QACvB,IAAI,GAAG,GAAG,EAAE,CAAA;QACZ,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE;YACrB,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;YACzB,2DAA2D;YAC3D,0BAA0B;YAC1B,IAAI,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE;gBAC1B,QAAQ,GAAG,CAAC,QAAQ,CAAA;gBACpB,GAAG,IAAI,CAAC,CAAA;gBACR,SAAQ;aACT;YAED,IAAI,OAAO,EAAE;gBACX,IAAI,CAAC,KAAK,UAAU,GAAG,CAAC,EAAE;oBACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE;wBAC1B,QAAQ,GAAG,IAAI,CAAA;qBAChB;iBACF;qBAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,CAAC,IAAI,QAAQ,CAAC,EAAE;oBAC3D,OAAO,GAAG,KAAK,CAAA;iBAChB;gBACD,GAAG,IAAI,CAAC,CAAA;gBACR,SAAQ;aACT;iBAAM,IAAI,CAAC,KAAK,GAAG,EAAE;gBACpB,OAAO,GAAG,IAAI,CAAA;gBACd,UAAU,GAAG,CAAC,CAAA;gBACd,QAAQ,GAAG,KAAK,CAAA;gBAChB,GAAG,IAAI,CAAC,CAAA;gBACR,SAAQ;aACT;YAED,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;gBAC7C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,GAAG,GAAG,EAAE,CAAA;gBACR,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;gBAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;gBACnC,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,GAAG,GAAG,EAAE,CAAA;gBACR,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAChB,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;gBACzB,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;oBACzC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAA;iBACrB;gBACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,GAAG,GAAG,EAAE,CAAA;gBACR,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAA;gBACxB,OAAO,CAAC,CAAA;aACT;YACD,GAAG,IAAI,CAAC,CAAA;SACT;QAED,qBAAqB;QACrB,kEAAkE;QAClE,iCAAiC;QACjC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAA;QACf,GAAG,CAAC,SAAS,GAAG,SAAS,CAAA;QACzB,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;QACrC,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAe,EAAE,UAA4B,EAAE;QAC7D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QAC7C,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAA;QACvC,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,oEAAoE;IACpE,iBAAiB;IACjB,WAAW;QACT,gCAAgC;QAChC,qBAAqB;QACrB,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA;QACxD,oBAAoB;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;QAC5B,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;QACzD,+DAA+D;QAC/D,mEAAmE;QACnE,sCAAsC;QACtC,MAAM,QAAQ,GACZ,QAAQ;YACR,IAAI,CAAC,SAAS;YACd,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM;gBACnB,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe;gBAC9B,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QAC9C,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO,IAAI,CAAA;SACZ;QAED,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACpE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE;YACjD,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,qEAAqE;IACrE,qEAAqE;IACrE,yEAAyE;IACzE,sEAAsE;IACtE,qEAAqE;IACrE,wEAAwE;IACxE,oEAAoE;IACpE,0DAA0D;IAC1D,EAAE;IACF,uCAAuC;IACvC,4BAA4B;IAC5B,wDAAwD;IACxD,uCAAuC;IACvC,8CAA8C;IAC9C,UAAU;IACV,4BAA4B;IAC5B,YAAY;IACZ,EAAE;IACF,mEAAmE;IACnE,wBAAwB;IACxB,iDAAiD;IACjD,8BAA8B;IAC9B,8DAA8D;IAC9D,uCAAuC;IACvC,8CAA8C;IAC9C,UAAU;IACV,gDAAgD;IAChD,iBAAiB;IACjB,EAAE;IACF,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,eAAe;IACf,EAAE;IACF,wEAAwE;IACxE,4DAA4D;IAC5D,iEAAiE;IACjE,4BAA4B;IAC5B,8DAA8D;IAC9D,6CAA6C;IAC7C,oDAAoD;IACpD,EAAE;IACF,uEAAuE;IACvE,gEAAgE;IAChE,EAAE;IACF,sEAAsE;IACtE,qCAAqC;IACrC,EAAE;IACF,0EAA0E;IAC1E,2EAA2E;IAC3E,EAAE;IACF,kBAAkB;IAClB,+CAA+C;IAC/C,4CAA4C;IAC5C,uEAAuE;IACvE,EAAE;IACF,6EAA6E;IAC7E,0EAA0E;IAC1E,sEAAsE;IACtE,sCAAsC;IACtC,EAAE;IACF,yEAAyE;IACzE,oEAAoE;IACpE,0CAA0C;IAC1C,EAAE;IACF,2BAA2B;IAC3B,sEAAsE;IACtE,qEAAqE;IACrE,uEAAuE;IACvE,cAAc,CACZ,QAAkB;QAElB,MAAM,GAAG,GAAG,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAA;QAC3C,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,IAAI,CAAC,SAAS,EAAE,CAAA;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAA;YAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM;iBACpB,GAAG,CAAC,CAAC,CAAC,EAAE;gBACP,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,GAC5B,OAAO,CAAC,KAAK,QAAQ;oBACnB,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;oBAC5C,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;gBAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAA;gBAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;gBAClC,OAAO,EAAE,CAAA;YACX,CAAC,CAAC;iBACD,IAAI,CAAC,EAAE,CAAC,CAAA;YAEX,IAAI,KAAK,GAAG,EAAE,CAAA;YACd,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;gBAClB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;oBACtC,+DAA+D;oBAC/D,+CAA+C;oBAE/C,gEAAgE;oBAChE,+CAA+C;oBAC/C,MAAM,cAAc,GAClB,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;oBAC1D,IAAI,CAAC,cAAc,EAAE;wBACnB,MAAM,GAAG,GAAG,eAAe,CAAA;wBAC3B,sDAAsD;wBACtD,oBAAoB;wBACpB,MAAM,UAAU;wBACd,uDAAuD;wBACvD,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC/B,8CAA8C;4BAC9C,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;4BACjD,gDAAgD;4BAChD,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;wBACtD,2DAA2D;wBAC3D,4CAA4C;wBAC5C,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;wBAE7D,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;qBACpE;iBACF;aACF;YAED,6DAA6D;YAC7D,IAAI,GAAG,GAAG,EAAE,CAAA;YACZ,IACE,IAAI,CAAC,KAAK,EAAE;gBACZ,IAAI,CAAC,KAAK,CAAC,WAAW;gBACtB,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,GAAG,EAC1B;gBACA,GAAG,GAAG,WAAW,CAAA;aAClB;YACD,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,GAAG,GAAG,CAAA;YAC/B,OAAO;gBACL,KAAK;gBACL,QAAQ,CAAC,GAAG,CAAC;gBACb,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;gBACnC,IAAI,CAAC,MAAM;aACZ,CAAA;SACF;QAED,iEAAiE;QACjE,iEAAiE;QACjE,oCAAoC;QAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,CAAA;QACvD,uBAAuB;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAA;QACrD,IAAI,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QAEnC,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,EAAE;YAChE,mEAAmE;YACnE,2BAA2B;YAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;YACzB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;YACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;YAChB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;YAC1B,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;SACpD;QAED,mCAAmC;QACnC,IAAI,cAAc,GAChB,CAAC,QAAQ,IAAI,QAAQ,IAAI,GAAG,IAAI,CAAC,UAAU;YACzC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAC/B,IAAI,cAAc,KAAK,IAAI,EAAE;YAC3B,cAAc,GAAG,EAAE,CAAA;SACpB;QACD,IAAI,cAAc,EAAE;YAClB,IAAI,GAAG,MAAM,IAAI,OAAO,cAAc,KAAK,CAAA;SAC5C;QAED,sDAAsD;QACtD,IAAI,KAAK,GAAG,EAAE,CAAA;QACd,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE;YACvC,KAAK,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAA;SACjE;aAAM;YACL,MAAM,KAAK,GACT,IAAI,CAAC,IAAI,KAAK,GAAG;gBACf,CAAC,CAAC,iDAAiD;oBACjD,IAAI;wBACJ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;wBACvD,IAAI;wBACJ,GAAG;gBACL,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG;oBACnB,CAAC,CAAC,GAAG;oBACL,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG;wBACnB,CAAC,CAAC,IAAI;wBACN,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,cAAc;4BACrC,CAAC,CAAC,GAAG;4BACL,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,cAAc;gCACrC,CAAC,CAAC,IAAI;gCACN,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAA;YACrB,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAA;SAC7B;QACD,OAAO;YACL,KAAK;YACL,QAAQ,CAAC,IAAI,CAAC;YACd,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;YACnC,IAAI,CAAC,MAAM;SACZ,CAAA;IACH,CAAC;IAED,cAAc,CAAC,GAAY;QACzB,OAAO,IAAI,CAAC,MAAM;aACf,GAAG,CAAC,CAAC,CAAC,EAAE;YACP,+CAA+C;YAC/C,qBAAqB;YACrB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;gBACzB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;aAChD;YACD,oBAAoB;YACpB,iEAAiE;YACjE,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;YACvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;YAClC,OAAO,EAAE,CAAA;QACX,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACrD,IAAI,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;IAED,MAAM,CAAC,UAAU,CACf,IAAY,EACZ,QAA6B,EAC7B,UAAmB,KAAK;QAExB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,EAAE,GAAG,EAAE,CAAA;QACX,IAAI,KAAK,GAAG,KAAK,CAAA;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACpC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACxB,IAAI,QAAQ,EAAE;gBACZ,QAAQ,GAAG,KAAK,CAAA;gBAChB,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBACzC,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,IAAI,EAAE;gBACd,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;oBACzB,EAAE,IAAI,MAAM,CAAA;iBACb;qBAAM;oBACL,QAAQ,GAAG,IAAI,CAAA;iBAChB;gBACD,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;gBAC7D,IAAI,QAAQ,EAAE;oBACZ,EAAE,IAAI,GAAG,CAAA;oBACT,KAAK,GAAG,KAAK,IAAI,SAAS,CAAA;oBAC1B,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAA;oBACjB,QAAQ,GAAG,QAAQ,IAAI,KAAK,CAAA;oBAC5B,SAAQ;iBACT;aACF;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,IAAI,OAAO,IAAI,IAAI,KAAK,GAAG;oBAAE,EAAE,IAAI,WAAW,CAAA;;oBACzC,EAAE,IAAI,IAAI,CAAA;gBACf,QAAQ,GAAG,IAAI,CAAA;gBACf,SAAQ;aACT;YACD,IAAI,CAAC,KAAK,GAAG,EAAE;gBACb,EAAE,IAAI,KAAK,CAAA;gBACX,QAAQ,GAAG,IAAI,CAAA;gBACf,SAAQ;aACT;YACD,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,CAAA;SACtB;QACD,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAChD,CAAC;CACF","sourcesContent":["// parse a single path portion\n\nimport { parseClass } from './brace-expressions.js'\nimport { MinimatchOptions, MMRegExp } from './index.js'\nimport { unescape } from './unescape.js'\n\n// classes [] are handled by the parseClass method\n// for positive extglobs, we sub-parse the contents, and combine,\n// with the appropriate regexp close.\n// for negative extglobs, we sub-parse the contents, but then\n// have to include the rest of the pattern, then the parent, etc.,\n// as the thing that cannot be because RegExp negative lookaheads\n// are different from globs.\n//\n// So for example:\n// a@(i|w!(x|y)z|j)b => ^a(i|w((!?(x|y)zb).*)z|j)b$\n//   1   2 3   4 5 6      1   2    3   46      5 6\n//\n// Assembling the extglob requires not just the negated patterns themselves,\n// but also anything following the negative patterns up to the boundary\n// of the current pattern, plus anything following in the parent pattern.\n//\n//\n// So, first, we parse the string into an AST of extglobs, without turning\n// anything into regexps yet.\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y']}, 'z'], ['j']]}, 'b']\n//\n// Then, for all the negative extglobs, we append whatever comes after in\n// each parent as their tail\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y'], 'z', 'b'}, 'z'], ['j']]}, 'b']\n//\n// Lastly, we turn each of these pieces into a regexp, and join\n//\n//                                 v----- .* because there's more following,\n//                                 v    v  otherwise, .+ because it must be\n//                                 v    v  *something* there.\n// ['^a', {@ ['i', 'w(?:(!?(?:x|y).*zb$).*)z', 'j' ]}, 'b$']\n//   copy what follows into here--^^^^^\n// ['^a', '(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)', 'b$']\n// ['^a(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)b$']\n\nexport type ExtglobType = '!' | '?' | '+' | '*' | '@'\nconst types = new Set(['!', '?', '+', '*', '@'])\nconst isExtglobType = (c: string): c is ExtglobType =>\n  types.has(c as ExtglobType)\n\n// Patterns that get prepended to bind to the start of either the\n// entire string, or just a single path portion, to prevent dots\n// and/or traversal patterns, when needed.\n// Exts don't need the ^ or / bit, because the root binds that already.\nconst startNoTraversal = '(?!(?:^|/)\\\\.\\\\.?(?:$|/))'\nconst startNoDot = '(?!\\\\.)'\n\n// characters that indicate a start of pattern needs the \"no dots\" bit,\n// because a dot *might* be matched. ( is not in the list, because in\n// the case of a child extglob, it will handle the prevention itself.\nconst addPatternStart = new Set(['[', '.'])\n// cases where traversal is A-OK, no dot prevention needed\nconst justDots = new Set(['..', '.'])\nconst reSpecials = new Set('().*{}+?[]^$\\\\!')\nconst regExpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// any single thing other than /\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n// use + when we need to ensure that *something* matches, because the * is\n// the only thing in the path portion.\nconst starNoEmpty = qmark + '+?'\n\n// remove the \\ chars that we added if we end up doing a nonmagic compare\n// const deslash = (s: string) => s.replace(/\\\\(.)/g, '$1')\n\nexport class AST {\n  type: ExtglobType | null\n  readonly #root: AST\n\n  #hasMagic?: boolean\n  #uflag: boolean = false\n  #parts: (string | AST)[] = []\n  readonly #parent?: AST\n  readonly #parentIndex: number\n  #negs: AST[]\n  #filledNegs: boolean = false\n  #options: MinimatchOptions\n  #toString?: string\n  // set to true if it's an extglob with no children\n  // (which really means one child of '')\n  #emptyExt: boolean = false\n\n  constructor(\n    type: ExtglobType | null,\n    parent?: AST,\n    options: MinimatchOptions = {}\n  ) {\n    this.type = type\n    // extglobs are inherently magical\n    if (type) this.#hasMagic = true\n    this.#parent = parent\n    this.#root = this.#parent ? this.#parent.#root : this\n    this.#options = this.#root === this ? options : this.#root.#options\n    this.#negs = this.#root === this ? [] : this.#root.#negs\n    if (type === '!' && !this.#root.#filledNegs) this.#negs.push(this)\n    this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0\n  }\n\n  get hasMagic(): boolean | undefined {\n    /* c8 ignore start */\n    if (this.#hasMagic !== undefined) return this.#hasMagic\n    /* c8 ignore stop */\n    for (const p of this.#parts) {\n      if (typeof p === 'string') continue\n      if (p.type || p.hasMagic) return (this.#hasMagic = true)\n    }\n    // note: will be undefined until we generate the regexp src and find out\n    return this.#hasMagic\n  }\n\n  // reconstructs the pattern\n  toString(): string {\n    if (this.#toString !== undefined) return this.#toString\n    if (!this.type) {\n      return (this.#toString = this.#parts.map(p => String(p)).join(''))\n    } else {\n      return (this.#toString =\n        this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')')\n    }\n  }\n\n  #fillNegs() {\n    /* c8 ignore start */\n    if (this !== this.#root) throw new Error('should only call on root')\n    if (this.#filledNegs) return this\n    /* c8 ignore stop */\n\n    // call toString() once to fill this out\n    this.toString()\n    this.#filledNegs = true\n    let n: AST | undefined\n    while ((n = this.#negs.pop())) {\n      if (n.type !== '!') continue\n      // walk up the tree, appending everthing that comes AFTER parentIndex\n      let p: AST | undefined = n\n      let pp = p.#parent\n      while (pp) {\n        for (\n          let i = p.#parentIndex + 1;\n          !pp.type && i < pp.#parts.length;\n          i++\n        ) {\n          for (const part of n.#parts) {\n            /* c8 ignore start */\n            if (typeof part === 'string') {\n              throw new Error('string part in extglob AST??')\n            }\n            /* c8 ignore stop */\n            part.copyIn(pp.#parts[i])\n          }\n        }\n        p = pp\n        pp = p.#parent\n      }\n    }\n    return this\n  }\n\n  push(...parts: (string | AST)[]) {\n    for (const p of parts) {\n      if (p === '') continue\n      /* c8 ignore start */\n      if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {\n        throw new Error('invalid part: ' + p)\n      }\n      /* c8 ignore stop */\n      this.#parts.push(p)\n    }\n  }\n\n  toJSON() {\n    const ret: any[] =\n      this.type === null\n        ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))\n        : [this.type, ...this.#parts.map(p => (p as AST).toJSON())]\n    if (this.isStart() && !this.type) ret.unshift([])\n    if (\n      this.isEnd() &&\n      (this === this.#root ||\n        (this.#root.#filledNegs && this.#parent?.type === '!'))\n    ) {\n      ret.push({})\n    }\n    return ret\n  }\n\n  isStart(): boolean {\n    if (this.#root === this) return true\n    // if (this.type) return !!this.#parent?.isStart()\n    if (!this.#parent?.isStart()) return false\n    if (this.#parentIndex === 0) return true\n    // if everything AHEAD of this is a negation, then it's still the \"start\"\n    const p = this.#parent\n    for (let i = 0; i < this.#parentIndex; i++) {\n      const pp = p.#parts[i]\n      if (!(pp instanceof AST && pp.type === '!')) {\n        return false\n      }\n    }\n    return true\n  }\n\n  isEnd(): boolean {\n    if (this.#root === this) return true\n    if (this.#parent?.type === '!') return true\n    if (!this.#parent?.isEnd()) return false\n    if (!this.type) return this.#parent?.isEnd()\n    // if not root, it'll always have a parent\n    /* c8 ignore start */\n    const pl = this.#parent ? this.#parent.#parts.length : 0\n    /* c8 ignore stop */\n    return this.#parentIndex === pl - 1\n  }\n\n  copyIn(part: AST | string) {\n    if (typeof part === 'string') this.push(part)\n    else this.push(part.clone(this))\n  }\n\n  clone(parent: AST) {\n    const c = new AST(this.type, parent)\n    for (const p of this.#parts) {\n      c.copyIn(p)\n    }\n    return c\n  }\n\n  static #parseAST(\n    str: string,\n    ast: AST,\n    pos: number,\n    opt: MinimatchOptions\n  ): number {\n    let escaping = false\n    let inBrace = false\n    let braceStart = -1\n    let braceNeg = false\n    if (ast.type === null) {\n      // outside of a extglob, append until we find a start\n      let i = pos\n      let acc = ''\n      while (i < str.length) {\n        const c = str.charAt(i++)\n        // still accumulate escapes at this point, but we do ignore\n        // starts that are escaped\n        if (escaping || c === '\\\\') {\n          escaping = !escaping\n          acc += c\n          continue\n        }\n\n        if (inBrace) {\n          if (i === braceStart + 1) {\n            if (c === '^' || c === '!') {\n              braceNeg = true\n            }\n          } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n            inBrace = false\n          }\n          acc += c\n          continue\n        } else if (c === '[') {\n          inBrace = true\n          braceStart = i\n          braceNeg = false\n          acc += c\n          continue\n        }\n\n        if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {\n          ast.push(acc)\n          acc = ''\n          const ext = new AST(c, ast)\n          i = AST.#parseAST(str, ext, i, opt)\n          ast.push(ext)\n          continue\n        }\n        acc += c\n      }\n      ast.push(acc)\n      return i\n    }\n\n    // some kind of extglob, pos is at the (\n    // find the next | or )\n    let i = pos + 1\n    let part = new AST(null, ast)\n    const parts: AST[] = []\n    let acc = ''\n    while (i < str.length) {\n      const c = str.charAt(i++)\n      // still accumulate escapes at this point, but we do ignore\n      // starts that are escaped\n      if (escaping || c === '\\\\') {\n        escaping = !escaping\n        acc += c\n        continue\n      }\n\n      if (inBrace) {\n        if (i === braceStart + 1) {\n          if (c === '^' || c === '!') {\n            braceNeg = true\n          }\n        } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n          inBrace = false\n        }\n        acc += c\n        continue\n      } else if (c === '[') {\n        inBrace = true\n        braceStart = i\n        braceNeg = false\n        acc += c\n        continue\n      }\n\n      if (isExtglobType(c) && str.charAt(i) === '(') {\n        part.push(acc)\n        acc = ''\n        const ext = new AST(c, part)\n        part.push(ext)\n        i = AST.#parseAST(str, ext, i, opt)\n        continue\n      }\n      if (c === '|') {\n        part.push(acc)\n        acc = ''\n        parts.push(part)\n        part = new AST(null, ast)\n        continue\n      }\n      if (c === ')') {\n        if (acc === '' && ast.#parts.length === 0) {\n          ast.#emptyExt = true\n        }\n        part.push(acc)\n        acc = ''\n        ast.push(...parts, part)\n        return i\n      }\n      acc += c\n    }\n\n    // unfinished extglob\n    // if we got here, it was a malformed extglob! not an extglob, but\n    // maybe something else in there.\n    ast.type = null\n    ast.#hasMagic = undefined\n    ast.#parts = [str.substring(pos - 1)]\n    return i\n  }\n\n  static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n    const ast = new AST(null, undefined, options)\n    AST.#parseAST(pattern, ast, 0, options)\n    return ast\n  }\n\n  // returns the regular expression if there's magic, or the unescaped\n  // string if not.\n  toMMPattern(): MMRegExp | string {\n    // should only be called on root\n    /* c8 ignore start */\n    if (this !== this.#root) return this.#root.toMMPattern()\n    /* c8 ignore stop */\n    const glob = this.toString()\n    const [re, body, hasMagic, uflag] = this.toRegExpSource()\n    // if we're in nocase mode, and not nocaseMagicOnly, then we do\n    // still need a regular expression if we have to case-insensitively\n    // match capital/lowercase characters.\n    const anyMagic =\n      hasMagic ||\n      this.#hasMagic ||\n      (this.#options.nocase &&\n        !this.#options.nocaseMagicOnly &&\n        glob.toUpperCase() !== glob.toLowerCase())\n    if (!anyMagic) {\n      return body\n    }\n\n    const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '')\n    return Object.assign(new RegExp(`^${re}$`, flags), {\n      _src: re,\n      _glob: glob,\n    })\n  }\n\n  get options() {\n    return this.#options\n  }\n\n  // returns the string match, the regexp source, whether there's magic\n  // in the regexp (so a regular expression is required) and whether or\n  // not the uflag is needed for the regular expression (for posix classes)\n  // TODO: instead of injecting the start/end at this point, just return\n  // the BODY of the regexp, along with the start/end portions suitable\n  // for binding the start/end in either a joined full-path makeRe context\n  // (where we bind to (^|/), or a standalone matchPart context (where\n  // we bind to ^, and not /).  Otherwise slashes get duped!\n  //\n  // In part-matching mode, the start is:\n  // - if not isStart: nothing\n  // - if traversal possible, but not allowed: ^(?!\\.\\.?$)\n  // - if dots allowed or not possible: ^\n  // - if dots possible and not allowed: ^(?!\\.)\n  // end is:\n  // - if not isEnd(): nothing\n  // - else: $\n  //\n  // In full-path matching mode, we put the slash at the START of the\n  // pattern, so start is:\n  // - if first pattern: same as part-matching mode\n  // - if not isStart(): nothing\n  // - if traversal possible, but not allowed: /(?!\\.\\.?(?:$|/))\n  // - if dots allowed or not possible: /\n  // - if dots possible and not allowed: /(?!\\.)\n  // end is:\n  // - if last pattern, same as part-matching mode\n  // - else nothing\n  //\n  // Always put the (?:$|/) on negated tails, though, because that has to be\n  // there to bind the end of the negated pattern portion, and it's easier to\n  // just stick it in now rather than try to inject it later in the middle of\n  // the pattern.\n  //\n  // We can just always return the same end, and leave it up to the caller\n  // to know whether it's going to be used joined or in parts.\n  // And, if the start is adjusted slightly, can do the same there:\n  // - if not isStart: nothing\n  // - if traversal possible, but not allowed: (?:/|^)(?!\\.\\.?$)\n  // - if dots allowed or not possible: (?:/|^)\n  // - if dots possible and not allowed: (?:/|^)(?!\\.)\n  //\n  // But it's better to have a simpler binding without a conditional, for\n  // performance, so probably better to return both start options.\n  //\n  // Then the caller just ignores the end if it's not the first pattern,\n  // and the start always gets applied.\n  //\n  // But that's always going to be $ if it's the ending pattern, or nothing,\n  // so the caller can just attach $ at the end of the pattern when building.\n  //\n  // So the todo is:\n  // - better detect what kind of start is needed\n  // - return both flavors of starting pattern\n  // - attach $ at the end of the pattern when creating the actual RegExp\n  //\n  // Ah, but wait, no, that all only applies to the root when the first pattern\n  // is not an extglob. If the first pattern IS an extglob, then we need all\n  // that dot prevention biz to live in the extglob portions, because eg\n  // +(*|.x*) can match .xy but not .yx.\n  //\n  // So, return the two flavors if it's #root and the first child is not an\n  // AST, otherwise leave it to the child AST to handle it, and there,\n  // use the (?:^|/) style of start binding.\n  //\n  // Even simplified further:\n  // - Since the start for a join is eg /(?!\\.) and the start for a part\n  // is ^(?!\\.), we can just prepend (?!\\.) to the pattern (either root\n  // or start or whatever) and prepend ^ or / at the Regexp construction.\n  toRegExpSource(\n    allowDot?: boolean\n  ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n    const dot = allowDot ?? !!this.#options.dot\n    if (this.#root === this) this.#fillNegs()\n    if (!this.type) {\n      const noEmpty = this.isStart() && this.isEnd()\n      const src = this.#parts\n        .map(p => {\n          const [re, _, hasMagic, uflag] =\n            typeof p === 'string'\n              ? AST.#parseGlob(p, this.#hasMagic, noEmpty)\n              : p.toRegExpSource(allowDot)\n          this.#hasMagic = this.#hasMagic || hasMagic\n          this.#uflag = this.#uflag || uflag\n          return re\n        })\n        .join('')\n\n      let start = ''\n      if (this.isStart()) {\n        if (typeof this.#parts[0] === 'string') {\n          // this is the string that will match the start of the pattern,\n          // so we need to protect against dots and such.\n\n          // '.' and '..' cannot match unless the pattern is that exactly,\n          // even if it starts with . or dot:true is set.\n          const dotTravAllowed =\n            this.#parts.length === 1 && justDots.has(this.#parts[0])\n          if (!dotTravAllowed) {\n            const aps = addPatternStart\n            // check if we have a possibility of matching . or ..,\n            // and prevent that.\n            const needNoTrav =\n              // dots are allowed, and the pattern starts with [ or .\n              (dot && aps.has(src.charAt(0))) ||\n              // the pattern starts with \\., and then [ or .\n              (src.startsWith('\\\\.') && aps.has(src.charAt(2))) ||\n              // the pattern starts with \\.\\., and then [ or .\n              (src.startsWith('\\\\.\\\\.') && aps.has(src.charAt(4)))\n            // no need to prevent dots if it can't match a dot, or if a\n            // sub-pattern will be preventing it anyway.\n            const needNoDot = !dot && !allowDot && aps.has(src.charAt(0))\n\n            start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''\n          }\n        }\n      }\n\n      // append the \"end of path portion\" pattern to negation tails\n      let end = ''\n      if (\n        this.isEnd() &&\n        this.#root.#filledNegs &&\n        this.#parent?.type === '!'\n      ) {\n        end = '(?:$|\\\\/)'\n      }\n      const final = start + src + end\n      return [\n        final,\n        unescape(src),\n        (this.#hasMagic = !!this.#hasMagic),\n        this.#uflag,\n      ]\n    }\n\n    // We need to calculate the body *twice* if it's a repeat pattern\n    // at the start, once in nodot mode, then again in dot mode, so a\n    // pattern like *(?) can match 'x.y'\n\n    const repeated = this.type === '*' || this.type === '+'\n    // some kind of extglob\n    const start = this.type === '!' ? '(?:(?!(?:' : '(?:'\n    let body = this.#partsToRegExp(dot)\n\n    if (this.isStart() && this.isEnd() && !body && this.type !== '!') {\n      // invalid extglob, has to at least be *something* present, if it's\n      // the entire path portion.\n      const s = this.toString()\n      this.#parts = [s]\n      this.type = null\n      this.#hasMagic = undefined\n      return [s, unescape(this.toString()), false, false]\n    }\n\n    // XXX abstract out this map method\n    let bodyDotAllowed =\n      !repeated || allowDot || dot || !startNoDot\n        ? ''\n        : this.#partsToRegExp(true)\n    if (bodyDotAllowed === body) {\n      bodyDotAllowed = ''\n    }\n    if (bodyDotAllowed) {\n      body = `(?:${body})(?:${bodyDotAllowed})*?`\n    }\n\n    // an empty !() is exactly equivalent to a starNoEmpty\n    let final = ''\n    if (this.type === '!' && this.#emptyExt) {\n      final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty\n    } else {\n      const close =\n        this.type === '!'\n          ? // !() must match something,but !(x) can match ''\n            '))' +\n            (this.isStart() && !dot && !allowDot ? startNoDot : '') +\n            star +\n            ')'\n          : this.type === '@'\n          ? ')'\n          : this.type === '?'\n          ? ')?'\n          : this.type === '+' && bodyDotAllowed\n          ? ')'\n          : this.type === '*' && bodyDotAllowed\n          ? `)?`\n          : `)${this.type}`\n      final = start + body + close\n    }\n    return [\n      final,\n      unescape(body),\n      (this.#hasMagic = !!this.#hasMagic),\n      this.#uflag,\n    ]\n  }\n\n  #partsToRegExp(dot: boolean) {\n    return this.#parts\n      .map(p => {\n        // extglob ASTs should only contain parent ASTs\n        /* c8 ignore start */\n        if (typeof p === 'string') {\n          throw new Error('string type in extglob ast??')\n        }\n        /* c8 ignore stop */\n        // can ignore hasMagic, because extglobs are already always magic\n        const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot)\n        this.#uflag = this.#uflag || uflag\n        return re\n      })\n      .filter(p => !(this.isStart() && this.isEnd()) || !!p)\n      .join('|')\n  }\n\n  static #parseGlob(\n    glob: string,\n    hasMagic: boolean | undefined,\n    noEmpty: boolean = false\n  ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n    let escaping = false\n    let re = ''\n    let uflag = false\n    for (let i = 0; i < glob.length; i++) {\n      const c = glob.charAt(i)\n      if (escaping) {\n        escaping = false\n        re += (reSpecials.has(c) ? '\\\\' : '') + c\n        continue\n      }\n      if (c === '\\\\') {\n        if (i === glob.length - 1) {\n          re += '\\\\\\\\'\n        } else {\n          escaping = true\n        }\n        continue\n      }\n      if (c === '[') {\n        const [src, needUflag, consumed, magic] = parseClass(glob, i)\n        if (consumed) {\n          re += src\n          uflag = uflag || needUflag\n          i += consumed - 1\n          hasMagic = hasMagic || magic\n          continue\n        }\n      }\n      if (c === '*') {\n        if (noEmpty && glob === '*') re += starNoEmpty\n        else re += star\n        hasMagic = true\n        continue\n      }\n      if (c === '?') {\n        re += qmark\n        hasMagic = true\n        continue\n      }\n      re += regExpEscape(c)\n    }\n    return [re, unescape(glob), !!hasMagic, uflag]\n  }\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts b/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts
deleted file mode 100644
index b1572deb..00000000
--- a/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export type ParseClassResult = [
-    src: string,
-    uFlag: boolean,
-    consumed: number,
-    hasMagic: boolean
-];
-export declare const parseClass: (glob: string, position: number) => ParseClassResult;
-//# sourceMappingURL=brace-expressions.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map b/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map
deleted file mode 100644
index d3949648..00000000
--- a/backend/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,SACf,MAAM,YACF,MAAM,qBA8HjB,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.js b/backend/node_modules/minimatch/dist/esm/brace-expressions.js
deleted file mode 100644
index c629d6ae..00000000
--- a/backend/node_modules/minimatch/dist/esm/brace-expressions.js
+++ /dev/null
@@ -1,148 +0,0 @@
-// translate the various posix character classes into unicode properties
-// this works across all unicode locales
-// { : [, /u flag required, negated]
-const posixClasses = {
-    '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true],
-    '[:alpha:]': ['\\p{L}\\p{Nl}', true],
-    '[:ascii:]': ['\\x' + '00-\\x' + '7f', false],
-    '[:blank:]': ['\\p{Zs}\\t', true],
-    '[:cntrl:]': ['\\p{Cc}', true],
-    '[:digit:]': ['\\p{Nd}', true],
-    '[:graph:]': ['\\p{Z}\\p{C}', true, true],
-    '[:lower:]': ['\\p{Ll}', true],
-    '[:print:]': ['\\p{C}', true],
-    '[:punct:]': ['\\p{P}', true],
-    '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true],
-    '[:upper:]': ['\\p{Lu}', true],
-    '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true],
-    '[:xdigit:]': ['A-Fa-f0-9', false],
-};
-// only need to escape a few things inside of brace expressions
-// escapes: [ \ ] -
-const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&');
-// escape all regexp magic characters
-const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-// everything has already been escaped, we just have to join
-const rangesToString = (ranges) => ranges.join('');
-// takes a glob string at a posix brace expression, and returns
-// an equivalent regular expression source, and boolean indicating
-// whether the /u flag needs to be applied, and the number of chars
-// consumed to parse the character class.
-// This also removes out of order ranges, and returns ($.) if the
-// entire class just no good.
-export const parseClass = (glob, position) => {
-    const pos = position;
-    /* c8 ignore start */
-    if (glob.charAt(pos) !== '[') {
-        throw new Error('not in a brace expression');
-    }
-    /* c8 ignore stop */
-    const ranges = [];
-    const negs = [];
-    let i = pos + 1;
-    let sawStart = false;
-    let uflag = false;
-    let escaping = false;
-    let negate = false;
-    let endPos = pos;
-    let rangeStart = '';
-    WHILE: while (i < glob.length) {
-        const c = glob.charAt(i);
-        if ((c === '!' || c === '^') && i === pos + 1) {
-            negate = true;
-            i++;
-            continue;
-        }
-        if (c === ']' && sawStart && !escaping) {
-            endPos = i + 1;
-            break;
-        }
-        sawStart = true;
-        if (c === '\\') {
-            if (!escaping) {
-                escaping = true;
-                i++;
-                continue;
-            }
-            // escaped \ char, fall through and treat like normal char
-        }
-        if (c === '[' && !escaping) {
-            // either a posix class, a collation equivalent, or just a [
-            for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
-                if (glob.startsWith(cls, i)) {
-                    // invalid, [a-[] is fine, but not [a-[:alpha]]
-                    if (rangeStart) {
-                        return ['$.', false, glob.length - pos, true];
-                    }
-                    i += cls.length;
-                    if (neg)
-                        negs.push(unip);
-                    else
-                        ranges.push(unip);
-                    uflag = uflag || u;
-                    continue WHILE;
-                }
-            }
-        }
-        // now it's just a normal character, effectively
-        escaping = false;
-        if (rangeStart) {
-            // throw this range away if it's not valid, but others
-            // can still match.
-            if (c > rangeStart) {
-                ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c));
-            }
-            else if (c === rangeStart) {
-                ranges.push(braceEscape(c));
-            }
-            rangeStart = '';
-            i++;
-            continue;
-        }
-        // now might be the start of a range.
-        // can be either c-d or c-] or c] or c] at this point
-        if (glob.startsWith('-]', i + 1)) {
-            ranges.push(braceEscape(c + '-'));
-            i += 2;
-            continue;
-        }
-        if (glob.startsWith('-', i + 1)) {
-            rangeStart = c;
-            i += 2;
-            continue;
-        }
-        // not the start of a range, just a single character
-        ranges.push(braceEscape(c));
-        i++;
-    }
-    if (endPos < i) {
-        // didn't see the end of the class, not a valid class,
-        // but might still be valid as a literal match.
-        return ['', false, 0, false];
-    }
-    // if we got no ranges and no negates, then we have a range that
-    // cannot possibly match anything, and that poisons the whole glob
-    if (!ranges.length && !negs.length) {
-        return ['$.', false, glob.length - pos, true];
-    }
-    // if we got one positive range, and it's a single character, then that's
-    // not actually a magic pattern, it's just that one literal character.
-    // we should not treat that as "magic", we should just return the literal
-    // character. [_] is a perfectly valid way to escape glob magic chars.
-    if (negs.length === 0 &&
-        ranges.length === 1 &&
-        /^\\?.$/.test(ranges[0]) &&
-        !negate) {
-        const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
-        return [regexpEscape(r), false, endPos - pos, false];
-    }
-    const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']';
-    const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']';
-    const comb = ranges.length && negs.length
-        ? '(' + sranges + '|' + snegs + ')'
-        : ranges.length
-            ? sranges
-            : snegs;
-    return [comb, uflag, endPos - pos, true];
-};
-//# sourceMappingURL=brace-expressions.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/brace-expressions.js.map b/backend/node_modules/minimatch/dist/esm/brace-expressions.js.map
deleted file mode 100644
index cdba30da..00000000
--- a/backend/node_modules/minimatch/dist/esm/brace-expressions.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"brace-expressions.js","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"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","sourcesContent":["// translate the various posix character classes into unicode properties\n// this works across all unicode locales\n\n// { : [, /u flag required, negated]\nconst posixClasses: { [k: string]: [e: string, u: boolean, n?: boolean] } = {\n  '[:alnum:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}', true],\n  '[:alpha:]': ['\\\\p{L}\\\\p{Nl}', true],\n  '[:ascii:]': ['\\\\x' + '00-\\\\x' + '7f', false],\n  '[:blank:]': ['\\\\p{Zs}\\\\t', true],\n  '[:cntrl:]': ['\\\\p{Cc}', true],\n  '[:digit:]': ['\\\\p{Nd}', true],\n  '[:graph:]': ['\\\\p{Z}\\\\p{C}', true, true],\n  '[:lower:]': ['\\\\p{Ll}', true],\n  '[:print:]': ['\\\\p{C}', true],\n  '[:punct:]': ['\\\\p{P}', true],\n  '[:space:]': ['\\\\p{Z}\\\\t\\\\r\\\\n\\\\v\\\\f', true],\n  '[:upper:]': ['\\\\p{Lu}', true],\n  '[:word:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}\\\\p{Pc}', true],\n  '[:xdigit:]': ['A-Fa-f0-9', false],\n}\n\n// only need to escape a few things inside of brace expressions\n// escapes: [ \\ ] -\nconst braceEscape = (s: string) => s.replace(/[[\\]\\\\-]/g, '\\\\$&')\n// escape all regexp magic characters\nconst regexpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// everything has already been escaped, we just have to join\nconst rangesToString = (ranges: string[]): string => ranges.join('')\n\nexport type ParseClassResult = [\n  src: string,\n  uFlag: boolean,\n  consumed: number,\n  hasMagic: boolean\n]\n\n// takes a glob string at a posix brace expression, and returns\n// an equivalent regular expression source, and boolean indicating\n// whether the /u flag needs to be applied, and the number of chars\n// consumed to parse the character class.\n// This also removes out of order ranges, and returns ($.) if the\n// entire class just no good.\nexport const parseClass = (\n  glob: string,\n  position: number\n): ParseClassResult => {\n  const pos = position\n  /* c8 ignore start */\n  if (glob.charAt(pos) !== '[') {\n    throw new Error('not in a brace expression')\n  }\n  /* c8 ignore stop */\n  const ranges: string[] = []\n  const negs: string[] = []\n\n  let i = pos + 1\n  let sawStart = false\n  let uflag = false\n  let escaping = false\n  let negate = false\n  let endPos = pos\n  let rangeStart = ''\n  WHILE: while (i < glob.length) {\n    const c = glob.charAt(i)\n    if ((c === '!' || c === '^') && i === pos + 1) {\n      negate = true\n      i++\n      continue\n    }\n\n    if (c === ']' && sawStart && !escaping) {\n      endPos = i + 1\n      break\n    }\n\n    sawStart = true\n    if (c === '\\\\') {\n      if (!escaping) {\n        escaping = true\n        i++\n        continue\n      }\n      // escaped \\ char, fall through and treat like normal char\n    }\n    if (c === '[' && !escaping) {\n      // either a posix class, a collation equivalent, or just a [\n      for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {\n        if (glob.startsWith(cls, i)) {\n          // invalid, [a-[] is fine, but not [a-[:alpha]]\n          if (rangeStart) {\n            return ['$.', false, glob.length - pos, true]\n          }\n          i += cls.length\n          if (neg) negs.push(unip)\n          else ranges.push(unip)\n          uflag = uflag || u\n          continue WHILE\n        }\n      }\n    }\n\n    // now it's just a normal character, effectively\n    escaping = false\n    if (rangeStart) {\n      // throw this range away if it's not valid, but others\n      // can still match.\n      if (c > rangeStart) {\n        ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c))\n      } else if (c === rangeStart) {\n        ranges.push(braceEscape(c))\n      }\n      rangeStart = ''\n      i++\n      continue\n    }\n\n    // now might be the start of a range.\n    // can be either c-d or c-] or c] or c] at this point\n    if (glob.startsWith('-]', i + 1)) {\n      ranges.push(braceEscape(c + '-'))\n      i += 2\n      continue\n    }\n    if (glob.startsWith('-', i + 1)) {\n      rangeStart = c\n      i += 2\n      continue\n    }\n\n    // not the start of a range, just a single character\n    ranges.push(braceEscape(c))\n    i++\n  }\n\n  if (endPos < i) {\n    // didn't see the end of the class, not a valid class,\n    // but might still be valid as a literal match.\n    return ['', false, 0, false]\n  }\n\n  // if we got no ranges and no negates, then we have a range that\n  // cannot possibly match anything, and that poisons the whole glob\n  if (!ranges.length && !negs.length) {\n    return ['$.', false, glob.length - pos, true]\n  }\n\n  // if we got one positive range, and it's a single character, then that's\n  // not actually a magic pattern, it's just that one literal character.\n  // we should not treat that as \"magic\", we should just return the literal\n  // character. [_] is a perfectly valid way to escape glob magic chars.\n  if (\n    negs.length === 0 &&\n    ranges.length === 1 &&\n    /^\\\\?.$/.test(ranges[0]) &&\n    !negate\n  ) {\n    const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]\n    return [regexpEscape(r), false, endPos - pos, false]\n  }\n\n  const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'\n  const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'\n  const comb =\n    ranges.length && negs.length\n      ? '(' + sranges + '|' + snegs + ')'\n      : ranges.length\n      ? sranges\n      : snegs\n\n  return [comb, uflag, endPos - pos, true]\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.d.ts b/backend/node_modules/minimatch/dist/esm/escape.d.ts
deleted file mode 100644
index dc3e3163..00000000
--- a/backend/node_modules/minimatch/dist/esm/escape.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { MinimatchOptions } from './index.js';
-/**
- * Escape all magic characters in a glob pattern.
- *
- * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
- * option is used, then characters are escaped by wrapping in `[]`, because
- * a magic character wrapped in a character class can only be satisfied by
- * that exact character.  In this mode, `\` is _not_ escaped, because it is
- * not interpreted as a magic character, but instead as a path separator.
- */
-export declare const escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
-//# sourceMappingURL=escape.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.d.ts.map b/backend/node_modules/minimatch/dist/esm/escape.d.ts.map
deleted file mode 100644
index 0779dae7..00000000
--- a/backend/node_modules/minimatch/dist/esm/escape.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,MACd,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAQlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.js b/backend/node_modules/minimatch/dist/esm/escape.js
deleted file mode 100644
index 16f7c8c7..00000000
--- a/backend/node_modules/minimatch/dist/esm/escape.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Escape all magic characters in a glob pattern.
- *
- * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
- * option is used, then characters are escaped by wrapping in `[]`, because
- * a magic character wrapped in a character class can only be satisfied by
- * that exact character.  In this mode, `\` is _not_ escaped, because it is
- * not interpreted as a magic character, but instead as a path separator.
- */
-export const escape = (s, { windowsPathsNoEscape = false, } = {}) => {
-    // don't need to escape +@! because we escape the parens
-    // that make those magic, and escaping ! as [!] isn't valid,
-    // because [!]] is a valid glob class meaning not ']'.
-    return windowsPathsNoEscape
-        ? s.replace(/[?*()[\]]/g, '[$&]')
-        : s.replace(/[?*()[\]\\]/g, '\\$&');
-};
-//# sourceMappingURL=escape.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/escape.js.map b/backend/node_modules/minimatch/dist/esm/escape.js.map
deleted file mode 100644
index 170fd1ad..00000000
--- a/backend/node_modules/minimatch/dist/esm/escape.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character.  In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n */\nexport const escape = (\n  s: string,\n  {\n    windowsPathsNoEscape = false,\n  }: Pick = {}\n) => {\n  // don't need to escape +@! because we escape the parens\n  // that make those magic, and escaping ! as [!] isn't valid,\n  // because [!]] is a valid glob class meaning not ']'.\n  return windowsPathsNoEscape\n    ? s.replace(/[?*()[\\]]/g, '[$&]')\n    : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.d.ts b/backend/node_modules/minimatch/dist/esm/index.d.ts
deleted file mode 100644
index 41d16a98..00000000
--- a/backend/node_modules/minimatch/dist/esm/index.d.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { AST } from './ast.js';
-type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd';
-export interface MinimatchOptions {
-    nobrace?: boolean;
-    nocomment?: boolean;
-    nonegate?: boolean;
-    debug?: boolean;
-    noglobstar?: boolean;
-    noext?: boolean;
-    nonull?: boolean;
-    windowsPathsNoEscape?: boolean;
-    allowWindowsEscape?: boolean;
-    partial?: boolean;
-    dot?: boolean;
-    nocase?: boolean;
-    nocaseMagicOnly?: boolean;
-    magicalBraces?: boolean;
-    matchBase?: boolean;
-    flipNegate?: boolean;
-    preserveMultipleSlashes?: boolean;
-    optimizationLevel?: number;
-    platform?: Platform;
-    windowsNoMagicRoot?: boolean;
-}
-export declare const minimatch: {
-    (p: string, pattern: string, options?: MinimatchOptions): boolean;
-    sep: Sep;
-    GLOBSTAR: typeof GLOBSTAR;
-    filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean;
-    defaults: (def: MinimatchOptions) => typeof minimatch;
-    braceExpand: (pattern: string, options?: MinimatchOptions) => string[];
-    makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp;
-    match: (list: string[], pattern: string, options?: MinimatchOptions) => string[];
-    AST: typeof AST;
-    Minimatch: typeof Minimatch;
-    escape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
-    unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
-};
-type Sep = '\\' | '/';
-export declare const sep: Sep;
-export declare const GLOBSTAR: unique symbol;
-export declare const filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean;
-export declare const defaults: (def: MinimatchOptions) => typeof minimatch;
-export declare const braceExpand: (pattern: string, options?: MinimatchOptions) => string[];
-export declare const makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp;
-export declare const match: (list: string[], pattern: string, options?: MinimatchOptions) => string[];
-export type MMRegExp = RegExp & {
-    _src?: string;
-    _glob?: string;
-};
-export type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR;
-export type ParseReturn = ParseReturnFiltered | false;
-export declare class Minimatch {
-    options: MinimatchOptions;
-    set: ParseReturnFiltered[][];
-    pattern: string;
-    windowsPathsNoEscape: boolean;
-    nonegate: boolean;
-    negate: boolean;
-    comment: boolean;
-    empty: boolean;
-    preserveMultipleSlashes: boolean;
-    partial: boolean;
-    globSet: string[];
-    globParts: string[][];
-    nocase: boolean;
-    isWindows: boolean;
-    platform: Platform;
-    windowsNoMagicRoot: boolean;
-    regexp: false | null | MMRegExp;
-    constructor(pattern: string, options?: MinimatchOptions);
-    hasMagic(): boolean;
-    debug(..._: any[]): void;
-    make(): void;
-    preprocess(globParts: string[][]): string[][];
-    adjascentGlobstarOptimize(globParts: string[][]): string[][];
-    levelOneOptimize(globParts: string[][]): string[][];
-    levelTwoFileOptimize(parts: string | string[]): string[];
-    firstPhasePreProcess(globParts: string[][]): string[][];
-    secondPhasePreProcess(globParts: string[][]): string[][];
-    partsMatch(a: string[], b: string[], emptyGSMatch?: boolean): false | string[];
-    parseNegate(): void;
-    matchOne(file: string[], pattern: ParseReturn[], partial?: boolean): boolean;
-    braceExpand(): string[];
-    parse(pattern: string): ParseReturn;
-    makeRe(): false | MMRegExp;
-    slashSplit(p: string): string[];
-    match(f: string, partial?: boolean): boolean;
-    static defaults(def: MinimatchOptions): typeof Minimatch;
-}
-export { AST } from './ast.js';
-export { escape } from './escape.js';
-export { unescape } from './unescape.js';
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.d.ts.map b/backend/node_modules/minimatch/dist/esm/index.d.ts.map
deleted file mode 100644
index 195491d8..00000000
--- a/backend/node_modules/minimatch/dist/esm/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAe,MAAM,UAAU,CAAA;AAI3C,KAAK,QAAQ,GACT,KAAK,GACL,SAAS,GACT,QAAQ,GACR,SAAS,GACT,OAAO,GACP,OAAO,GACP,SAAS,GACT,OAAO,GACP,OAAO,GACP,QAAQ,GACR,QAAQ,CAAA;AAEZ,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,eAAO,MAAM,SAAS;QACjB,MAAM,WACA,MAAM,YACN,gBAAgB;;;sBAuGf,MAAM,YAAW,gBAAgB,SACvC,MAAM;oBAOkB,gBAAgB,KAAG,gBAAgB;2BA6EtD,MAAM,YACN,gBAAgB;sBA2BK,MAAM,YAAW,gBAAgB;kBAKzD,MAAM,EAAE,WACL,MAAM,YACN,gBAAgB;;;;;CArN1B,CAAA;AA+DD,KAAK,GAAG,GAAG,IAAI,GAAG,GAAG,CAAA;AAOrB,eAAO,MAAM,GAAG,KAAgE,CAAA;AAGhF,eAAO,MAAM,QAAQ,eAAwB,CAAA;AAmB7C,eAAO,MAAM,MAAM,YACP,MAAM,YAAW,gBAAgB,SACvC,MAAM,YACsB,CAAA;AAMlC,eAAO,MAAM,QAAQ,QAAS,gBAAgB,KAAG,gBA+DhD,CAAA;AAaD,eAAO,MAAM,WAAW,YACb,MAAM,YACN,gBAAgB,aAY1B,CAAA;AAeD,eAAO,MAAM,MAAM,YAAa,MAAM,YAAW,gBAAgB,qBACvB,CAAA;AAG1C,eAAO,MAAM,KAAK,SACV,MAAM,EAAE,WACL,MAAM,YACN,gBAAgB,aAQ1B,CAAA;AAQD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,QAAQ,CAAA;AACrE,MAAM,MAAM,WAAW,GAAG,mBAAmB,GAAG,KAAK,CAAA;AAErD,qBAAa,SAAS;IACpB,OAAO,EAAE,gBAAgB,CAAA;IACzB,GAAG,EAAE,mBAAmB,EAAE,EAAE,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IAEf,oBAAoB,EAAE,OAAO,CAAA;IAC7B,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,uBAAuB,EAAE,OAAO,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,EAAE,EAAE,CAAA;IACrB,MAAM,EAAE,OAAO,CAAA;IAEf,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;IAClB,kBAAkB,EAAE,OAAO,CAAA;IAE3B,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAA;gBACnB,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAkC3D,QAAQ,IAAI,OAAO;IAYnB,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;IAEjB,IAAI;IA0FJ,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IA8BhC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IAiB/C,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IAoBtC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA6D7C,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IA0F1C,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE;IAkBxD,UAAU,CACR,CAAC,EAAE,MAAM,EAAE,EACX,CAAC,EAAE,MAAM,EAAE,EACX,YAAY,GAAE,OAAe,GAC5B,KAAK,GAAG,MAAM,EAAE;IA+CnB,WAAW;IAqBX,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE,OAAe;IAiNzE,WAAW;IAIX,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IAiDnC,MAAM;IAsFN,UAAU,CAAC,CAAC,EAAE,MAAM;IAepB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,UAAe;IAiEvC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,gBAAgB;CAGtC;AAED,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.js b/backend/node_modules/minimatch/dist/esm/index.js
deleted file mode 100644
index 84b577b0..00000000
--- a/backend/node_modules/minimatch/dist/esm/index.js
+++ /dev/null
@@ -1,1001 +0,0 @@
-import expand from 'brace-expansion';
-import { assertValidPattern } from './assert-valid-pattern.js';
-import { AST } from './ast.js';
-import { escape } from './escape.js';
-import { unescape } from './unescape.js';
-export const minimatch = (p, pattern, options = {}) => {
-    assertValidPattern(pattern);
-    // shortcut: comments match nothing.
-    if (!options.nocomment && pattern.charAt(0) === '#') {
-        return false;
-    }
-    return new Minimatch(pattern, options).match(p);
-};
-// Optimized checking for the most common glob patterns.
-const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
-const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext);
-const starDotExtTestDot = (ext) => (f) => f.endsWith(ext);
-const starDotExtTestNocase = (ext) => {
-    ext = ext.toLowerCase();
-    return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext);
-};
-const starDotExtTestNocaseDot = (ext) => {
-    ext = ext.toLowerCase();
-    return (f) => f.toLowerCase().endsWith(ext);
-};
-const starDotStarRE = /^\*+\.\*+$/;
-const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.');
-const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.');
-const dotStarRE = /^\.\*+$/;
-const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.');
-const starRE = /^\*+$/;
-const starTest = (f) => f.length !== 0 && !f.startsWith('.');
-const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..';
-const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
-const qmarksTestNocase = ([$0, ext = '']) => {
-    const noext = qmarksTestNoExt([$0]);
-    if (!ext)
-        return noext;
-    ext = ext.toLowerCase();
-    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
-};
-const qmarksTestNocaseDot = ([$0, ext = '']) => {
-    const noext = qmarksTestNoExtDot([$0]);
-    if (!ext)
-        return noext;
-    ext = ext.toLowerCase();
-    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
-};
-const qmarksTestDot = ([$0, ext = '']) => {
-    const noext = qmarksTestNoExtDot([$0]);
-    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
-};
-const qmarksTest = ([$0, ext = '']) => {
-    const noext = qmarksTestNoExt([$0]);
-    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
-};
-const qmarksTestNoExt = ([$0]) => {
-    const len = $0.length;
-    return (f) => f.length === len && !f.startsWith('.');
-};
-const qmarksTestNoExtDot = ([$0]) => {
-    const len = $0.length;
-    return (f) => f.length === len && f !== '.' && f !== '..';
-};
-/* c8 ignore start */
-const defaultPlatform = (typeof process === 'object' && process
-    ? (typeof process.env === 'object' &&
-        process.env &&
-        process.env.__MINIMATCH_TESTING_PLATFORM__) ||
-        process.platform
-    : 'posix');
-const path = {
-    win32: { sep: '\\' },
-    posix: { sep: '/' },
-};
-/* c8 ignore stop */
-export const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep;
-minimatch.sep = sep;
-export const GLOBSTAR = Symbol('globstar **');
-minimatch.GLOBSTAR = GLOBSTAR;
-// any single thing other than /
-// don't need to escape / when using new RegExp()
-const qmark = '[^/]';
-// * => any number of characters
-const star = qmark + '*?';
-// ** when dots are allowed.  Anything goes, except .. and .
-// not (^ or / followed by one or two dots followed by $ or /),
-// followed by anything, any number of times.
-const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?';
-// not a ^ or / followed by a dot,
-// followed by anything, any number of times.
-const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?';
-export const filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
-minimatch.filter = filter;
-const ext = (a, b = {}) => Object.assign({}, a, b);
-export const defaults = (def) => {
-    if (!def || typeof def !== 'object' || !Object.keys(def).length) {
-        return minimatch;
-    }
-    const orig = minimatch;
-    const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
-    return Object.assign(m, {
-        Minimatch: class Minimatch extends orig.Minimatch {
-            constructor(pattern, options = {}) {
-                super(pattern, ext(def, options));
-            }
-            static defaults(options) {
-                return orig.defaults(ext(def, options)).Minimatch;
-            }
-        },
-        AST: class AST extends orig.AST {
-            /* c8 ignore start */
-            constructor(type, parent, options = {}) {
-                super(type, parent, ext(def, options));
-            }
-            /* c8 ignore stop */
-            static fromGlob(pattern, options = {}) {
-                return orig.AST.fromGlob(pattern, ext(def, options));
-            }
-        },
-        unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
-        escape: (s, options = {}) => orig.escape(s, ext(def, options)),
-        filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
-        defaults: (options) => orig.defaults(ext(def, options)),
-        makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
-        braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
-        match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
-        sep: orig.sep,
-        GLOBSTAR: GLOBSTAR,
-    });
-};
-minimatch.defaults = defaults;
-// Brace expansion:
-// a{b,c}d -> abd acd
-// a{b,}c -> abc ac
-// a{0..3}d -> a0d a1d a2d a3d
-// a{b,c{d,e}f}g -> abg acdfg acefg
-// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
-//
-// Invalid sets are not expanded.
-// a{2..}b -> a{2..}b
-// a{b}c -> a{b}c
-export const braceExpand = (pattern, options = {}) => {
-    assertValidPattern(pattern);
-    // Thanks to Yeting Li  for
-    // improving this regexp to avoid a ReDOS vulnerability.
-    if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
-        // shortcut. no need to expand.
-        return [pattern];
-    }
-    return expand(pattern);
-};
-minimatch.braceExpand = braceExpand;
-// parse a component of the expanded set.
-// At this point, no pattern may contain "/" in it
-// so we're going to return a 2d array, where each entry is the full
-// pattern, split on '/', and then turned into a regular expression.
-// A regexp is made at the end which joins each array with an
-// escaped /, and another full one which joins each regexp with |.
-//
-// Following the lead of Bash 4.1, note that "**" only has special meaning
-// when it is the *only* thing in a path portion.  Otherwise, any series
-// of * is equivalent to a single *.  Globstar behavior is enabled by
-// default, and can be disabled by setting options.noglobstar.
-export const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
-minimatch.makeRe = makeRe;
-export const match = (list, pattern, options = {}) => {
-    const mm = new Minimatch(pattern, options);
-    list = list.filter(f => mm.match(f));
-    if (mm.options.nonull && !list.length) {
-        list.push(pattern);
-    }
-    return list;
-};
-minimatch.match = match;
-// replace stuff like \* with *
-const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
-const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-export class Minimatch {
-    options;
-    set;
-    pattern;
-    windowsPathsNoEscape;
-    nonegate;
-    negate;
-    comment;
-    empty;
-    preserveMultipleSlashes;
-    partial;
-    globSet;
-    globParts;
-    nocase;
-    isWindows;
-    platform;
-    windowsNoMagicRoot;
-    regexp;
-    constructor(pattern, options = {}) {
-        assertValidPattern(pattern);
-        options = options || {};
-        this.options = options;
-        this.pattern = pattern;
-        this.platform = options.platform || defaultPlatform;
-        this.isWindows = this.platform === 'win32';
-        this.windowsPathsNoEscape =
-            !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
-        if (this.windowsPathsNoEscape) {
-            this.pattern = this.pattern.replace(/\\/g, '/');
-        }
-        this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
-        this.regexp = null;
-        this.negate = false;
-        this.nonegate = !!options.nonegate;
-        this.comment = false;
-        this.empty = false;
-        this.partial = !!options.partial;
-        this.nocase = !!this.options.nocase;
-        this.windowsNoMagicRoot =
-            options.windowsNoMagicRoot !== undefined
-                ? options.windowsNoMagicRoot
-                : !!(this.isWindows && this.nocase);
-        this.globSet = [];
-        this.globParts = [];
-        this.set = [];
-        // make the set of regexps etc.
-        this.make();
-    }
-    hasMagic() {
-        if (this.options.magicalBraces && this.set.length > 1) {
-            return true;
-        }
-        for (const pattern of this.set) {
-            for (const part of pattern) {
-                if (typeof part !== 'string')
-                    return true;
-            }
-        }
-        return false;
-    }
-    debug(..._) { }
-    make() {
-        const pattern = this.pattern;
-        const options = this.options;
-        // empty patterns and comments match nothing.
-        if (!options.nocomment && pattern.charAt(0) === '#') {
-            this.comment = true;
-            return;
-        }
-        if (!pattern) {
-            this.empty = true;
-            return;
-        }
-        // step 1: figure out negation, etc.
-        this.parseNegate();
-        // step 2: expand braces
-        this.globSet = [...new Set(this.braceExpand())];
-        if (options.debug) {
-            this.debug = (...args) => console.error(...args);
-        }
-        this.debug(this.pattern, this.globSet);
-        // step 3: now we have a set, so turn each one into a series of
-        // path-portion matching patterns.
-        // These will be regexps, except in the case of "**", which is
-        // set to the GLOBSTAR object for globstar behavior,
-        // and will not contain any / characters
-        //
-        // First, we preprocess to make the glob pattern sets a bit simpler
-        // and deduped.  There are some perf-killing patterns that can cause
-        // problems with a glob walk, but we can simplify them down a bit.
-        const rawGlobParts = this.globSet.map(s => this.slashSplit(s));
-        this.globParts = this.preprocess(rawGlobParts);
-        this.debug(this.pattern, this.globParts);
-        // glob --> regexps
-        let set = this.globParts.map((s, _, __) => {
-            if (this.isWindows && this.windowsNoMagicRoot) {
-                // check if it's a drive or unc path.
-                const isUNC = s[0] === '' &&
-                    s[1] === '' &&
-                    (s[2] === '?' || !globMagic.test(s[2])) &&
-                    !globMagic.test(s[3]);
-                const isDrive = /^[a-z]:/i.test(s[0]);
-                if (isUNC) {
-                    return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))];
-                }
-                else if (isDrive) {
-                    return [s[0], ...s.slice(1).map(ss => this.parse(ss))];
-                }
-            }
-            return s.map(ss => this.parse(ss));
-        });
-        this.debug(this.pattern, set);
-        // filter out everything that didn't compile properly.
-        this.set = set.filter(s => s.indexOf(false) === -1);
-        // do not treat the ? in UNC paths as magic
-        if (this.isWindows) {
-            for (let i = 0; i < this.set.length; i++) {
-                const p = this.set[i];
-                if (p[0] === '' &&
-                    p[1] === '' &&
-                    this.globParts[i][2] === '?' &&
-                    typeof p[3] === 'string' &&
-                    /^[a-z]:$/i.test(p[3])) {
-                    p[2] = '?';
-                }
-            }
-        }
-        this.debug(this.pattern, this.set);
-    }
-    // various transforms to equivalent pattern sets that are
-    // faster to process in a filesystem walk.  The goal is to
-    // eliminate what we can, and push all ** patterns as far
-    // to the right as possible, even if it increases the number
-    // of patterns that we have to process.
-    preprocess(globParts) {
-        // if we're not in globstar mode, then turn all ** into *
-        if (this.options.noglobstar) {
-            for (let i = 0; i < globParts.length; i++) {
-                for (let j = 0; j < globParts[i].length; j++) {
-                    if (globParts[i][j] === '**') {
-                        globParts[i][j] = '*';
-                    }
-                }
-            }
-        }
-        const { optimizationLevel = 1 } = this.options;
-        if (optimizationLevel >= 2) {
-            // aggressive optimization for the purpose of fs walking
-            globParts = this.firstPhasePreProcess(globParts);
-            globParts = this.secondPhasePreProcess(globParts);
-        }
-        else if (optimizationLevel >= 1) {
-            // just basic optimizations to remove some .. parts
-            globParts = this.levelOneOptimize(globParts);
-        }
-        else {
-            // just collapse multiple ** portions into one
-            globParts = this.adjascentGlobstarOptimize(globParts);
-        }
-        return globParts;
-    }
-    // just get rid of adjascent ** portions
-    adjascentGlobstarOptimize(globParts) {
-        return globParts.map(parts => {
-            let gs = -1;
-            while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
-                let i = gs;
-                while (parts[i + 1] === '**') {
-                    i++;
-                }
-                if (i !== gs) {
-                    parts.splice(gs, i - gs);
-                }
-            }
-            return parts;
-        });
-    }
-    // get rid of adjascent ** and resolve .. portions
-    levelOneOptimize(globParts) {
-        return globParts.map(parts => {
-            parts = parts.reduce((set, part) => {
-                const prev = set[set.length - 1];
-                if (part === '**' && prev === '**') {
-                    return set;
-                }
-                if (part === '..') {
-                    if (prev && prev !== '..' && prev !== '.' && prev !== '**') {
-                        set.pop();
-                        return set;
-                    }
-                }
-                set.push(part);
-                return set;
-            }, []);
-            return parts.length === 0 ? [''] : parts;
-        });
-    }
-    levelTwoFileOptimize(parts) {
-        if (!Array.isArray(parts)) {
-            parts = this.slashSplit(parts);
-        }
-        let didSomething = false;
-        do {
-            didSomething = false;
-            // 
// -> 
/
-            if (!this.preserveMultipleSlashes) {
-                for (let i = 1; i < parts.length - 1; i++) {
-                    const p = parts[i];
-                    // don't squeeze out UNC patterns
-                    if (i === 1 && p === '' && parts[0] === '')
-                        continue;
-                    if (p === '.' || p === '') {
-                        didSomething = true;
-                        parts.splice(i, 1);
-                        i--;
-                    }
-                }
-                if (parts[0] === '.' &&
-                    parts.length === 2 &&
-                    (parts[1] === '.' || parts[1] === '')) {
-                    didSomething = true;
-                    parts.pop();
-                }
-            }
-            // 
/

/../ ->

/
-            let dd = 0;
-            while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
-                const p = parts[dd - 1];
-                if (p && p !== '.' && p !== '..' && p !== '**') {
-                    didSomething = true;
-                    parts.splice(dd - 1, 2);
-                    dd -= 2;
-                }
-            }
-        } while (didSomething);
-        return parts.length === 0 ? [''] : parts;
-    }
-    // First phase: single-pattern processing
-    // 
 is 1 or more portions
-    //  is 1 or more portions
-    // 

is any portion other than ., .., '', or ** - // is . or '' - // - // **/.. is *brutal* for filesystem walking performance, because - // it effectively resets the recursive walk each time it occurs, - // and ** cannot be reduced out by a .. pattern part like a regexp - // or most strings (other than .., ., and '') can be. - // - //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/} - //

// -> 
/
-    // 
/

/../ ->

/
-    // **/**/ -> **/
-    //
-    // **/*/ -> */**/ <== not valid because ** doesn't follow
-    // this WOULD be allowed if ** did follow symlinks, or * didn't
-    firstPhasePreProcess(globParts) {
-        let didSomething = false;
-        do {
-            didSomething = false;
-            // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/} - for (let parts of globParts) { - let gs = -1; - while (-1 !== (gs = parts.indexOf('**', gs + 1))) { - let gss = gs; - while (parts[gss + 1] === '**') { - //

/**/**/ -> 
/**/
-                        gss++;
-                    }
-                    // eg, if gs is 2 and gss is 4, that means we have 3 **
-                    // parts, and can remove 2 of them.
-                    if (gss > gs) {
-                        parts.splice(gs + 1, gss - gs);
-                    }
-                    let next = parts[gs + 1];
-                    const p = parts[gs + 2];
-                    const p2 = parts[gs + 3];
-                    if (next !== '..')
-                        continue;
-                    if (!p ||
-                        p === '.' ||
-                        p === '..' ||
-                        !p2 ||
-                        p2 === '.' ||
-                        p2 === '..') {
-                        continue;
-                    }
-                    didSomething = true;
-                    // edit parts in place, and push the new one
-                    parts.splice(gs, 1);
-                    const other = parts.slice(0);
-                    other[gs] = '**';
-                    globParts.push(other);
-                    gs--;
-                }
-                // 
// -> 
/
-                if (!this.preserveMultipleSlashes) {
-                    for (let i = 1; i < parts.length - 1; i++) {
-                        const p = parts[i];
-                        // don't squeeze out UNC patterns
-                        if (i === 1 && p === '' && parts[0] === '')
-                            continue;
-                        if (p === '.' || p === '') {
-                            didSomething = true;
-                            parts.splice(i, 1);
-                            i--;
-                        }
-                    }
-                    if (parts[0] === '.' &&
-                        parts.length === 2 &&
-                        (parts[1] === '.' || parts[1] === '')) {
-                        didSomething = true;
-                        parts.pop();
-                    }
-                }
-                // 
/

/../ ->

/
-                let dd = 0;
-                while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
-                    const p = parts[dd - 1];
-                    if (p && p !== '.' && p !== '..' && p !== '**') {
-                        didSomething = true;
-                        const needDot = dd === 1 && parts[dd + 1] === '**';
-                        const splin = needDot ? ['.'] : [];
-                        parts.splice(dd - 1, 2, ...splin);
-                        if (parts.length === 0)
-                            parts.push('');
-                        dd -= 2;
-                    }
-                }
-            }
-        } while (didSomething);
-        return globParts;
-    }
-    // second phase: multi-pattern dedupes
-    // {
/*/,
/

/} ->

/*/
-    // {
/,
/} -> 
/
-    // {
/**/,
/} -> 
/**/
-    //
-    // {
/**/,
/**/

/} ->

/**/
-    // ^-- not valid because ** doens't follow symlinks
-    secondPhasePreProcess(globParts) {
-        for (let i = 0; i < globParts.length - 1; i++) {
-            for (let j = i + 1; j < globParts.length; j++) {
-                const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
-                if (matched) {
-                    globParts[i] = [];
-                    globParts[j] = matched;
-                    break;
-                }
-            }
-        }
-        return globParts.filter(gs => gs.length);
-    }
-    partsMatch(a, b, emptyGSMatch = false) {
-        let ai = 0;
-        let bi = 0;
-        let result = [];
-        let which = '';
-        while (ai < a.length && bi < b.length) {
-            if (a[ai] === b[bi]) {
-                result.push(which === 'b' ? b[bi] : a[ai]);
-                ai++;
-                bi++;
-            }
-            else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
-                result.push(a[ai]);
-                ai++;
-            }
-            else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
-                result.push(b[bi]);
-                bi++;
-            }
-            else if (a[ai] === '*' &&
-                b[bi] &&
-                (this.options.dot || !b[bi].startsWith('.')) &&
-                b[bi] !== '**') {
-                if (which === 'b')
-                    return false;
-                which = 'a';
-                result.push(a[ai]);
-                ai++;
-                bi++;
-            }
-            else if (b[bi] === '*' &&
-                a[ai] &&
-                (this.options.dot || !a[ai].startsWith('.')) &&
-                a[ai] !== '**') {
-                if (which === 'a')
-                    return false;
-                which = 'b';
-                result.push(b[bi]);
-                ai++;
-                bi++;
-            }
-            else {
-                return false;
-            }
-        }
-        // if we fall out of the loop, it means they two are identical
-        // as long as their lengths match
-        return a.length === b.length && result;
-    }
-    parseNegate() {
-        if (this.nonegate)
-            return;
-        const pattern = this.pattern;
-        let negate = false;
-        let negateOffset = 0;
-        for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
-            negate = !negate;
-            negateOffset++;
-        }
-        if (negateOffset)
-            this.pattern = pattern.slice(negateOffset);
-        this.negate = negate;
-    }
-    // set partial to true to test if, for example,
-    // "/a/b" matches the start of "/*/b/*/d"
-    // Partial means, if you run out of file before you run
-    // out of pattern, then that's fine, as long as all
-    // the parts match.
-    matchOne(file, pattern, partial = false) {
-        const options = this.options;
-        // UNC paths like //?/X:/... can match X:/... and vice versa
-        // Drive letters in absolute drive or unc paths are always compared
-        // case-insensitively.
-        if (this.isWindows) {
-            const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
-            const fileUNC = !fileDrive &&
-                file[0] === '' &&
-                file[1] === '' &&
-                file[2] === '?' &&
-                /^[a-z]:$/i.test(file[3]);
-            const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
-            const patternUNC = !patternDrive &&
-                pattern[0] === '' &&
-                pattern[1] === '' &&
-                pattern[2] === '?' &&
-                typeof pattern[3] === 'string' &&
-                /^[a-z]:$/i.test(pattern[3]);
-            const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
-            const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
-            if (typeof fdi === 'number' && typeof pdi === 'number') {
-                const [fd, pd] = [file[fdi], pattern[pdi]];
-                if (fd.toLowerCase() === pd.toLowerCase()) {
-                    pattern[pdi] = fd;
-                    if (pdi > fdi) {
-                        pattern = pattern.slice(pdi);
-                    }
-                    else if (fdi > pdi) {
-                        file = file.slice(fdi);
-                    }
-                }
-            }
-        }
-        // resolve and reduce . and .. portions in the file as well.
-        // dont' need to do the second phase, because it's only one string[]
-        const { optimizationLevel = 1 } = this.options;
-        if (optimizationLevel >= 2) {
-            file = this.levelTwoFileOptimize(file);
-        }
-        this.debug('matchOne', this, { file, pattern });
-        this.debug('matchOne', file.length, pattern.length);
-        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
-            this.debug('matchOne loop');
-            var p = pattern[pi];
-            var f = file[fi];
-            this.debug(pattern, p, f);
-            // should be impossible.
-            // some invalid regexp stuff in the set.
-            /* c8 ignore start */
-            if (p === false) {
-                return false;
-            }
-            /* c8 ignore stop */
-            if (p === GLOBSTAR) {
-                this.debug('GLOBSTAR', [pattern, p, f]);
-                // "**"
-                // a/**/b/**/c would match the following:
-                // a/b/x/y/z/c
-                // a/x/y/z/b/c
-                // a/b/x/b/x/c
-                // a/b/c
-                // To do this, take the rest of the pattern after
-                // the **, and see if it would match the file remainder.
-                // If so, return success.
-                // If not, the ** "swallows" a segment, and try again.
-                // This is recursively awful.
-                //
-                // a/**/b/**/c matching a/b/x/y/z/c
-                // - a matches a
-                // - doublestar
-                //   - matchOne(b/x/y/z/c, b/**/c)
-                //     - b matches b
-                //     - doublestar
-                //       - matchOne(x/y/z/c, c) -> no
-                //       - matchOne(y/z/c, c) -> no
-                //       - matchOne(z/c, c) -> no
-                //       - matchOne(c, c) yes, hit
-                var fr = fi;
-                var pr = pi + 1;
-                if (pr === pl) {
-                    this.debug('** at the end');
-                    // a ** at the end will just swallow the rest.
-                    // We have found a match.
-                    // however, it will not swallow /.x, unless
-                    // options.dot is set.
-                    // . and .. are *never* matched by **, for explosively
-                    // exponential reasons.
-                    for (; fi < fl; fi++) {
-                        if (file[fi] === '.' ||
-                            file[fi] === '..' ||
-                            (!options.dot && file[fi].charAt(0) === '.'))
-                            return false;
-                    }
-                    return true;
-                }
-                // ok, let's see if we can swallow whatever we can.
-                while (fr < fl) {
-                    var swallowee = file[fr];
-                    this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
-                    // XXX remove this slice.  Just pass the start index.
-                    if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
-                        this.debug('globstar found match!', fr, fl, swallowee);
-                        // found a match.
-                        return true;
-                    }
-                    else {
-                        // can't swallow "." or ".." ever.
-                        // can only swallow ".foo" when explicitly asked.
-                        if (swallowee === '.' ||
-                            swallowee === '..' ||
-                            (!options.dot && swallowee.charAt(0) === '.')) {
-                            this.debug('dot detected!', file, fr, pattern, pr);
-                            break;
-                        }
-                        // ** swallows a segment, and continue.
-                        this.debug('globstar swallow a segment, and continue');
-                        fr++;
-                    }
-                }
-                // no match was found.
-                // However, in partial mode, we can't say this is necessarily over.
-                /* c8 ignore start */
-                if (partial) {
-                    // ran out of file
-                    this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
-                    if (fr === fl) {
-                        return true;
-                    }
-                }
-                /* c8 ignore stop */
-                return false;
-            }
-            // something other than **
-            // non-magic patterns just have to match exactly
-            // patterns with magic have been turned into regexps.
-            let hit;
-            if (typeof p === 'string') {
-                hit = f === p;
-                this.debug('string match', p, f, hit);
-            }
-            else {
-                hit = p.test(f);
-                this.debug('pattern match', p, f, hit);
-            }
-            if (!hit)
-                return false;
-        }
-        // Note: ending in / means that we'll get a final ""
-        // at the end of the pattern.  This can only match a
-        // corresponding "" at the end of the file.
-        // If the file ends in /, then it can only match a
-        // a pattern that ends in /, unless the pattern just
-        // doesn't have any more for it. But, a/b/ should *not*
-        // match "a/b/*", even though "" matches against the
-        // [^/]*? pattern, except in partial mode, where it might
-        // simply not be reached yet.
-        // However, a/b/ should still satisfy a/*
-        // now either we fell off the end of the pattern, or we're done.
-        if (fi === fl && pi === pl) {
-            // ran out of pattern and filename at the same time.
-            // an exact hit!
-            return true;
-        }
-        else if (fi === fl) {
-            // ran out of file, but still had pattern left.
-            // this is ok if we're doing the match as part of
-            // a glob fs traversal.
-            return partial;
-        }
-        else if (pi === pl) {
-            // ran out of pattern, still have file left.
-            // this is only acceptable if we're on the very last
-            // empty segment of a file with a trailing slash.
-            // a/* should match a/b/
-            return fi === fl - 1 && file[fi] === '';
-            /* c8 ignore start */
-        }
-        else {
-            // should be unreachable.
-            throw new Error('wtf?');
-        }
-        /* c8 ignore stop */
-    }
-    braceExpand() {
-        return braceExpand(this.pattern, this.options);
-    }
-    parse(pattern) {
-        assertValidPattern(pattern);
-        const options = this.options;
-        // shortcuts
-        if (pattern === '**')
-            return GLOBSTAR;
-        if (pattern === '')
-            return '';
-        // far and away, the most common glob pattern parts are
-        // *, *.*, and *.  Add a fast check method for those.
-        let m;
-        let fastTest = null;
-        if ((m = pattern.match(starRE))) {
-            fastTest = options.dot ? starTestDot : starTest;
-        }
-        else if ((m = pattern.match(starDotExtRE))) {
-            fastTest = (options.nocase
-                ? options.dot
-                    ? starDotExtTestNocaseDot
-                    : starDotExtTestNocase
-                : options.dot
-                    ? starDotExtTestDot
-                    : starDotExtTest)(m[1]);
-        }
-        else if ((m = pattern.match(qmarksRE))) {
-            fastTest = (options.nocase
-                ? options.dot
-                    ? qmarksTestNocaseDot
-                    : qmarksTestNocase
-                : options.dot
-                    ? qmarksTestDot
-                    : qmarksTest)(m);
-        }
-        else if ((m = pattern.match(starDotStarRE))) {
-            fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
-        }
-        else if ((m = pattern.match(dotStarRE))) {
-            fastTest = dotStarTest;
-        }
-        const re = AST.fromGlob(pattern, this.options).toMMPattern();
-        if (fastTest && typeof re === 'object') {
-            // Avoids overriding in frozen environments
-            Reflect.defineProperty(re, 'test', { value: fastTest });
-        }
-        return re;
-    }
-    makeRe() {
-        if (this.regexp || this.regexp === false)
-            return this.regexp;
-        // at this point, this.set is a 2d array of partial
-        // pattern strings, or "**".
-        //
-        // It's better to use .match().  This function shouldn't
-        // be used, really, but it's pretty convenient sometimes,
-        // when you just want to work with a regex.
-        const set = this.set;
-        if (!set.length) {
-            this.regexp = false;
-            return this.regexp;
-        }
-        const options = this.options;
-        const twoStar = options.noglobstar
-            ? star
-            : options.dot
-                ? twoStarDot
-                : twoStarNoDot;
-        const flags = new Set(options.nocase ? ['i'] : []);
-        // regexpify non-globstar patterns
-        // if ** is only item, then we just do one twoStar
-        // if ** is first, and there are more, prepend (\/|twoStar\/)? to next
-        // if ** is last, append (\/twoStar|) to previous
-        // if ** is in the middle, append (\/|\/twoStar\/) to previous
-        // then filter out GLOBSTAR symbols
-        let re = set
-            .map(pattern => {
-            const pp = pattern.map(p => {
-                if (p instanceof RegExp) {
-                    for (const f of p.flags.split(''))
-                        flags.add(f);
-                }
-                return typeof p === 'string'
-                    ? regExpEscape(p)
-                    : p === GLOBSTAR
-                        ? GLOBSTAR
-                        : p._src;
-            });
-            pp.forEach((p, i) => {
-                const next = pp[i + 1];
-                const prev = pp[i - 1];
-                if (p !== GLOBSTAR || prev === GLOBSTAR) {
-                    return;
-                }
-                if (prev === undefined) {
-                    if (next !== undefined && next !== GLOBSTAR) {
-                        pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next;
-                    }
-                    else {
-                        pp[i] = twoStar;
-                    }
-                }
-                else if (next === undefined) {
-                    pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
-                }
-                else if (next !== GLOBSTAR) {
-                    pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
-                    pp[i + 1] = GLOBSTAR;
-                }
-            });
-            return pp.filter(p => p !== GLOBSTAR).join('/');
-        })
-            .join('|');
-        // need to wrap in parens if we had more than one thing with |,
-        // otherwise only the first will be anchored to ^ and the last to $
-        const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
-        // must match entire pattern
-        // ending in a * or ** will make it less strict.
-        re = '^' + open + re + close + '$';
-        // can match anything, as long as it's not this.
-        if (this.negate)
-            re = '^(?!' + re + ').+$';
-        try {
-            this.regexp = new RegExp(re, [...flags].join(''));
-            /* c8 ignore start */
-        }
-        catch (ex) {
-            // should be impossible
-            this.regexp = false;
-        }
-        /* c8 ignore stop */
-        return this.regexp;
-    }
-    slashSplit(p) {
-        // if p starts with // on windows, we preserve that
-        // so that UNC paths aren't broken.  Otherwise, any number of
-        // / characters are coalesced into one, unless
-        // preserveMultipleSlashes is set to true.
-        if (this.preserveMultipleSlashes) {
-            return p.split('/');
-        }
-        else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
-            // add an extra '' for the one we lose
-            return ['', ...p.split(/\/+/)];
-        }
-        else {
-            return p.split(/\/+/);
-        }
-    }
-    match(f, partial = this.partial) {
-        this.debug('match', f, this.pattern);
-        // short-circuit in the case of busted things.
-        // comments, etc.
-        if (this.comment) {
-            return false;
-        }
-        if (this.empty) {
-            return f === '';
-        }
-        if (f === '/' && partial) {
-            return true;
-        }
-        const options = this.options;
-        // windows: need to use /, not \
-        if (this.isWindows) {
-            f = f.split('\\').join('/');
-        }
-        // treat the test path as a set of pathparts.
-        const ff = this.slashSplit(f);
-        this.debug(this.pattern, 'split', ff);
-        // just ONE of the pattern sets in this.set needs to match
-        // in order for it to be valid.  If negating, then just one
-        // match means that we have failed.
-        // Either way, return on the first hit.
-        const set = this.set;
-        this.debug(this.pattern, 'set', set);
-        // Find the basename of the path by looking for the last non-empty segment
-        let filename = ff[ff.length - 1];
-        if (!filename) {
-            for (let i = ff.length - 2; !filename && i >= 0; i--) {
-                filename = ff[i];
-            }
-        }
-        for (let i = 0; i < set.length; i++) {
-            const pattern = set[i];
-            let file = ff;
-            if (options.matchBase && pattern.length === 1) {
-                file = [filename];
-            }
-            const hit = this.matchOne(file, pattern, partial);
-            if (hit) {
-                if (options.flipNegate) {
-                    return true;
-                }
-                return !this.negate;
-            }
-        }
-        // didn't get any hits.  this is success if it's a negative
-        // pattern, failure otherwise.
-        if (options.flipNegate) {
-            return false;
-        }
-        return this.negate;
-    }
-    static defaults(def) {
-        return minimatch.defaults(def).Minimatch;
-    }
-}
-/* c8 ignore start */
-export { AST } from './ast.js';
-export { escape } from './escape.js';
-export { unescape } from './unescape.js';
-/* c8 ignore stop */
-minimatch.AST = AST;
-minimatch.Minimatch = Minimatch;
-minimatch.escape = escape;
-minimatch.unescape = unescape;
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/index.js.map b/backend/node_modules/minimatch/dist/esm/index.js.map
deleted file mode 100644
index ff82a0d3..00000000
--- a/backend/node_modules/minimatch/dist/esm/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import expand from 'brace-expansion'\nimport { assertValidPattern } from './assert-valid-pattern.js'\nimport { AST, ExtglobType } from './ast.js'\nimport { escape } from './escape.js'\nimport { unescape } from './unescape.js'\n\ntype Platform =\n  | 'aix'\n  | 'android'\n  | 'darwin'\n  | 'freebsd'\n  | 'haiku'\n  | 'linux'\n  | 'openbsd'\n  | 'sunos'\n  | 'win32'\n  | 'cygwin'\n  | 'netbsd'\n\nexport interface MinimatchOptions {\n  nobrace?: boolean\n  nocomment?: boolean\n  nonegate?: boolean\n  debug?: boolean\n  noglobstar?: boolean\n  noext?: boolean\n  nonull?: boolean\n  windowsPathsNoEscape?: boolean\n  allowWindowsEscape?: boolean\n  partial?: boolean\n  dot?: boolean\n  nocase?: boolean\n  nocaseMagicOnly?: boolean\n  magicalBraces?: boolean\n  matchBase?: boolean\n  flipNegate?: boolean\n  preserveMultipleSlashes?: boolean\n  optimizationLevel?: number\n  platform?: Platform\n  windowsNoMagicRoot?: boolean\n}\n\nexport const minimatch = (\n  p: string,\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // shortcut: comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    return false\n  }\n\n  return new Minimatch(pattern, options).match(p)\n}\n\n// Optimized checking for the most common glob patterns.\nconst starDotExtRE = /^\\*+([^+@!?\\*\\[\\(]*)$/\nconst starDotExtTest = (ext: string) => (f: string) =>\n  !f.startsWith('.') && f.endsWith(ext)\nconst starDotExtTestDot = (ext: string) => (f: string) => f.endsWith(ext)\nconst starDotExtTestNocase = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => !f.startsWith('.') && f.toLowerCase().endsWith(ext)\n}\nconst starDotExtTestNocaseDot = (ext: string) => {\n  ext = ext.toLowerCase()\n  return (f: string) => f.toLowerCase().endsWith(ext)\n}\nconst starDotStarRE = /^\\*+\\.\\*+$/\nconst starDotStarTest = (f: string) => !f.startsWith('.') && f.includes('.')\nconst starDotStarTestDot = (f: string) =>\n  f !== '.' && f !== '..' && f.includes('.')\nconst dotStarRE = /^\\.\\*+$/\nconst dotStarTest = (f: string) => f !== '.' && f !== '..' && f.startsWith('.')\nconst starRE = /^\\*+$/\nconst starTest = (f: string) => f.length !== 0 && !f.startsWith('.')\nconst starTestDot = (f: string) => f.length !== 0 && f !== '.' && f !== '..'\nconst qmarksRE = /^\\?+([^+@!?\\*\\[\\(]*)?$/\nconst qmarksTestNocase = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestNocaseDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  if (!ext) return noext\n  ext = ext.toLowerCase()\n  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestDot = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExtDot([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTest = ([$0, ext = '']: RegExpMatchArray) => {\n  const noext = qmarksTestNoExt([$0])\n  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTestNoExt = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && !f.startsWith('.')\n}\nconst qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {\n  const len = $0.length\n  return (f: string) => f.length === len && f !== '.' && f !== '..'\n}\n\n/* c8 ignore start */\nconst defaultPlatform: Platform = (\n  typeof process === 'object' && process\n    ? (typeof process.env === 'object' &&\n        process.env &&\n        process.env.__MINIMATCH_TESTING_PLATFORM__) ||\n      process.platform\n    : 'posix'\n) as Platform\ntype Sep = '\\\\' | '/'\nconst path: { [k: string]: { sep: Sep } } = {\n  win32: { sep: '\\\\' },\n  posix: { sep: '/' },\n}\n/* c8 ignore stop */\n\nexport const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep\nminimatch.sep = sep\n\nexport const GLOBSTAR = Symbol('globstar **')\nminimatch.GLOBSTAR = GLOBSTAR\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n\n// ** when dots are allowed.  Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nconst twoStarDot = '(?:(?!(?:\\\\/|^)(?:\\\\.{1,2})($|\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nconst twoStarNoDot = '(?:(?!(?:\\\\/|^)\\\\.).)*?'\n\nexport const filter =\n  (pattern: string, options: MinimatchOptions = {}) =>\n  (p: string) =>\n    minimatch(p, pattern, options)\nminimatch.filter = filter\n\nconst ext = (a: MinimatchOptions, b: MinimatchOptions = {}) =>\n  Object.assign({}, a, b)\n\nexport const defaults = (def: MinimatchOptions): typeof minimatch => {\n  if (!def || typeof def !== 'object' || !Object.keys(def).length) {\n    return minimatch\n  }\n\n  const orig = minimatch\n\n  const m = (p: string, pattern: string, options: MinimatchOptions = {}) =>\n    orig(p, pattern, ext(def, options))\n\n  return Object.assign(m, {\n    Minimatch: class Minimatch extends orig.Minimatch {\n      constructor(pattern: string, options: MinimatchOptions = {}) {\n        super(pattern, ext(def, options))\n      }\n      static defaults(options: MinimatchOptions) {\n        return orig.defaults(ext(def, options)).Minimatch\n      }\n    },\n\n    AST: class AST extends orig.AST {\n      /* c8 ignore start */\n      constructor(\n        type: ExtglobType | null,\n        parent?: AST,\n        options: MinimatchOptions = {}\n      ) {\n        super(type, parent, ext(def, options))\n      }\n      /* c8 ignore stop */\n\n      static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n        return orig.AST.fromGlob(pattern, ext(def, options))\n      }\n    },\n\n    unescape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.unescape(s, ext(def, options)),\n\n    escape: (\n      s: string,\n      options: Pick = {}\n    ) => orig.escape(s, ext(def, options)),\n\n    filter: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.filter(pattern, ext(def, options)),\n\n    defaults: (options: MinimatchOptions) => orig.defaults(ext(def, options)),\n\n    makeRe: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.makeRe(pattern, ext(def, options)),\n\n    braceExpand: (pattern: string, options: MinimatchOptions = {}) =>\n      orig.braceExpand(pattern, ext(def, options)),\n\n    match: (list: string[], pattern: string, options: MinimatchOptions = {}) =>\n      orig.match(list, pattern, ext(def, options)),\n\n    sep: orig.sep,\n    GLOBSTAR: GLOBSTAR as typeof GLOBSTAR,\n  })\n}\nminimatch.defaults = defaults\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nexport const braceExpand = (\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  assertValidPattern(pattern)\n\n  // Thanks to Yeting Li  for\n  // improving this regexp to avoid a ReDOS vulnerability.\n  if (options.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(pattern)) {\n    // shortcut. no need to expand.\n    return [pattern]\n  }\n\n  return expand(pattern)\n}\nminimatch.braceExpand = braceExpand\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion.  Otherwise, any series\n// of * is equivalent to a single *.  Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\n\nexport const makeRe = (pattern: string, options: MinimatchOptions = {}) =>\n  new Minimatch(pattern, options).makeRe()\nminimatch.makeRe = makeRe\n\nexport const match = (\n  list: string[],\n  pattern: string,\n  options: MinimatchOptions = {}\n) => {\n  const mm = new Minimatch(pattern, options)\n  list = list.filter(f => mm.match(f))\n  if (mm.options.nonull && !list.length) {\n    list.push(pattern)\n  }\n  return list\n}\nminimatch.match = match\n\n// replace stuff like \\* with *\nconst globMagic = /[?*]|[+@!]\\(.*?\\)|\\[|\\]/\nconst regExpEscape = (s: string) =>\n  s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\nexport type MMRegExp = RegExp & {\n  _src?: string\n  _glob?: string\n}\n\nexport type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR\nexport type ParseReturn = ParseReturnFiltered | false\n\nexport class Minimatch {\n  options: MinimatchOptions\n  set: ParseReturnFiltered[][]\n  pattern: string\n\n  windowsPathsNoEscape: boolean\n  nonegate: boolean\n  negate: boolean\n  comment: boolean\n  empty: boolean\n  preserveMultipleSlashes: boolean\n  partial: boolean\n  globSet: string[]\n  globParts: string[][]\n  nocase: boolean\n\n  isWindows: boolean\n  platform: Platform\n  windowsNoMagicRoot: boolean\n\n  regexp: false | null | MMRegExp\n  constructor(pattern: string, options: MinimatchOptions = {}) {\n    assertValidPattern(pattern)\n\n    options = options || {}\n    this.options = options\n    this.pattern = pattern\n    this.platform = options.platform || defaultPlatform\n    this.isWindows = this.platform === 'win32'\n    this.windowsPathsNoEscape =\n      !!options.windowsPathsNoEscape || options.allowWindowsEscape === false\n    if (this.windowsPathsNoEscape) {\n      this.pattern = this.pattern.replace(/\\\\/g, '/')\n    }\n    this.preserveMultipleSlashes = !!options.preserveMultipleSlashes\n    this.regexp = null\n    this.negate = false\n    this.nonegate = !!options.nonegate\n    this.comment = false\n    this.empty = false\n    this.partial = !!options.partial\n    this.nocase = !!this.options.nocase\n    this.windowsNoMagicRoot =\n      options.windowsNoMagicRoot !== undefined\n        ? options.windowsNoMagicRoot\n        : !!(this.isWindows && this.nocase)\n\n    this.globSet = []\n    this.globParts = []\n    this.set = []\n\n    // make the set of regexps etc.\n    this.make()\n  }\n\n  hasMagic(): boolean {\n    if (this.options.magicalBraces && this.set.length > 1) {\n      return true\n    }\n    for (const pattern of this.set) {\n      for (const part of pattern) {\n        if (typeof part !== 'string') return true\n      }\n    }\n    return false\n  }\n\n  debug(..._: any[]) {}\n\n  make() {\n    const pattern = this.pattern\n    const options = this.options\n\n    // empty patterns and comments match nothing.\n    if (!options.nocomment && pattern.charAt(0) === '#') {\n      this.comment = true\n      return\n    }\n\n    if (!pattern) {\n      this.empty = true\n      return\n    }\n\n    // step 1: figure out negation, etc.\n    this.parseNegate()\n\n    // step 2: expand braces\n    this.globSet = [...new Set(this.braceExpand())]\n\n    if (options.debug) {\n      this.debug = (...args: any[]) => console.error(...args)\n    }\n\n    this.debug(this.pattern, this.globSet)\n\n    // step 3: now we have a set, so turn each one into a series of\n    // path-portion matching patterns.\n    // These will be regexps, except in the case of \"**\", which is\n    // set to the GLOBSTAR object for globstar behavior,\n    // and will not contain any / characters\n    //\n    // First, we preprocess to make the glob pattern sets a bit simpler\n    // and deduped.  There are some perf-killing patterns that can cause\n    // problems with a glob walk, but we can simplify them down a bit.\n    const rawGlobParts = this.globSet.map(s => this.slashSplit(s))\n    this.globParts = this.preprocess(rawGlobParts)\n    this.debug(this.pattern, this.globParts)\n\n    // glob --> regexps\n    let set = this.globParts.map((s, _, __) => {\n      if (this.isWindows && this.windowsNoMagicRoot) {\n        // check if it's a drive or unc path.\n        const isUNC =\n          s[0] === '' &&\n          s[1] === '' &&\n          (s[2] === '?' || !globMagic.test(s[2])) &&\n          !globMagic.test(s[3])\n        const isDrive = /^[a-z]:/i.test(s[0])\n        if (isUNC) {\n          return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]\n        } else if (isDrive) {\n          return [s[0], ...s.slice(1).map(ss => this.parse(ss))]\n        }\n      }\n      return s.map(ss => this.parse(ss))\n    })\n\n    this.debug(this.pattern, set)\n\n    // filter out everything that didn't compile properly.\n    this.set = set.filter(\n      s => s.indexOf(false) === -1\n    ) as ParseReturnFiltered[][]\n\n    // do not treat the ? in UNC paths as magic\n    if (this.isWindows) {\n      for (let i = 0; i < this.set.length; i++) {\n        const p = this.set[i]\n        if (\n          p[0] === '' &&\n          p[1] === '' &&\n          this.globParts[i][2] === '?' &&\n          typeof p[3] === 'string' &&\n          /^[a-z]:$/i.test(p[3])\n        ) {\n          p[2] = '?'\n        }\n      }\n    }\n\n    this.debug(this.pattern, this.set)\n  }\n\n  // various transforms to equivalent pattern sets that are\n  // faster to process in a filesystem walk.  The goal is to\n  // eliminate what we can, and push all ** patterns as far\n  // to the right as possible, even if it increases the number\n  // of patterns that we have to process.\n  preprocess(globParts: string[][]) {\n    // if we're not in globstar mode, then turn all ** into *\n    if (this.options.noglobstar) {\n      for (let i = 0; i < globParts.length; i++) {\n        for (let j = 0; j < globParts[i].length; j++) {\n          if (globParts[i][j] === '**') {\n            globParts[i][j] = '*'\n          }\n        }\n      }\n    }\n\n    const { optimizationLevel = 1 } = this.options\n\n    if (optimizationLevel >= 2) {\n      // aggressive optimization for the purpose of fs walking\n      globParts = this.firstPhasePreProcess(globParts)\n      globParts = this.secondPhasePreProcess(globParts)\n    } else if (optimizationLevel >= 1) {\n      // just basic optimizations to remove some .. parts\n      globParts = this.levelOneOptimize(globParts)\n    } else {\n      // just collapse multiple ** portions into one\n      globParts = this.adjascentGlobstarOptimize(globParts)\n    }\n\n    return globParts\n  }\n\n  // just get rid of adjascent ** portions\n  adjascentGlobstarOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      let gs: number = -1\n      while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n        let i = gs\n        while (parts[i + 1] === '**') {\n          i++\n        }\n        if (i !== gs) {\n          parts.splice(gs, i - gs)\n        }\n      }\n      return parts\n    })\n  }\n\n  // get rid of adjascent ** and resolve .. portions\n  levelOneOptimize(globParts: string[][]) {\n    return globParts.map(parts => {\n      parts = parts.reduce((set: string[], part) => {\n        const prev = set[set.length - 1]\n        if (part === '**' && prev === '**') {\n          return set\n        }\n        if (part === '..') {\n          if (prev && prev !== '..' && prev !== '.' && prev !== '**') {\n            set.pop()\n            return set\n          }\n        }\n        set.push(part)\n        return set\n      }, [])\n      return parts.length === 0 ? [''] : parts\n    })\n  }\n\n  levelTwoFileOptimize(parts: string | string[]) {\n    if (!Array.isArray(parts)) {\n      parts = this.slashSplit(parts)\n    }\n    let didSomething: boolean = false\n    do {\n      didSomething = false\n      // 
// -> 
/\n      if (!this.preserveMultipleSlashes) {\n        for (let i = 1; i < parts.length - 1; i++) {\n          const p = parts[i]\n          // don't squeeze out UNC patterns\n          if (i === 1 && p === '' && parts[0] === '') continue\n          if (p === '.' || p === '') {\n            didSomething = true\n            parts.splice(i, 1)\n            i--\n          }\n        }\n        if (\n          parts[0] === '.' &&\n          parts.length === 2 &&\n          (parts[1] === '.' || parts[1] === '')\n        ) {\n          didSomething = true\n          parts.pop()\n        }\n      }\n\n      // 
/

/../ ->

/\n      let dd: number = 0\n      while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n        const p = parts[dd - 1]\n        if (p && p !== '.' && p !== '..' && p !== '**') {\n          didSomething = true\n          parts.splice(dd - 1, 2)\n          dd -= 2\n        }\n      }\n    } while (didSomething)\n    return parts.length === 0 ? [''] : parts\n  }\n\n  // First phase: single-pattern processing\n  // 
 is 1 or more portions\n  //  is 1 or more portions\n  // 

is any portion other than ., .., '', or **\n // is . or ''\n //\n // **/.. is *brutal* for filesystem walking performance, because\n // it effectively resets the recursive walk each time it occurs,\n // and ** cannot be reduced out by a .. pattern part like a regexp\n // or most strings (other than .., ., and '') can be.\n //\n //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n //

// -> 
/\n  // 
/

/../ ->

/\n  // **/**/ -> **/\n  //\n  // **/*/ -> */**/ <== not valid because ** doesn't follow\n  // this WOULD be allowed if ** did follow symlinks, or * didn't\n  firstPhasePreProcess(globParts: string[][]) {\n    let didSomething = false\n    do {\n      didSomething = false\n      // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/}\n for (let parts of globParts) {\n let gs: number = -1\n while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n let gss: number = gs\n while (parts[gss + 1] === '**') {\n //

/**/**/ -> 
/**/\n            gss++\n          }\n          // eg, if gs is 2 and gss is 4, that means we have 3 **\n          // parts, and can remove 2 of them.\n          if (gss > gs) {\n            parts.splice(gs + 1, gss - gs)\n          }\n\n          let next = parts[gs + 1]\n          const p = parts[gs + 2]\n          const p2 = parts[gs + 3]\n          if (next !== '..') continue\n          if (\n            !p ||\n            p === '.' ||\n            p === '..' ||\n            !p2 ||\n            p2 === '.' ||\n            p2 === '..'\n          ) {\n            continue\n          }\n          didSomething = true\n          // edit parts in place, and push the new one\n          parts.splice(gs, 1)\n          const other = parts.slice(0)\n          other[gs] = '**'\n          globParts.push(other)\n          gs--\n        }\n\n        // 
// -> 
/\n        if (!this.preserveMultipleSlashes) {\n          for (let i = 1; i < parts.length - 1; i++) {\n            const p = parts[i]\n            // don't squeeze out UNC patterns\n            if (i === 1 && p === '' && parts[0] === '') continue\n            if (p === '.' || p === '') {\n              didSomething = true\n              parts.splice(i, 1)\n              i--\n            }\n          }\n          if (\n            parts[0] === '.' &&\n            parts.length === 2 &&\n            (parts[1] === '.' || parts[1] === '')\n          ) {\n            didSomething = true\n            parts.pop()\n          }\n        }\n\n        // 
/

/../ ->

/\n        let dd: number = 0\n        while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n          const p = parts[dd - 1]\n          if (p && p !== '.' && p !== '..' && p !== '**') {\n            didSomething = true\n            const needDot = dd === 1 && parts[dd + 1] === '**'\n            const splin = needDot ? ['.'] : []\n            parts.splice(dd - 1, 2, ...splin)\n            if (parts.length === 0) parts.push('')\n            dd -= 2\n          }\n        }\n      }\n    } while (didSomething)\n\n    return globParts\n  }\n\n  // second phase: multi-pattern dedupes\n  // {
/*/,
/

/} ->

/*/\n  // {
/,
/} -> 
/\n  // {
/**/,
/} -> 
/**/\n  //\n  // {
/**/,
/**/

/} ->

/**/\n  // ^-- not valid because ** doens't follow symlinks\n  secondPhasePreProcess(globParts: string[][]): string[][] {\n    for (let i = 0; i < globParts.length - 1; i++) {\n      for (let j = i + 1; j < globParts.length; j++) {\n        const matched = this.partsMatch(\n          globParts[i],\n          globParts[j],\n          !this.preserveMultipleSlashes\n        )\n        if (matched) {\n          globParts[i] = []\n          globParts[j] = matched\n          break\n        }\n      }\n    }\n    return globParts.filter(gs => gs.length)\n  }\n\n  partsMatch(\n    a: string[],\n    b: string[],\n    emptyGSMatch: boolean = false\n  ): false | string[] {\n    let ai = 0\n    let bi = 0\n    let result: string[] = []\n    let which: string = ''\n    while (ai < a.length && bi < b.length) {\n      if (a[ai] === b[bi]) {\n        result.push(which === 'b' ? b[bi] : a[ai])\n        ai++\n        bi++\n      } else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {\n        result.push(a[ai])\n        ai++\n      } else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {\n        result.push(b[bi])\n        bi++\n      } else if (\n        a[ai] === '*' &&\n        b[bi] &&\n        (this.options.dot || !b[bi].startsWith('.')) &&\n        b[bi] !== '**'\n      ) {\n        if (which === 'b') return false\n        which = 'a'\n        result.push(a[ai])\n        ai++\n        bi++\n      } else if (\n        b[bi] === '*' &&\n        a[ai] &&\n        (this.options.dot || !a[ai].startsWith('.')) &&\n        a[ai] !== '**'\n      ) {\n        if (which === 'a') return false\n        which = 'b'\n        result.push(b[bi])\n        ai++\n        bi++\n      } else {\n        return false\n      }\n    }\n    // if we fall out of the loop, it means they two are identical\n    // as long as their lengths match\n    return a.length === b.length && result\n  }\n\n  parseNegate() {\n    if (this.nonegate) return\n\n    const pattern = this.pattern\n    let negate = false\n    let negateOffset = 0\n\n    for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {\n      negate = !negate\n      negateOffset++\n    }\n\n    if (negateOffset) this.pattern = pattern.slice(negateOffset)\n    this.negate = negate\n  }\n\n  // set partial to true to test if, for example,\n  // \"/a/b\" matches the start of \"/*/b/*/d\"\n  // Partial means, if you run out of file before you run\n  // out of pattern, then that's fine, as long as all\n  // the parts match.\n  matchOne(file: string[], pattern: ParseReturn[], partial: boolean = false) {\n    const options = this.options\n\n    // UNC paths like //?/X:/... can match X:/... and vice versa\n    // Drive letters in absolute drive or unc paths are always compared\n    // case-insensitively.\n    if (this.isWindows) {\n      const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0])\n      const fileUNC =\n        !fileDrive &&\n        file[0] === '' &&\n        file[1] === '' &&\n        file[2] === '?' &&\n        /^[a-z]:$/i.test(file[3])\n\n      const patternDrive =\n        typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0])\n      const patternUNC =\n        !patternDrive &&\n        pattern[0] === '' &&\n        pattern[1] === '' &&\n        pattern[2] === '?' &&\n        typeof pattern[3] === 'string' &&\n        /^[a-z]:$/i.test(pattern[3])\n\n      const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined\n      const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined\n      if (typeof fdi === 'number' && typeof pdi === 'number') {\n        const [fd, pd]: [string, string] = [file[fdi], pattern[pdi] as string]\n        if (fd.toLowerCase() === pd.toLowerCase()) {\n          pattern[pdi] = fd\n          if (pdi > fdi) {\n            pattern = pattern.slice(pdi)\n          } else if (fdi > pdi) {\n            file = file.slice(fdi)\n          }\n        }\n      }\n    }\n\n    // resolve and reduce . and .. portions in the file as well.\n    // dont' need to do the second phase, because it's only one string[]\n    const { optimizationLevel = 1 } = this.options\n    if (optimizationLevel >= 2) {\n      file = this.levelTwoFileOptimize(file)\n    }\n\n    this.debug('matchOne', this, { file, pattern })\n    this.debug('matchOne', file.length, pattern.length)\n\n    for (\n      var fi = 0, pi = 0, fl = file.length, pl = pattern.length;\n      fi < fl && pi < pl;\n      fi++, pi++\n    ) {\n      this.debug('matchOne loop')\n      var p = pattern[pi]\n      var f = file[fi]\n\n      this.debug(pattern, p, f)\n\n      // should be impossible.\n      // some invalid regexp stuff in the set.\n      /* c8 ignore start */\n      if (p === false) {\n        return false\n      }\n      /* c8 ignore stop */\n\n      if (p === GLOBSTAR) {\n        this.debug('GLOBSTAR', [pattern, p, f])\n\n        // \"**\"\n        // a/**/b/**/c would match the following:\n        // a/b/x/y/z/c\n        // a/x/y/z/b/c\n        // a/b/x/b/x/c\n        // a/b/c\n        // To do this, take the rest of the pattern after\n        // the **, and see if it would match the file remainder.\n        // If so, return success.\n        // If not, the ** \"swallows\" a segment, and try again.\n        // This is recursively awful.\n        //\n        // a/**/b/**/c matching a/b/x/y/z/c\n        // - a matches a\n        // - doublestar\n        //   - matchOne(b/x/y/z/c, b/**/c)\n        //     - b matches b\n        //     - doublestar\n        //       - matchOne(x/y/z/c, c) -> no\n        //       - matchOne(y/z/c, c) -> no\n        //       - matchOne(z/c, c) -> no\n        //       - matchOne(c, c) yes, hit\n        var fr = fi\n        var pr = pi + 1\n        if (pr === pl) {\n          this.debug('** at the end')\n          // a ** at the end will just swallow the rest.\n          // We have found a match.\n          // however, it will not swallow /.x, unless\n          // options.dot is set.\n          // . and .. are *never* matched by **, for explosively\n          // exponential reasons.\n          for (; fi < fl; fi++) {\n            if (\n              file[fi] === '.' ||\n              file[fi] === '..' ||\n              (!options.dot && file[fi].charAt(0) === '.')\n            )\n              return false\n          }\n          return true\n        }\n\n        // ok, let's see if we can swallow whatever we can.\n        while (fr < fl) {\n          var swallowee = file[fr]\n\n          this.debug('\\nglobstar while', file, fr, pattern, pr, swallowee)\n\n          // XXX remove this slice.  Just pass the start index.\n          if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {\n            this.debug('globstar found match!', fr, fl, swallowee)\n            // found a match.\n            return true\n          } else {\n            // can't swallow \".\" or \"..\" ever.\n            // can only swallow \".foo\" when explicitly asked.\n            if (\n              swallowee === '.' ||\n              swallowee === '..' ||\n              (!options.dot && swallowee.charAt(0) === '.')\n            ) {\n              this.debug('dot detected!', file, fr, pattern, pr)\n              break\n            }\n\n            // ** swallows a segment, and continue.\n            this.debug('globstar swallow a segment, and continue')\n            fr++\n          }\n        }\n\n        // no match was found.\n        // However, in partial mode, we can't say this is necessarily over.\n        /* c8 ignore start */\n        if (partial) {\n          // ran out of file\n          this.debug('\\n>>> no match, partial?', file, fr, pattern, pr)\n          if (fr === fl) {\n            return true\n          }\n        }\n        /* c8 ignore stop */\n        return false\n      }\n\n      // something other than **\n      // non-magic patterns just have to match exactly\n      // patterns with magic have been turned into regexps.\n      let hit: boolean\n      if (typeof p === 'string') {\n        hit = f === p\n        this.debug('string match', p, f, hit)\n      } else {\n        hit = p.test(f)\n        this.debug('pattern match', p, f, hit)\n      }\n\n      if (!hit) return false\n    }\n\n    // Note: ending in / means that we'll get a final \"\"\n    // at the end of the pattern.  This can only match a\n    // corresponding \"\" at the end of the file.\n    // If the file ends in /, then it can only match a\n    // a pattern that ends in /, unless the pattern just\n    // doesn't have any more for it. But, a/b/ should *not*\n    // match \"a/b/*\", even though \"\" matches against the\n    // [^/]*? pattern, except in partial mode, where it might\n    // simply not be reached yet.\n    // However, a/b/ should still satisfy a/*\n\n    // now either we fell off the end of the pattern, or we're done.\n    if (fi === fl && pi === pl) {\n      // ran out of pattern and filename at the same time.\n      // an exact hit!\n      return true\n    } else if (fi === fl) {\n      // ran out of file, but still had pattern left.\n      // this is ok if we're doing the match as part of\n      // a glob fs traversal.\n      return partial\n    } else if (pi === pl) {\n      // ran out of pattern, still have file left.\n      // this is only acceptable if we're on the very last\n      // empty segment of a file with a trailing slash.\n      // a/* should match a/b/\n      return fi === fl - 1 && file[fi] === ''\n\n      /* c8 ignore start */\n    } else {\n      // should be unreachable.\n      throw new Error('wtf?')\n    }\n    /* c8 ignore stop */\n  }\n\n  braceExpand() {\n    return braceExpand(this.pattern, this.options)\n  }\n\n  parse(pattern: string): ParseReturn {\n    assertValidPattern(pattern)\n\n    const options = this.options\n\n    // shortcuts\n    if (pattern === '**') return GLOBSTAR\n    if (pattern === '') return ''\n\n    // far and away, the most common glob pattern parts are\n    // *, *.*, and *.  Add a fast check method for those.\n    let m: RegExpMatchArray | null\n    let fastTest: null | ((f: string) => boolean) = null\n    if ((m = pattern.match(starRE))) {\n      fastTest = options.dot ? starTestDot : starTest\n    } else if ((m = pattern.match(starDotExtRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? starDotExtTestNocaseDot\n            : starDotExtTestNocase\n          : options.dot\n          ? starDotExtTestDot\n          : starDotExtTest\n      )(m[1])\n    } else if ((m = pattern.match(qmarksRE))) {\n      fastTest = (\n        options.nocase\n          ? options.dot\n            ? qmarksTestNocaseDot\n            : qmarksTestNocase\n          : options.dot\n          ? qmarksTestDot\n          : qmarksTest\n      )(m)\n    } else if ((m = pattern.match(starDotStarRE))) {\n      fastTest = options.dot ? starDotStarTestDot : starDotStarTest\n    } else if ((m = pattern.match(dotStarRE))) {\n      fastTest = dotStarTest\n    }\n\n    const re = AST.fromGlob(pattern, this.options).toMMPattern()\n    if (fastTest && typeof re === 'object') {\n      // Avoids overriding in frozen environments\n      Reflect.defineProperty(re, 'test', { value: fastTest })\n    }\n    return re\n  }\n\n  makeRe() {\n    if (this.regexp || this.regexp === false) return this.regexp\n\n    // at this point, this.set is a 2d array of partial\n    // pattern strings, or \"**\".\n    //\n    // It's better to use .match().  This function shouldn't\n    // be used, really, but it's pretty convenient sometimes,\n    // when you just want to work with a regex.\n    const set = this.set\n\n    if (!set.length) {\n      this.regexp = false\n      return this.regexp\n    }\n    const options = this.options\n\n    const twoStar = options.noglobstar\n      ? star\n      : options.dot\n      ? twoStarDot\n      : twoStarNoDot\n    const flags = new Set(options.nocase ? ['i'] : [])\n\n    // regexpify non-globstar patterns\n    // if ** is only item, then we just do one twoStar\n    // if ** is first, and there are more, prepend (\\/|twoStar\\/)? to next\n    // if ** is last, append (\\/twoStar|) to previous\n    // if ** is in the middle, append (\\/|\\/twoStar\\/) to previous\n    // then filter out GLOBSTAR symbols\n    let re = set\n      .map(pattern => {\n        const pp: (string | typeof GLOBSTAR)[] = pattern.map(p => {\n          if (p instanceof RegExp) {\n            for (const f of p.flags.split('')) flags.add(f)\n          }\n          return typeof p === 'string'\n            ? regExpEscape(p)\n            : p === GLOBSTAR\n            ? GLOBSTAR\n            : p._src\n        }) as (string | typeof GLOBSTAR)[]\n        pp.forEach((p, i) => {\n          const next = pp[i + 1]\n          const prev = pp[i - 1]\n          if (p !== GLOBSTAR || prev === GLOBSTAR) {\n            return\n          }\n          if (prev === undefined) {\n            if (next !== undefined && next !== GLOBSTAR) {\n              pp[i + 1] = '(?:\\\\/|' + twoStar + '\\\\/)?' + next\n            } else {\n              pp[i] = twoStar\n            }\n          } else if (next === undefined) {\n            pp[i - 1] = prev + '(?:\\\\/|' + twoStar + ')?'\n          } else if (next !== GLOBSTAR) {\n            pp[i - 1] = prev + '(?:\\\\/|\\\\/' + twoStar + '\\\\/)' + next\n            pp[i + 1] = GLOBSTAR\n          }\n        })\n        return pp.filter(p => p !== GLOBSTAR).join('/')\n      })\n      .join('|')\n\n    // need to wrap in parens if we had more than one thing with |,\n    // otherwise only the first will be anchored to ^ and the last to $\n    const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']\n    // must match entire pattern\n    // ending in a * or ** will make it less strict.\n    re = '^' + open + re + close + '$'\n\n    // can match anything, as long as it's not this.\n    if (this.negate) re = '^(?!' + re + ').+$'\n\n    try {\n      this.regexp = new RegExp(re, [...flags].join(''))\n      /* c8 ignore start */\n    } catch (ex) {\n      // should be impossible\n      this.regexp = false\n    }\n    /* c8 ignore stop */\n    return this.regexp\n  }\n\n  slashSplit(p: string) {\n    // if p starts with // on windows, we preserve that\n    // so that UNC paths aren't broken.  Otherwise, any number of\n    // / characters are coalesced into one, unless\n    // preserveMultipleSlashes is set to true.\n    if (this.preserveMultipleSlashes) {\n      return p.split('/')\n    } else if (this.isWindows && /^\\/\\/[^\\/]+/.test(p)) {\n      // add an extra '' for the one we lose\n      return ['', ...p.split(/\\/+/)]\n    } else {\n      return p.split(/\\/+/)\n    }\n  }\n\n  match(f: string, partial = this.partial) {\n    this.debug('match', f, this.pattern)\n    // short-circuit in the case of busted things.\n    // comments, etc.\n    if (this.comment) {\n      return false\n    }\n    if (this.empty) {\n      return f === ''\n    }\n\n    if (f === '/' && partial) {\n      return true\n    }\n\n    const options = this.options\n\n    // windows: need to use /, not \\\n    if (this.isWindows) {\n      f = f.split('\\\\').join('/')\n    }\n\n    // treat the test path as a set of pathparts.\n    const ff = this.slashSplit(f)\n    this.debug(this.pattern, 'split', ff)\n\n    // just ONE of the pattern sets in this.set needs to match\n    // in order for it to be valid.  If negating, then just one\n    // match means that we have failed.\n    // Either way, return on the first hit.\n\n    const set = this.set\n    this.debug(this.pattern, 'set', set)\n\n    // Find the basename of the path by looking for the last non-empty segment\n    let filename: string = ff[ff.length - 1]\n    if (!filename) {\n      for (let i = ff.length - 2; !filename && i >= 0; i--) {\n        filename = ff[i]\n      }\n    }\n\n    for (let i = 0; i < set.length; i++) {\n      const pattern = set[i]\n      let file = ff\n      if (options.matchBase && pattern.length === 1) {\n        file = [filename]\n      }\n      const hit = this.matchOne(file, pattern, partial)\n      if (hit) {\n        if (options.flipNegate) {\n          return true\n        }\n        return !this.negate\n      }\n    }\n\n    // didn't get any hits.  this is success if it's a negative\n    // pattern, failure otherwise.\n    if (options.flipNegate) {\n      return false\n    }\n    return this.negate\n  }\n\n  static defaults(def: MinimatchOptions) {\n    return minimatch.defaults(def).Minimatch\n  }\n}\n/* c8 ignore start */\nexport { AST } from './ast.js'\nexport { escape } from './escape.js'\nexport { unescape } from './unescape.js'\n/* c8 ignore stop */\nminimatch.AST = AST\nminimatch.Minimatch = Minimatch\nminimatch.escape = escape\nminimatch.unescape = unescape\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/package.json b/backend/node_modules/minimatch/dist/esm/package.json
deleted file mode 100644
index 3dbc1ca5..00000000
--- a/backend/node_modules/minimatch/dist/esm/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "type": "module"
-}
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.d.ts b/backend/node_modules/minimatch/dist/esm/unescape.d.ts
deleted file mode 100644
index 23a7b387..00000000
--- a/backend/node_modules/minimatch/dist/esm/unescape.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { MinimatchOptions } from './index.js';
-/**
- * Un-escape a string that has been escaped with {@link escape}.
- *
- * If the {@link windowsPathsNoEscape} option is used, then square-brace
- * escapes are removed, but not backslash escapes.  For example, it will turn
- * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
- * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
- *
- * When `windowsPathsNoEscape` is not set, then both brace escapes and
- * backslash escapes are removed.
- *
- * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
- * or unescaped.
- */
-export declare const unescape: (s: string, { windowsPathsNoEscape, }?: Pick) => string;
-//# sourceMappingURL=unescape.d.ts.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.d.ts.map b/backend/node_modules/minimatch/dist/esm/unescape.d.ts.map
deleted file mode 100644
index 7ace0701..00000000
--- a/backend/node_modules/minimatch/dist/esm/unescape.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,MAChB,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAKlD,CAAA"}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.js b/backend/node_modules/minimatch/dist/esm/unescape.js
deleted file mode 100644
index 0faf9a2b..00000000
--- a/backend/node_modules/minimatch/dist/esm/unescape.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Un-escape a string that has been escaped with {@link escape}.
- *
- * If the {@link windowsPathsNoEscape} option is used, then square-brace
- * escapes are removed, but not backslash escapes.  For example, it will turn
- * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
- * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
- *
- * When `windowsPathsNoEscape` is not set, then both brace escapes and
- * backslash escapes are removed.
- *
- * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
- * or unescaped.
- */
-export const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
-    return windowsPathsNoEscape
-        ? s.replace(/\[([^\/\\])\]/g, '$1')
-        : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
-};
-//# sourceMappingURL=unescape.js.map
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/dist/esm/unescape.js.map b/backend/node_modules/minimatch/dist/esm/unescape.js.map
deleted file mode 100644
index eb146c20..00000000
--- a/backend/node_modules/minimatch/dist/esm/unescape.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAA","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link windowsPathsNoEscape} option is used, then square-brace\n * escapes are removed, but not backslash escapes.  For example, it will turn\n * the string `'[*]'` into `*`, but it will not turn `'\\\\*'` into `'*'`,\n * becuase `\\` is a path separator in `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both brace escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n */\nexport const unescape = (\n  s: string,\n  {\n    windowsPathsNoEscape = false,\n  }: Pick = {}\n) => {\n  return windowsPathsNoEscape\n    ? s.replace(/\\[([^\\/\\\\])\\]/g, '$1')\n    : s.replace(/((?!\\\\).|^)\\[([^\\/\\\\])\\]/g, '$1$2').replace(/\\\\([^\\/])/g, '$1')\n}\n"]}
\ No newline at end of file
diff --git a/backend/node_modules/minimatch/package.json b/backend/node_modules/minimatch/package.json
deleted file mode 100644
index 01fc48ec..00000000
--- a/backend/node_modules/minimatch/package.json
+++ /dev/null
@@ -1,82 +0,0 @@
-{
-  "author": "Isaac Z. Schlueter  (http://blog.izs.me)",
-  "name": "minimatch",
-  "description": "a glob matcher in javascript",
-  "version": "9.0.5",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/isaacs/minimatch.git"
-  },
-  "main": "./dist/commonjs/index.js",
-  "types": "./dist/commonjs/index.d.ts",
-  "exports": {
-    "./package.json": "./package.json",
-    ".": {
-      "import": {
-        "types": "./dist/esm/index.d.ts",
-        "default": "./dist/esm/index.js"
-      },
-      "require": {
-        "types": "./dist/commonjs/index.d.ts",
-        "default": "./dist/commonjs/index.js"
-      }
-    }
-  },
-  "files": [
-    "dist"
-  ],
-  "scripts": {
-    "preversion": "npm test",
-    "postversion": "npm publish",
-    "prepublishOnly": "git push origin --follow-tags",
-    "prepare": "tshy",
-    "pretest": "npm run prepare",
-    "presnap": "npm run prepare",
-    "test": "tap",
-    "snap": "tap",
-    "format": "prettier --write . --loglevel warn",
-    "benchmark": "node benchmark/index.js",
-    "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts"
-  },
-  "prettier": {
-    "semi": false,
-    "printWidth": 80,
-    "tabWidth": 2,
-    "useTabs": false,
-    "singleQuote": true,
-    "jsxSingleQuote": false,
-    "bracketSameLine": true,
-    "arrowParens": "avoid",
-    "endOfLine": "lf"
-  },
-  "engines": {
-    "node": ">=16 || 14 >=14.17"
-  },
-  "dependencies": {
-    "brace-expansion": "^2.0.1"
-  },
-  "devDependencies": {
-    "@types/brace-expansion": "^1.1.0",
-    "@types/node": "^18.15.11",
-    "@types/tap": "^15.0.8",
-    "eslint-config-prettier": "^8.6.0",
-    "mkdirp": "1",
-    "prettier": "^2.8.2",
-    "tap": "^18.7.2",
-    "ts-node": "^10.9.1",
-    "tshy": "^1.12.0",
-    "typedoc": "^0.23.21",
-    "typescript": "^4.9.3"
-  },
-  "funding": {
-    "url": "https://github.com/sponsors/isaacs"
-  },
-  "license": "ISC",
-  "tshy": {
-    "exports": {
-      "./package.json": "./package.json",
-      ".": "./src/index.ts"
-    }
-  },
-  "type": "module"
-}
diff --git a/backend/node_modules/run/LICENSE b/backend/node_modules/run/LICENSE
deleted file mode 100644
index 10457ca6..00000000
--- a/backend/node_modules/run/LICENSE
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright 2011 David Trejo. All rights reserved.
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
diff --git a/backend/node_modules/run/cli.js b/backend/node_modules/run/cli.js
deleted file mode 100644
index 0b5ee4a2..00000000
--- a/backend/node_modules/run/cli.js
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env node
-require('./run.js')
diff --git a/backend/node_modules/run/package.json b/backend/node_modules/run/package.json
deleted file mode 100644
index 01cb4ee0..00000000
--- a/backend/node_modules/run/package.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "name": "run",
-  "description": "Reruns the given file whenever a file in the current working dir subtree is changed.",
-  "version": "1.5.0",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/DTrejo/run.js.git"
-  },
-  "author": "David Trejo  (http://dtrejo.com/)",
-  "maintainers": [
-    "David Trejo  (http://dtrejo.com/)"
-  ],
-  "preferGlobal": true,
-  "bin": {
-    "runjs": "./cli.js"
-  },
-  "engines": {
-    "node": ">=v0.9.0"
-  },
-  "dependencies": {
-    "minimatch": "*"
-  },
-  "devDependencies": {},
-  "homepage": "https://github.com/dtrejo/run.js",
-  "optionalDependencies": {}
-}
diff --git a/backend/node_modules/run/readme.md b/backend/node_modules/run/readme.md
deleted file mode 100644
index 66ab2323..00000000
--- a/backend/node_modules/run/readme.md
+++ /dev/null
@@ -1,47 +0,0 @@
-## Install
-
-`$ npm -g install run`
-
-## Usage
-
-`$ runjs yourcode.js`
-
-# What does it do?
-
-`runjs` will rerun server.js whenever one of the watched files is
-changed. It ignores files in your `.gitignore`.
-
-    $ runjs server.js
-    Watching /Dropbox/dev/server.js and all sub-directories not excluded by your .gitignore
-    Found & ignored file.db ; is dotfile or has ignored extension
-
-    Starting: server.js
-    > Listening on http://localhost:8888/
-
-No more switching to the terminal to rerun your code. Just change a file and
-your code will be rerun.
-
-This is especially nice for web-servers, as you can skip the terminal and
-alt-tab to the browser to see your updated code happily running.
-
-### Features
-- supports globs in .gitignore (e.g. `*.log`)
-- any arguments, including debug arguments, are relayed to your code
-- **stdin is relayed to your code** [not supported by nodemon as of 12/5/11]
-- files and directories in `.gitignore` are not watched, neither are dotfiles.
-- coffeescript is supported: `runjs yourcode.coffee`
-  (by [rockymeza](https://github.com/rockymeza))
-
-Source at [github.com/DTrejo/run.js](https://github.com/DTrejo/run.js)
-
----
-![Screenshot of runjs](https://github.com/DTrejo/run.js/raw/master/test/screenshot.png)
-
-### Contributors
-Ordered by date of first contribution.
-[Auto-generated](http://github.com/dtrejo/node-authors) on Wed Aug 08 2012 20:27:26 GMT-0700 (PDT).
-
-- [David Trejo aka `DTrejo`](https://github.com/DTrejo)
-- [Rocky Meza aka `rockymeza`](https://github.com/rockymeza)
-- [Shani Elharrar aka `morishani`](https://github.com/morishani)
-- [Andrew Sutherland aka `asuth`](https://github.com/asuth)
diff --git a/backend/node_modules/run/run.js b/backend/node_modules/run/run.js
deleted file mode 100644
index 0d3e831b..00000000
--- a/backend/node_modules/run/run.js
+++ /dev/null
@@ -1,179 +0,0 @@
-// https://github.com/DTrejo/run.js
-// Used to run code in a directory and rerun it if any files are changed.
-// Usage: ./cli.js servercode.js
-// Where servercode.js is whatever js file you want node to run
-
-// Excludes filetypes in the ignoreExtensions array
-var util = require('util')
-  , fs = require('fs')
-  , path = require('path')
-  , spawn = require('child_process').spawn
-  , { minimatch } = require('minimatch')
-  , child // child process which runs the user's code
-  , ignoreExtensions = ['.dirtydb', '.db', '.styl', '.css']
-  , ignoreFiles = [ 'node_modules' ]
-  // switched out for coffee depending on extension.
-  , node = 'node'
-  , args = process.argv
-  , signal = null
-
-//
-// Tell user the correct usage if they miss-type
-//
-if (args.length <= 2) {
-  console.log('Found ' + (args.length - 2)
-    , 'argument(s). Expected one or more.')
-  console.log(
-    'Usage: \n  runjs [SIGNAL] somecode.js [--args]\n'
-    + 'Ex:  \n  runjs somecode.js --args'
-    + '     \n  runjs SIGUSR2 somecode.js --args\n'
-    )
-  process.exit(1)
-}
-
-//
-// If we define a signal, parse it out and then remove from the array
-//
-if (args[2].match(/^SIG/)) {
-  signal = args.splice(2, 1)[0];
-}
-
-//
-// use `coffee` if the file ends with .coffee
-//
-if (args[2].match(/\.coffee$/)) node = 'coffee'
-
-
-//
-// Exclude files based on .gitignore
-//
-if (fs.existsSync('.gitignore')) {
-  ignoreFiles = ignoreFiles.concat(fs.readFileSync('.gitignore', 'utf8')
-    .split('\n')
-    .filter(function(s) {
-      s = s.trim()
-      return s.indexOf('#') !== 0 && s.length > 0
-    })
-  )
-}
-
-console.log('Watching', path.resolve('./'), 'and all sub-directories not'
-  , 'excluded by your .gitignore. Will not monitor dotfiles.')
-
-watchFiles(parseFolder('.'), restart) // watch all files, restart if problem
-run()
-
-
-process.stdin.setEncoding('utf8')
-
-// executes the command given by the second argument
-;function run() {
-  // run the server
-  var childArgs = args.slice(2) || []
-  child = spawn(node, childArgs)
-
-  // let the child's output escape.
-  child.stdout.on('data', function(data) {
-    process.stdout.write(data)
-  })
-  child.stderr.on('data', function(error) {
-    process.stdout.write(error)
-  })
-
-  // let the user's typing get to the child
-  process.stdin.pipe(child.stdin)
-
-  console.log('\nStarting: ' + childArgs.join(' '))
-}
-
-;function restart() {
-  // kill if running
-  if (child) {
-    if (signal) {
-      child.kill(signal)
-    } else {
-      child.kill()
-      run()
-    }
-  } else {
-    run()
-  }
-}
-
-/**
-* Parses a folder recursively and returns a list of files
-*
-* @param root {String}
-* @return {Array}
-*/
-;function parseFolder(root) {
-  var fileList = []
-    , files = fs.readdirSync(root)
-
-  files.forEach(function(file) {
-    var pathname = path.join(root, file)
-      , stat = fs.lstatSync(pathname)
-
-    if (stat === undefined) return
-
-    // add files to file list
-    if (!stat.isDirectory()) {
-      fileList.push(pathname)
-
-    // recur if directory
-    } else {
-      // don't watch folders matched by .gitignore regexes
-      for (var i = 0, pattern; pattern = ignoreFiles[i]; i++) {
-        if (minimatch(file, pattern)) {
-          console.log('Found & ignored', './' + pathname, '; is listed in .gitignore')
-          return
-        }
-      }
-      fileList = fileList.concat(parseFolder(pathname))
-    }
-  })
-
-  return fileList
-}
-
-
-/**
-* Add change listener to files, which is called whenever one changes.
-* Ignores certain extensions.
-*
-* @param files {Array}
-* @param callback {function}
-*/
-;function watchFiles(files, callback) {
-
-  var config = {  persistent: true, interval: 25 }
-  files.forEach(function (file) {
-
-    // don't watch dotfiles.
-    if (file.indexOf('.') === 0) return
-
-    // don't watch things with ignored extensions
-    var ext = path.extname(file)
-    if (ignoreExtensions.indexOf(ext) !== -1) {
-      console.log('Found & ignored', './' + file, '; has ignored extension')
-      return
-    }
-
-    // don't watch files matched by .gitignore regexes
-    for (var i = 0, pattern; pattern = ignoreFiles[i]; i++) {
-      if (minimatch(file, pattern)) {
-        console.log('Found & ignored', './' + file, '; is listed in .gitignore')
-        return
-      }
-    }
-
-    // if any file changes, run the callback
-    fs.watchFile(file, config, function (curr, prev) {
-
-      if ((curr.mtime + '') != (prev.mtime + '')) {
-        console.log('./' + file + ' changed')
-        if (callback) callback()
-      }
-    })
-  })
-}
diff --git a/backend/node_modules/run/test/runme.js b/backend/node_modules/run/test/runme.js
deleted file mode 100644
index 987fd75c..00000000
--- a/backend/node_modules/run/test/runme.js
+++ /dev/null
@@ -1,28 +0,0 @@
-var readline = require('readline')
-  , rl = readline.createInterface(process.stdin, process.stdout)
-  , prefix = 'OHAI> '
-
-rl.on('line', function(line) {
-  switch(line.trim()) {
-    case 'hello':
-      console.log('world!')
-      break
-    case 'error':
-        throw new Error('Sample error!')
-      break
-    default:
-      console.log('Say what? I might have heard `' + line.trim() + '`')
-      break
-  }
-  rl.setPrompt(prefix, prefix.length)
-  rl.prompt()
-}).on('close', function() {
-  console.log('Have a great day!')
-  process.exit(0)
-})
-
-console.log(prefix + 'Good to see you. Try typing `hello` or `error`.')
-console.log(prefix + 'My process.argv =', process.argv.join(' '));
-console.log(prefix + 'When you type, this process will get your keystrokes.');
-rl.setPrompt(prefix, prefix.length)
-rl.prompt()
diff --git a/backend/node_modules/run/test/screenshot.png b/backend/node_modules/run/test/screenshot.png
deleted file mode 100644
index 0405a07cb7641dd378ec87992114fef2d8d2aaf6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 92481
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 MQp%Fm;-;bh2P;v<3jhEB diff --git a/backend/package-lock.json b/backend/package-lock.json deleted file mode 100644 index f2d1490d..00000000 --- a/backend/package-lock.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "backend", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "run": "^1.5.0" - } - }, - "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==" - }, - "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==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/run/-/run-1.5.0.tgz", - "integrity": "sha512-CBPzeX6JQZUdhZpSFyNt2vUk44ivKMWZYCNBYoZYEE46mL9nf6WyMP3320WnzIrJuo89+njiUvlo83jUEXjXLg==", - "dependencies": { - "minimatch": "*" - }, - "bin": { - "runjs": "cli.js" - }, - "engines": { - "node": ">=v0.9.0" - } - } - } -} diff --git a/backend/package.json b/backend/package.json deleted file mode 100644 index 269feced..00000000 --- a/backend/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "run": "^1.5.0" - } -} From d13df330233e1b087db727e281c03a673e4dfa94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Tue, 9 Jul 2024 20:13:14 +0200 Subject: [PATCH 11/19] revert: package.json remove react-scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Márk Kővári --- frontend/package.json | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 3101d47d..31cb5db7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,16 +10,11 @@ "preview": "vite preview", "test": "echo \"Error: no test specified, but pessing now\" && exit 0" }, -"dependencies": { - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", + "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", - "react-scripts": "5.0.1", - "validator": "^13.9.0", - "web-vitals": "^2.1.4" -} , + "validator": "^13.12.0" + }, "devDependencies": { "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", @@ -34,4 +29,4 @@ "typescript": "^5.2.2", "vite": "^5.2.0" } -} +} \ No newline at end of file From a3e0ce58f08f805ee74bad95e9b732c6feac2dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Tue, 9 Jul 2024 20:25:21 +0200 Subject: [PATCH 12/19] fix(backend): add throws exception to test suites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Márk Kővári --- .../backend/controller/UserRegistrationTest.java | 2 +- .../com/greenfoxacademy/backend/controller/UserServiceTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserRegistrationTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserRegistrationTest.java index bb9d36d2..2d24c420 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserRegistrationTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserRegistrationTest.java @@ -24,7 +24,7 @@ public class UserRegistrationTest { private UserRepository userRepository; @Test - public void userIsSuccessfulRegisteredInDatabase() { + public void userIsSuccessfulRegisteredInDatabase() throws Exception { RegisterUserDto newUser = new RegisterUserDto(); newUser.setFirstName("John"); newUser.setLastName("Doe"); diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserServiceTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserServiceTest.java index ebc074e9..b077c2df 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserServiceTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserServiceTest.java @@ -27,7 +27,7 @@ public class UserServiceTest { private UserController userController; @Test - public void registerMethodIsSuccessfullyCalled() { + public void registerMethodIsSuccessfullyCalled() throws Exception { RegisterUserDto registerUserDto = new RegisterUserDto(); registerUserDto.setFirstName("John"); registerUserDto.setLastName("Doe"); From 76bd186fe1ce950b93f432792458bf0091365555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Tue, 9 Jul 2024 20:38:02 +0200 Subject: [PATCH 13/19] refactor(backend):align with google java standards --- .../backend/BackendApplication.java | 3 ++ .../backend/controller/UserController.java | 15 ++++++---- .../backend/dtos/RegisterResponseDto.java | 5 ++++ .../greenfoxacademy/backend/models/User.java | 16 ++++++---- .../services/PasswordConstraintValidator.java | 3 ++ .../backend/services/ValidPassword.java | 29 ++++++++++++++----- 6 files changed, 52 insertions(+), 19 deletions(-) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java b/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java index 35876729..d4092c00 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java @@ -3,6 +3,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +/** + * This is the main class of the application. + */ @SpringBootApplication public class BackendApplication { diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index 18b6b897..d5b879cd 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -1,5 +1,9 @@ package com.greenfoxacademy.backend.controller; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + import com.greenfoxacademy.backend.dtos.RegisterUserDto; import com.greenfoxacademy.backend.services.UserService; import lombok.RequiredArgsConstructor; @@ -8,11 +12,12 @@ import org.springframework.validation.FieldError; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.*; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; /** diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java index 7527c26f..794ca6f9 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java @@ -1,5 +1,10 @@ package com.greenfoxacademy.backend.dtos; + +/** + * RegisterResponseDto represents a registration response. + * @param id of the created user + */ public record RegisterResponseDto( Integer id ) { diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index 3e042293..ef5b79b9 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -1,6 +1,10 @@ package com.greenfoxacademy.backend.models; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -8,23 +12,23 @@ /** * Represents a user entity in the system. This class is a data model - * that maps to the user table in the database + * that maps to the user table in the database. */ @Data @Builder @AllArgsConstructor @NoArgsConstructor @Entity -@Table (name = "_user") +@Table(name = "_user") public class User { - + @Id @GeneratedValue private Integer id; private String firstName; private String lastName; - @Column (unique = true) + @Column(unique = true) private String email; private String password; - + } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java index 873a81d3..09810b05 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java @@ -7,6 +7,9 @@ import java.util.ArrayList; +/** + * Custom validator for password field. + */ public class PasswordConstraintValidator implements ConstraintValidator { @Override diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java index 0cfc9332..c99d61bd 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/ValidPassword.java @@ -1,26 +1,39 @@ package com.greenfoxacademy.backend.services; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + import jakarta.validation.Constraint; import jakarta.validation.Payload; - import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - +/** + * ValidPassword annotation to mark a field as a password which should be validated. + */ @Documented @Constraint (validatedBy = PasswordConstraintValidator.class) @Target ({TYPE, FIELD, ANNOTATION_TYPE}) -@Retention (RUNTIME) +@Retention(RUNTIME) public @interface ValidPassword { - + + /** + * Message to be displayed when the password is invalid. + */ String message() default "Invalid Password"; - + + /** + * Groups. + */ Class[] groups() default {}; - + + /** + * Payload. + */ Class[] payload() default {}; } From 6b5dffa90a1d871fb19148ce699187fbaf65a381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?= Date: Tue, 9 Jul 2024 20:46:30 +0200 Subject: [PATCH 14/19] refactor(backend): align with Google Java Coding standards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Márk Kővári --- .../backend/controller/UserController.java | 23 ++- .../backend/dtos/RegisterResponseDto.java | 3 + .../services/PasswordConstraintValidator.java | 14 +- .../controller/UserControllerTest.java | 170 ++++++++++++------ 4 files changed, 151 insertions(+), 59 deletions(-) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index d5b879cd..47d4d6e0 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -1,11 +1,10 @@ package com.greenfoxacademy.backend.controller; +import com.greenfoxacademy.backend.dtos.RegisterUserDto; +import com.greenfoxacademy.backend.services.UserService; import java.net.URI; import java.util.HashMap; import java.util.Map; - -import com.greenfoxacademy.backend.dtos.RegisterUserDto; -import com.greenfoxacademy.backend.services.UserService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,7 +26,14 @@ @RequiredArgsConstructor public class UserController { private final UserService userService; - + + /** + * This method registers a new user. + * + * @param registerUserDto the user to be registered + * + * @return a response entity with the status code and the location of the new user + */ @CrossOrigin (origins = "http://localhost:5173") @PostMapping ("/register") public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto registerUserDto) { @@ -38,7 +44,14 @@ public ResponseEntity registerUser(@Validated @RequestBody RegisterUserDto re return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); } } - + + /** + * This method handles validation exceptions. + * + * @param ex the exception to be handled + * + * @return a map with the field name and the error message + */ @ResponseStatus (HttpStatus.BAD_REQUEST) @ExceptionHandler (MethodArgumentNotValidException.class) public Map handleValidationExceptions(MethodArgumentNotValidException ex) { diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java index 794ca6f9..edc09608 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/RegisterResponseDto.java @@ -3,8 +3,11 @@ /** * RegisterResponseDto represents a registration response. + * * @param id of the created user + * */ + public record RegisterResponseDto( Integer id ) { diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java index 09810b05..c583320f 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/PasswordConstraintValidator.java @@ -3,7 +3,6 @@ import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; - import java.util.ArrayList; @@ -15,8 +14,11 @@ public class PasswordConstraintValidator implements ConstraintValidator Date: Tue, 9 Jul 2024 23:25:11 +0200 Subject: [PATCH 15/19] refactor: use single import files and move static imports to the top --- .../backend/controller/UserControllerTest.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 7ddcb358..59c36094 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -1,5 +1,12 @@ package com.greenfoxacademy.backend.controller; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import org.junit.jupiter.api.DisplayName; @@ -12,9 +19,6 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import static org.hamcrest.Matchers.is; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @SpringBootTest From 0a412e8b64e1aea9eea27105ed10a4344d231aee Mon Sep 17 00:00:00 2001 From: Carlos Ponton Date: Tue, 9 Jul 2024 23:37:02 +0200 Subject: [PATCH 16/19] refactor: split string message to lines with less than 100 characters --- .../backend/controller/UserControllerTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 59c36094..4785b65c 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -186,9 +186,10 @@ void shouldReturnPasswordIsInvalidWithAllErrorsIfItHasAllErrors() throws Excepti status().isBadRequest(), jsonPath( "$.password", - is("Invalid password: must be at least 8 characters long, must not contain whitespace," + - " must contain at least one digit, must contain at least one uppercase letter," + - " must contain at least one lowercase letter") + is("Invalid password: must be at least 8 characters long, " + + " must not contain whitespace, must contain at least one digit, " + + " must contain at least one uppercase letter," + + " must contain at least one lowercase letter") )); } From 5c58f26afb09dd3b6df156606bbf23a15d3b5d16 Mon Sep 17 00:00:00 2001 From: Carlos Ponton Date: Tue, 9 Jul 2024 23:43:52 +0200 Subject: [PATCH 17/19] fix: correct string message space to pass the test --- .../backend/controller/UserControllerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 4785b65c..5f394222 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -186,8 +186,8 @@ void shouldReturnPasswordIsInvalidWithAllErrorsIfItHasAllErrors() throws Excepti status().isBadRequest(), jsonPath( "$.password", - is("Invalid password: must be at least 8 characters long, " - + " must not contain whitespace, must contain at least one digit, " + is("Invalid password: must be at least 8 characters long," + + " must not contain whitespace, must contain at least one digit," + " must contain at least one uppercase letter," + " must contain at least one lowercase letter") )); From 375e595a86a66bf7f4a0cd65d15828c594774955 Mon Sep 17 00:00:00 2001 From: Hsbalazs Date: Wed, 10 Jul 2024 20:57:50 +0200 Subject: [PATCH 18/19] fix: correctindentation level 12 to 8 in UserControllerTest --- .../controller/UserControllerTest.java | 257 +++++++++--------- 1 file changed, 128 insertions(+), 129 deletions(-) diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 5f394222..3403b552 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -20,7 +20,6 @@ import org.springframework.test.web.servlet.MockMvc; - @SpringBootTest @AutoConfigureMockMvc class UserControllerTest { @@ -37,18 +36,18 @@ class UserControllerTest { void shouldReturnPasswordIsNotPresentWhenPasswordIsNotPresent() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - jsonPath("$.password", is("Password should be added")) - ); + .andExpectAll( + status().isBadRequest(), + jsonPath("$.password", is("Password should be added")) + ); } @DisplayName("Should return password is short when password is short") @@ -56,21 +55,21 @@ void shouldReturnPasswordIsNotPresentWhenPasswordIsNotPresent() throws Exception void shouldReturnPasswordIsNotLongEnoughWhenPasswordIsShort() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1Aa" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1Aa" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - jsonPath( - "$.password", - is("Invalid password: must be at least 8 characters long")) - ); + .andExpectAll( + status().isBadRequest(), + jsonPath( + "$.password", + is("Invalid password: must be at least 8 characters long")) + ); } @@ -79,22 +78,22 @@ void shouldReturnPasswordIsNotLongEnoughWhenPasswordIsShort() throws Exception { void shouldReturnPasswordContainsNoDigitsIfItContainsNoDigits() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "aAaaaaaaaaaaaaaaaaaaaaaa" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "aAaaaaaaaaaaaaaaaaaaaaaa" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - jsonPath( - "$.password", - is("Invalid password: must contain at least one digit") - ) - ); + .andExpectAll( + status().isBadRequest(), + jsonPath( + "$.password", + is("Invalid password: must contain at least one digit") + ) + ); } @@ -103,22 +102,22 @@ void shouldReturnPasswordContainsNoDigitsIfItContainsNoDigits() throws Exception void shouldReturnPasswordContainsNoUpperCaseIfPasswordContainsNoUppercase() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1aaaaaaaaaaaaaaaaaaaaaaa" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1aaaaaaaaaaaaaaaaaaaaaaa" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - jsonPath( - "$.password", - is("Invalid password: must contain at least one uppercase letter") - ) - ); + .andExpectAll( + status().isBadRequest(), + jsonPath( + "$.password", + is("Invalid password: must contain at least one uppercase letter") + ) + ); } @@ -127,22 +126,22 @@ void shouldReturnPasswordContainsNoUpperCaseIfPasswordContainsNoUppercase() thro void shouldReturnPasswordContainsNoLowerCaseIfPasswordContainsNoLowercase() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1AAAAAAAAAAAAAAAAAAAAAA" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1AAAAAAAAAAAAAAAAAAAAAA" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON) .content(content)) - .andExpectAll(status().isBadRequest(), + .andExpectAll(status().isBadRequest(), jsonPath( - "$.password", - is("Invalid password: must contain at least one lowercase letter") + "$.password", + is("Invalid password: must contain at least one lowercase letter") ) - ); + ); } @DisplayName("Should return password contains white space when password contains white space") @@ -150,22 +149,22 @@ void shouldReturnPasswordContainsNoLowerCaseIfPasswordContainsNoLowercase() thro void shouldReturnPasswordContainsWhiteSpaceIfContainsWhiteSpace() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": "1 A c a 2 b B a 2" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": "1 A c a 2 b B a 2" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - jsonPath( - "$.password", - is("Invalid password: must not contain whitespace") - ) - ); + .andExpectAll( + status().isBadRequest(), + jsonPath( + "$.password", + is("Invalid password: must not contain whitespace") + ) + ); } @DisplayName("Should return password is invalid with all errors if it has all errors") @@ -173,24 +172,24 @@ void shouldReturnPasswordContainsWhiteSpaceIfContainsWhiteSpace() throws Excepti void shouldReturnPasswordIsInvalidWithAllErrorsIfItHasAllErrors() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john@doe.com", - "password": " " - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john@doe.com", + "password": " " + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - jsonPath( - "$.password", - is("Invalid password: must be at least 8 characters long," - + " must not contain whitespace, must contain at least one digit," - + " must contain at least one uppercase letter," - + " must contain at least one lowercase letter") - )); + .andExpectAll( + status().isBadRequest(), + jsonPath( + "$.password", + is("Invalid password: must be at least 8 characters long," + + " must not contain whitespace, must contain at least one digit," + + " must contain at least one uppercase letter," + + " must contain at least one lowercase letter") + )); } @DisplayName("Should return email is not valid when email in not valid") @@ -198,22 +197,22 @@ void shouldReturnPasswordIsInvalidWithAllErrorsIfItHasAllErrors() throws Excepti void shouldReturnEmailIsInvalidWhenEmailIsInvalid() throws Exception { String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "john.doe.com", - "password": "Aa2aaaaaBBBBaaaaa" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "john.doe.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - jsonPath( - "$.email", - is("must be a well-formed email address") - ) - ); + .andExpectAll( + status().isBadRequest(), + jsonPath( + "$.email", + is("must be a well-formed email address") + ) + ); } @@ -223,19 +222,19 @@ void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { Mockito.when(userRepository.save(Mockito.any())).thenThrow(new RuntimeException("Email is already taken")); String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "asd@asd.com", - "password": "Aa2aaaaaBBBBaaaaa" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "asd@asd.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isBadRequest(), - content().string("Email is already taken") - ); + .andExpectAll( + status().isBadRequest(), + content().string("Email is already taken") + ); } @DisplayName("Should return email is duplicated when email is duplicated") @@ -244,19 +243,19 @@ void shouldReturnUserSuccessfullyCreatedIfEverythingIsCorrect() throws Exception Mockito.when(userRepository.save(Mockito.any())).thenReturn(User.builder().id(1).build()); String content = """ - { - "firstName": "John", - "lastName": "Doe", - "email": "asd@asd.com", - "password": "Aa2aaaaaBBBBaaaaa" - } - """; + { + "firstName": "John", + "lastName": "Doe", + "email": "asd@asd.com", + "password": "Aa2aaaaaBBBBaaaaa" + } + """; this.mockMvc.perform(post("/register") .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpectAll( - status().isCreated(), - header().string("Location", "/users/1") - ); + .andExpectAll( + status().isCreated(), + header().string("Location", "/users/1") + ); } } \ No newline at end of file From a2fbbe53bc29b435ff7ab54acd14de47e0062a52 Mon Sep 17 00:00:00 2001 From: Hsbalazs Date: Wed, 10 Jul 2024 21:07:19 +0200 Subject: [PATCH 19/19] fix: line length in row 224 reduced under 100 in UserControllerTest --- .../greenfoxacademy/backend/controller/UserControllerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 3403b552..51dcaa89 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -220,7 +220,8 @@ void shouldReturnEmailIsInvalidWhenEmailIsInvalid() throws Exception { @Test void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { - Mockito.when(userRepository.save(Mockito.any())).thenThrow(new RuntimeException("Email is already taken")); + Mockito.when(userRepository.save(Mockito.any())) + .thenThrow(new RuntimeException("Email is already taken")); String content = """ { "firstName": "John",