diff --git a/apps/angular/5-crud-application/src/app/app.component.ts b/apps/angular/5-crud-application/src/app/app.component.ts index 9152ff5e4..86f8ae5db 100644 --- a/apps/angular/5-crud-application/src/app/app.component.ts +++ b/apps/angular/5-crud-application/src/app/app.component.ts @@ -1,50 +1,46 @@ import { CommonModule } from '@angular/common'; -import { HttpClient } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { randText } from '@ngneat/falso'; +import { Component, inject, OnInit } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { AppItemComponent } from './todos/components/item.component'; +import { AppGlobalLoaderComponent } from './todos/components/loader-global.component'; +import { fetchTodos } from './todos/stores/todos.actions'; +import { + selectorFetchErroredGlobal, + selectorIsGlobalLoaderVisible, + selectorTodos, +} from './todos/stores/todos.selectors'; @Component({ - imports: [CommonModule], + imports: [CommonModule, AppGlobalLoaderComponent, AppItemComponent], + providers: [], selector: 'app-root', template: ` -
- {{ todo.title }} - -
+ @if (hasErroredGlobal()) { +

Error fetching todos

+ } @else if (isGlobalLoaderVisble()) { + + } @else { + @for (todo of todos(); track todo.id) { + + } @empty { +

There are no todos...

+ } + } `, styles: [], }) export class AppComponent implements OnInit { - todos!: any[]; - - constructor(private http: HttpClient) {} + private readonly store = inject(Store); + public readonly isGlobalLoaderVisble = this.store.selectSignal( + selectorIsGlobalLoaderVisible, + ); + public readonly hasErroredGlobal = this.store.selectSignal( + selectorFetchErroredGlobal, + ); + public readonly todos = this.store.selectSignal(selectorTodos); ngOnInit(): void { - this.http - .get('https://jsonplaceholder.typicode.com/todos') - .subscribe((todos) => { - this.todos = todos; - }); - } - - update(todo: any) { - this.http - .put( - `https://jsonplaceholder.typicode.com/todos/${todo.id}`, - JSON.stringify({ - todo: todo.id, - title: randText(), - body: todo.body, - userId: todo.userId, - }), - { - headers: { - 'Content-type': 'application/json; charset=UTF-8', - }, - }, - ) - .subscribe((todoUpdated: any) => { - this.todos[todoUpdated.id - 1] = todoUpdated; - }); + console.log('hello'); + this.store.dispatch(fetchTodos()); } } diff --git a/apps/angular/5-crud-application/src/app/app.config.ts b/apps/angular/5-crud-application/src/app/app.config.ts index 1c0c9422f..4877f5bb7 100644 --- a/apps/angular/5-crud-application/src/app/app.config.ts +++ b/apps/angular/5-crud-application/src/app/app.config.ts @@ -1,6 +1,24 @@ import { provideHttpClient } from '@angular/common/http'; -import { ApplicationConfig } from '@angular/core'; +import { ApplicationConfig, isDevMode } from '@angular/core'; +import { provideEffects } from '@ngrx/effects'; +import { provideState, provideStore } from '@ngrx/store'; +import { provideStoreDevtools } from '@ngrx/store-devtools'; +import { TodosEffects } from './todos/stores/todos.effects'; +import { todosReducer } from './todos/stores/todos.reducer'; export const appConfig: ApplicationConfig = { - providers: [provideHttpClient()], + providers: [ + provideHttpClient(), + provideStore(), + provideState({ name: 'todosCrud', reducer: todosReducer }), + provideEffects(TodosEffects), + provideStoreDevtools({ + maxAge: 25, // Retains last 25 states + logOnly: !isDevMode(), // Restrict extension to log-only mode + autoPause: true, // Pauses recording actions and state changes when the extension window is not open + trace: false, // If set to true, will include stack trace for every dispatched action, so you can see it in trace tab jumping directly to that part of code + traceLimit: 75, // maximum stack trace frames to be stored (in case trace option was provided as true) + connectInZone: true, // If set to true, the connection is established within the Angular zone + }), + ], }; diff --git a/apps/angular/5-crud-application/src/app/todos/components/item.component.ts b/apps/angular/5-crud-application/src/app/todos/components/item.component.ts new file mode 100644 index 000000000..dbe71ae51 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/components/item.component.ts @@ -0,0 +1,58 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject, input } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { ITodo } from '../interfaces/todo.interface'; +import { deleteTodo, updateTodo } from '../stores/todos.actions'; +import { + selectorFetchErroredLocal, + selectorFetchErroredLocalMessage, +} from '../stores/todos.selectors'; +import { AppLocalLoaderComponent } from './loader-local.component'; + +@Component({ + imports: [CommonModule, AppLocalLoaderComponent], + providers: [], + selector: 'app-item', + template: ` +
+ @if (todo().isLoading) { + + } @else if ( + hasErroredLocal().status && hasErroredLocal().todoId === todo().id + ) { +

{{ hasErroredLocalMessage() }}

+ } @else { + {{ todo().title }} + + + } +
+ `, + styles: ` + .isLoading { + background-color: red; + } + `, +}) +export class AppItemComponent { + todo = input.required(); + private readonly store = inject(Store); + public readonly hasErroredLocal = this.store.selectSignal( + selectorFetchErroredLocal, + ); + public readonly hasErroredLocalMessage = this.store.selectSignal( + selectorFetchErroredLocalMessage, + ); + + onUpdateTodo(todo: ITodo) { + this.store.dispatch(updateTodo({ todo })); + } + + onDeleteTodo(id: number) { + this.store.dispatch(deleteTodo({ id })); + } +} diff --git a/apps/angular/5-crud-application/src/app/todos/components/loader-global.component.ts b/apps/angular/5-crud-application/src/app/todos/components/loader-global.component.ts new file mode 100644 index 000000000..5d12aa0c4 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/components/loader-global.component.ts @@ -0,0 +1,46 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; + +@Component({ + imports: [CommonModule], + selector: 'app-global-loader', + template: ` +
+ `, + styles: ` + .loader { + width: 100vw; + height: 100vh; + } + .loader_gradient { + position: absolute; + left: 50%; + top: 50%; + width: 50px; + --b: 8px; + aspect-ratio: 1; + border-radius: 50%; + padding: 1px; + background: conic-gradient(#0000 10%, #f03355) content-box; + -webkit-mask: repeating-conic-gradient( + #0000 0deg, + #000 1deg 20deg, + #0000 21deg 36deg + ), + radial-gradient( + farthest-side, + #0000 calc(100% - var(--b) - 1px), + #000 calc(100% - var(--b)) + ); + -webkit-mask-composite: destination-in; + mask-composite: intersect; + animation: l4 1s infinite steps(10); + } + @keyframes l4 { + to { + transform: rotate(1turn); + } + } + `, +}) +export class AppGlobalLoaderComponent {} diff --git a/apps/angular/5-crud-application/src/app/todos/components/loader-local.component.ts b/apps/angular/5-crud-application/src/app/todos/components/loader-local.component.ts new file mode 100644 index 000000000..8666d3a48 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/components/loader-local.component.ts @@ -0,0 +1,39 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; + +@Component({ + imports: [CommonModule], + selector: 'app-local-loader', + template: ` +
+ `, + styles: ` + .loader_gradient { + width: 20px; + --b: 8px; + aspect-ratio: 1; + border-radius: 50%; + padding: 1px; + background: conic-gradient(#0000 10%, #f03355) content-box; + -webkit-mask: repeating-conic-gradient( + #0000 0deg, + #000 1deg 20deg, + #0000 21deg 36deg + ), + radial-gradient( + farthest-side, + #0000 calc(100% - var(--b) - 1px), + #000 calc(100% - var(--b)) + ); + -webkit-mask-composite: destination-in; + mask-composite: intersect; + animation: l4 1s infinite steps(10); + } + @keyframes l4 { + to { + transform: rotate(1turn); + } + } + `, +}) +export class AppLocalLoaderComponent {} diff --git a/apps/angular/5-crud-application/src/app/todos/interfaces/todo.interface.ts b/apps/angular/5-crud-application/src/app/todos/interfaces/todo.interface.ts new file mode 100644 index 000000000..aed88a5d8 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/interfaces/todo.interface.ts @@ -0,0 +1,7 @@ +export interface ITodo { + completed: boolean; + title: string; + userId: number; + id: number; + isLoading?: boolean; +} diff --git a/apps/angular/5-crud-application/src/app/todos/services/todos.service.ts b/apps/angular/5-crud-application/src/app/todos/services/todos.service.ts new file mode 100644 index 000000000..eef7cacb5 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/services/todos.service.ts @@ -0,0 +1,46 @@ +import { HttpClient } from '@angular/common/http'; +import { inject, Injectable } from '@angular/core'; +import { randText } from '@ngneat/falso'; +import { map, Observable } from 'rxjs'; +import { ITodo } from '../interfaces/todo.interface'; +import { Todo } from './todos'; + +@Injectable({ + providedIn: 'root', +}) +export class TodosService extends Todo { + private http = inject(HttpClient); + private readonly baseUrl = 'https://jsonplaceholder.typicode.com/todos'; + + getAll(): Observable { + return this.http + .get(this.baseUrl) + .pipe( + map((todos: ITodo[]) => + todos.map((todo: ITodo) => ({ ...todo, isLoading: false })), + ), + ); + } + + updateTodo(todo: ITodo): Observable { + return this.http.put( + `${this.baseUrl}/${todo.id}`, + JSON.stringify({ + title: randText(), + completed: false, + userId: todo.userId, + id: todo.id, + isLoading: false, + }), + { + headers: { + 'Content-type': 'application/json; charset=UTF-8', + }, + }, + ); + } + + deleteTodo(id: number): Observable { + return this.http.delete(`${this.baseUrl}/${id}`); + } +} diff --git a/apps/angular/5-crud-application/src/app/todos/services/todos.ts b/apps/angular/5-crud-application/src/app/todos/services/todos.ts new file mode 100644 index 000000000..09a0b850c --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/services/todos.ts @@ -0,0 +1,8 @@ +import { Observable } from 'rxjs'; +import { ITodo } from '../interfaces/todo.interface'; + +export abstract class Todo { + abstract getAll(): Observable; + abstract updateTodo(todo: ITodo): Observable; + abstract deleteTodo(id: number): Observable; +} diff --git a/apps/angular/5-crud-application/src/app/todos/stores/todos.actions.ts b/apps/angular/5-crud-application/src/app/todos/stores/todos.actions.ts new file mode 100644 index 000000000..5affbc676 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/stores/todos.actions.ts @@ -0,0 +1,64 @@ +import { createAction, props } from '@ngrx/store'; +import { ITodo } from '../interfaces/todo.interface'; + +export const showGlobalLoader = createAction( + '[Todos] Show Global Loader', + props<{ isGlobalLoaderVisible: true }>, +); + +export const hideGlobalLoader = createAction( + '[Todos] Hide Global Loader', + props<{ isGlobalLoaderVisible: false }>, +); + +export const showLocalLoader = createAction( + '[Todos] Show Local Loader', + props<{ isLocalLoaderVisible: true }>, +); + +export const hideLocalLoader = createAction( + '[Todos] Hide Local Loader', + props<{ isLocalLoaderVisible: false }>, +); + +export const fetchTodos = createAction('[Todos] Fetch Todos'); + +export const fetchTodosSuccess = createAction( + '[Todos] Fetch Todos Success', + props<{ todos: ITodo[] }>(), +); + +export const fetchTodosError = createAction('[Todos] Fetch Todos Error'); + +export const updateTodo = createAction( + '[Todos] Update Todo', + props<{ todo: ITodo }>(), +); + +export const updateTodoSuccess = createAction( + '[Todos] Update Todo Success', + props<{ todo: ITodo }>(), +); + +export const updateTodoError = createAction( + '[Todos] Update Todo Error', + props<{ message: string; id: number }>(), +); + +export const deleteTodo = createAction( + '[Todos] Delete Todo', + props<{ + id: number; + }>(), +); + +export const deleteTodoSuccess = createAction( + '[Todos] Delete Todo Success', + props<{ + id: number; + }>(), +); +export const deleteTodoError = createAction( + '[Todos] Delete Todo Error', + props<{ message: string }>(), +); diff --git a/apps/angular/5-crud-application/src/app/todos/stores/todos.effects.ts b/apps/angular/5-crud-application/src/app/todos/stores/todos.effects.ts new file mode 100644 index 000000000..fc9c2e602 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/stores/todos.effects.ts @@ -0,0 +1,61 @@ +import { Injectable, inject } from '@angular/core'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { of } from 'rxjs'; +import { catchError, exhaustMap, map } from 'rxjs/operators'; +import { TodosService } from '../services/todos.service'; +import * as todosActions from './todos.actions'; + +@Injectable() +export class TodosEffects { + private actions$ = inject(Actions); + private todoService = inject(TodosService); + + loadTodos$ = createEffect(() => { + return this.actions$.pipe( + ofType(todosActions.fetchTodos), + exhaustMap(() => + this.todoService.getAll().pipe( + map((todos) => todosActions.fetchTodosSuccess({ todos })), + catchError(() => of(todosActions.fetchTodosError())), + ), + ), + ); + }); + + updateTodo$ = createEffect(() => { + return this.actions$.pipe( + ofType(todosActions.updateTodo), + exhaustMap(({ todo }) => + this.todoService.updateTodo(todo).pipe( + map((todo) => todosActions.updateTodoSuccess({ todo })), + catchError((err) => + of( + todosActions.updateTodoError({ + message: err.message, + id: todo.id, + }), + ), + ), + ), + ), + ); + }); + + deleteTodo$ = createEffect(() => { + return this.actions$.pipe( + ofType(todosActions.deleteTodo), + exhaustMap(({ id }) => + this.todoService.deleteTodo(id).pipe( + map(() => todosActions.deleteTodoSuccess({ id })), + catchError((err) => + of( + todosActions.deleteTodoError({ + message: err.message, + }), + ), + ), + ), + ), + ); + }); +} diff --git a/apps/angular/5-crud-application/src/app/todos/stores/todos.reducer.ts b/apps/angular/5-crud-application/src/app/todos/stores/todos.reducer.ts new file mode 100644 index 000000000..cabcd3620 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/stores/todos.reducer.ts @@ -0,0 +1,68 @@ +import { createReducer, on } from '@ngrx/store'; +import { ITodo } from '../interfaces/todo.interface'; +import * as TodosActions from './todos.actions'; + +export interface IState { + isGlobalLoaderVisible: boolean; + todos: ITodo[]; + hasErroredGlobal: boolean; + hasErroredLocal: { + todoId: number; + status: boolean; + }; + hasErroredLocalMessage: string | null; +} + +export const initialState: IState = { + isGlobalLoaderVisible: true, + todos: [], + hasErroredGlobal: false, + hasErroredLocal: { + todoId: 0, + status: false, + }, + hasErroredLocalMessage: null, +}; + +export const todosReducer = createReducer( + initialState, + on(TodosActions.showGlobalLoader, (state) => ({ + ...state, + isGlobalLoaderVisible: true, + })), + on(TodosActions.hideGlobalLoader, (state) => ({ + ...state, + isGlobalLoaderVisible: false, + })), + on(TodosActions.fetchTodosSuccess, (state, { todos }) => ({ + ...state, + todos, + isGlobalLoaderVisible: false, + })), + on(TodosActions.fetchTodosError, (state) => ({ ...state, hasErrored: true })), + on(TodosActions.updateTodo, (state, { todo }) => ({ + ...state, + todos: state.todos.map((todoEl) => + todoEl.id === todo.id ? { ...todoEl, isLoading: true } : todoEl, + ), + })), + on(TodosActions.updateTodoSuccess, (state, { todo }) => ({ + ...state, + todos: state.todos.map((todoEl) => (todoEl.id === todo.id ? todo : todoEl)), + })), + on(TodosActions.updateTodoError, (state, { message, id }) => ({ + ...state, + hasErroredLocal: { + status: true, + todoId: id, + }, + hasErroredLocalMessage: message, + todos: state.todos.map((todoEl) => + todoEl.id === id ? { ...todoEl, isLoading: false } : todoEl, + ), + })), + on(TodosActions.deleteTodoSuccess, (state, { id }) => ({ + ...state, + todos: state.todos.filter((todo) => todo.id != id), + })), +); diff --git a/apps/angular/5-crud-application/src/app/todos/stores/todos.selectors.ts b/apps/angular/5-crud-application/src/app/todos/stores/todos.selectors.ts new file mode 100644 index 000000000..763adda74 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/todos/stores/todos.selectors.ts @@ -0,0 +1,31 @@ +import { createFeatureSelector, createSelector } from '@ngrx/store'; +import { IState as featureState } from './todos.reducer'; + +export const featureKey = 'todosCrud'; + +export const selectFeature = createFeatureSelector(featureKey); + +export const selectorIsGlobalLoaderVisible = createSelector( + selectFeature, + (state: featureState) => state.isGlobalLoaderVisible, +); + +export const selectorTodos = createSelector( + selectFeature, + (state: featureState) => state.todos, +); + +export const selectorFetchErroredGlobal = createSelector( + selectFeature, + (state: featureState) => state.hasErroredGlobal, +); + +export const selectorFetchErroredLocal = createSelector( + selectFeature, + (state: featureState) => state.hasErroredLocal, +); + +export const selectorFetchErroredLocalMessage = createSelector( + selectFeature, + (state: featureState) => state.hasErroredLocalMessage, +); diff --git a/docs copy/.gitignore b/docs copy/.gitignore new file mode 100644 index 000000000..49ceb2158 --- /dev/null +++ b/docs copy/.gitignore @@ -0,0 +1,22 @@ +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store +.vercel diff --git a/docs copy/.vscode/extensions.json b/docs copy/.vscode/extensions.json new file mode 100644 index 000000000..22a15055d --- /dev/null +++ b/docs copy/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + "recommendations": ["astro-build.astro-vscode"], + "unwantedRecommendations": [] +} diff --git a/docs copy/.vscode/launch.json b/docs copy/.vscode/launch.json new file mode 100644 index 000000000..d64220976 --- /dev/null +++ b/docs copy/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "command": "./node_modules/.bin/astro dev", + "name": "Development server", + "request": "launch", + "type": "node-terminal" + } + ] +} diff --git a/docs copy/.vscode/settings.json b/docs copy/.vscode/settings.json new file mode 100644 index 000000000..1c5c156df --- /dev/null +++ b/docs copy/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.wordWrapColumn": 120 +} diff --git a/docs copy/README.md b/docs copy/README.md new file mode 100644 index 000000000..25d1048bc --- /dev/null +++ b/docs copy/README.md @@ -0,0 +1,52 @@ +# Starlight Starter Kit: Basics + +``` +npm create astro@latest -- --template starlight +``` + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) +[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) + +> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! + +## 🚀 Project Structure + +Inside of your Astro + Starlight project, you'll see the following folders and files: + +``` +. +├── public/ +├── src/ +│ ├── assets/ +│ ├── content/ +│ │ ├── docs/ +│ │ └── config.ts +│ └── env.d.ts +├── astro.config.mjs +├── package.json +└── tsconfig.json +``` + +Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. + +Images can be added to `src/assets/` and embedded in Markdown with a relative link. + +Static assets, like favicons, can be placed in the `public/` directory. + +## 🧞 Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `npm ci` | Installs dependencies | +| `npm run dev` | Starts local dev server at `localhost:4321` | +| `npm run build` | Build your production site to `./dist/` | +| `npm run preview` | Preview your build locally, before deploying | +| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Get help using the Astro CLI | + +## 👀 Want to learn more? + +Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). +f diff --git a/docs copy/astro.config.mjs b/docs copy/astro.config.mjs new file mode 100644 index 000000000..953462156 --- /dev/null +++ b/docs copy/astro.config.mjs @@ -0,0 +1,124 @@ +import starlight from '@astrojs/starlight'; +import { defineConfig } from 'astro/config'; +import svelte from '@astrojs/svelte'; +import vercel from '@astrojs/vercel/serverless'; + +export const locales = { + root: { + label: 'English', + lang: 'en' + }, + es: { + label: 'Español', + lang: 'es' + }, + fr: { + label: 'Français', + lang: 'fr' + }, + pt: { + label: 'Português', + lang: 'pt' + }, + ru: { + label: 'Русский', + lang: 'ru' + }, + 'zh-cn': { + label: '简体中文', + lang: 'zh-CN' + } +}; + + +// https://astro.build/config +export default defineConfig({ + integrations: [starlight({ + title: 'Angular Challenges', + logo: { + src: './public/angular-challenge.webp', + alt: 'angular challenges logo' + }, + favicon: './angular-challenge.ico', + social: { + github: 'https://github.com/tomalaforge/angular-challenges', + linkedin: 'https://www.linkedin.com/in/thomas-laforge-2b05a945/', + twitter: 'https://twitter.com/laforge_toma' + }, + customCss: ['./src/styles/custom-css.css'], + sidebar: [{ + label: 'Guides', + autogenerate: { + directory: 'guides' + }, + translations: { + es: 'Guías', + fr: 'Guides', + pt: 'Guias', + ru: 'Руководство', + 'zh-CN': '指南' + } + }, + { + label: 'Leaderboard', + autogenerate: { + directory: 'leaderboard', + collapsed: true + }, + translations: { + es: 'Leaderboard', + fr: 'Leaderboard', + pt: 'Tabela de Classificação', + ru: 'Leaderboard', + 'zh-CN': '排行榜' + } + }, + { + label: 'Challenges', + autogenerate: { + directory: 'challenges' + }, + translations: { + es: 'Desafíos', + fr: 'Challenges', + pt: 'Desafios', + ru: 'Задачи', + 'zh-CN': '挑战' + } + }], + head: [{ + tag: 'script', + attrs: { + src: 'https://www.googletagmanager.com/gtag/js?id=G-6BXJ62W6G5', + async: true + } + }, { + tag: 'script', + content: ` + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + + gtag('config', 'G-6BXJ62W6G5'); + ` + }, { + tag: 'script', + attrs: { + src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2438923752868254', + async: true + } + }], + components: { + MarkdownContent: './src/components/Content.astro', + TableOfContents: './src/components/TableOfContents.astro', + PageTitle: './src/components/PageTitle.astro', + MobileMenuFooter: './src/components/MobileMenuFooter.astro', + SiteTitle: './src/components/SiteTitle.astro', + Hero: './src/components/Hero.astro' + }, + defaultLocale: 'root', + locales + }), svelte()], + output: "hybrid", + adapter: vercel() +}); diff --git a/docs copy/package-lock.json b/docs copy/package-lock.json new file mode 100644 index 000000000..626127ffe --- /dev/null +++ b/docs copy/package-lock.json @@ -0,0 +1,11186 @@ +{ + "name": "angular-challenges-docs", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "angular-challenges-docs", + "version": "0.0.1", + "dependencies": { + "@astrojs/starlight": "^0.15.1", + "@astrojs/svelte": "^5.2.0", + "@astrojs/vercel": "^7.5.0", + "@fontsource/ibm-plex-serif": "^5.0.8", + "astro": "^4.0.0", + "sharp": "^0.32.5", + "svelte": "^4.2.12", + "typescript": "^5.4.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.7.0.tgz", + "integrity": "sha512-XpC8MAaWjD1ff6/IfkRq/5k1EFj6zhCNqXRd5J43SVJEBj/Bsmizkm8N0xOYscGcDFQkRgEw6/eKnI5x/1l6aA==" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.4.0.tgz", + "integrity": "sha512-6B13lz5n6BrbTqCTwhXjJXuR1sqiX/H6rTxzlXx+lN1NnV4jgnq/KJldCQaUWJzPL5SiWahQyinxAbxQtwgPHA==" + }, + "node_modules/@astrojs/markdown-remark": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-4.0.1.tgz", + "integrity": "sha512-RU4ESnqvyLpj8WZs0n5elS6idaDdtIIm7mIpMaRNPCebpxMjfcfdwcmBwz83ktAj5d2eO5bC3z92TcGdli+lRw==", + "dependencies": { + "@astrojs/prism": "^3.0.0", + "github-slugger": "^2.0.0", + "import-meta-resolve": "^4.0.0", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.0", + "remark-gfm": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "remark-smartypants": "^2.0.0", + "shikiji": "^0.6.13", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@astrojs/markdown-remark/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-2.0.1.tgz", + "integrity": "sha512-lWbiNoVV/6DO8hAf6eZmcN28hY/herif9eglw2PXZ5lEPoRu175BvBtuNTt9rH9YA/Ldm5mkNXhvMWNEnMqJkw==", + "dependencies": { + "@astrojs/markdown-remark": "4.0.1", + "@mdx-js/mdx": "^3.0.0", + "acorn": "^8.11.2", + "es-module-lexer": "^1.4.1", + "estree-util-visit": "^2.0.0", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "hast-util-to-html": "^9.0.0", + "kleur": "^4.1.4", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.0", + "remark-smartypants": "^2.0.0", + "source-map": "^0.7.4", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1" + }, + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "astro": "^4.0.0" + } + }, + "node_modules/@astrojs/mdx/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@astrojs/mdx/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.0.0.tgz", + "integrity": "sha512-g61lZupWq1bYbcBnYZqdjndShr/J3l/oFobBKPA3+qMat146zce3nz2kdO4giGbhYDt4gYdhmoBz0vZJ4sIurQ==", + "dependencies": { + "prismjs": "^1.29.0" + }, + "engines": { + "node": ">=18.14.1" + } + }, + "node_modules/@astrojs/sitemap": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.0.3.tgz", + "integrity": "sha512-+GRKp1yho9dpHBcMcU6JpbL41k0yYZghOkNsMRb8QIRflbGHvd787tdv9oIZ5NJj0SqAuOlqp2UpqLkJXuAe2A==", + "dependencies": { + "sitemap": "^7.1.1", + "zod": "^3.22.4" + } + }, + "node_modules/@astrojs/starlight": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.15.1.tgz", + "integrity": "sha512-5AdySPQOG/+r1vHSNotQAGqhQIfF68hS8PfV+z4M2ewnrWoeCsHI3yYRFYgSRsVofcOEGTHiIryTRG/uRIvDkQ==", + "dependencies": { + "@astrojs/mdx": "^2.0.0", + "@astrojs/sitemap": "^3.0.3", + "@pagefind/default-ui": "^1.0.3", + "@types/hast": "^3.0.3", + "@types/mdast": "^4.0.3", + "astro-expressive-code": "^0.30.1", + "bcp-47": "^2.1.0", + "execa": "^8.0.1", + "hast-util-select": "^6.0.2", + "hastscript": "^8.0.0", + "mdast-util-directive": "^3.0.0", + "pagefind": "^1.0.3", + "rehype": "^13.0.1", + "remark-directive": "^3.0.0", + "unified": "^11.0.4", + "unist-util-remove": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1" + }, + "peerDependencies": { + "astro": "^4.0.0" + } + }, + "node_modules/@astrojs/starlight/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@astrojs/starlight/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/starlight/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/starlight/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/starlight/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/starlight/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/starlight/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/starlight/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/svelte": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@astrojs/svelte/-/svelte-5.2.0.tgz", + "integrity": "sha512-GmwbXks2WMkmAfl0rlPM/2gA1RtmZzjGV2mOceV3g7QNyjIsSYBPKrlEnSFnuR+YMvlAtWdbMFBsb3gtGxnTTg==", + "dependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte2tsx": "^0.6.27" + }, + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "astro": "^4.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.56", + "typescript": "^5.3.3" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.1.tgz", + "integrity": "sha512-4C4UERETjXpC4WpBXDbkgNVgHyWfG3B/NKY46e7w5H134UDOFqUJKpsLm0UYmuupW+aJmRgeScrDNfvZ5WV80A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-android-arm64": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.1.tgz", + "integrity": "sha512-TrTaFJ9pXgfXEiJKQ3yQRelpQFqgRzVR9it8DbeRzG0RX7mKUy0bqhCFsgevwXLJepQKTnLl95TnPGf9T9AMOA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.1.tgz", + "integrity": "sha512-fz7jN6ahTI3cKzDO2otQuybts5cyu0feymg0bjvYCBrZQ8tSgE8pc0sSNEuGvifrQJWiwx9F05BowihmLxeQKw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.1.tgz", + "integrity": "sha512-WTvdz7SLMlJpektdrnWRUN9C0N2qNHwNbWpNo0a3Tod3gb9leX+yrYdCeB7VV36OtoyiPAivl7/xZ3G1z5h20g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.1.tgz", + "integrity": "sha512-dBHQl+7wZzBYcIF6o4k2XkAfwP2ks1mYW2q/Gzv9n39uDcDiAGDqEyml08OdY0BIct0yLSPkDTqn4i6czpBLLw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.1.tgz", + "integrity": "sha512-bur4JOxvYxfrAmocRJIW0SADs3QdEYK6TQ7dTNz6Z4/lySeu3Z1H/+tl0a4qDYv0bCdBpUYM0sYa/X+9ZqgfSQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.1.tgz", + "integrity": "sha512-ssp77SjcDIUSoUyj7DU7/5iwM4ZEluY+N8umtCT9nBRs3u045t0KkW02LTyHouHDomnMXaXSZcCSr2bdMK63kA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.1.tgz", + "integrity": "sha512-Jv1DkIvwEPAb+v25/Unrnnq9BO3F5cbFPT821n3S5litkz+O5NuXuNhqtPx5KtcwOTtaqkTsO+IVzJOsxd11aQ==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.1.tgz", + "integrity": "sha512-zGRDulLTeDemR8DFYyFIQ8kMP02xpUsX4IBikc7lwL9PrwR3gWmX2NopqiGlI2ZVWMl15qZeUjumTwpv18N7sQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.1.tgz", + "integrity": "sha512-VTk/MveyPdMFkYJJPCkYBw07KcTkGU2hLEyqYMsU4NjiOfzoaDTW9PWGRsNwiOA3qI0k/JQPjkl/4FCK1smskQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.1.tgz", + "integrity": "sha512-L+hX8Dtibb02r/OYCsp4sQQIi3ldZkFI0EUkMTDwRfFykXBPptoz/tuuGqEd3bThBSLRWPR6wsixDSgOx/U3Zw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.1.tgz", + "integrity": "sha512-+dI2jVPfM5A8zme8riEoNC7UKk0Lzc7jCj/U89cQIrOjrZTCWZl/+IXUeRT2rEZ5j25lnSA9G9H1Ob9azaF/KQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.1.tgz", + "integrity": "sha512-YY1Exxo2viZ/O2dMHuwQvimJ0SqvL+OAWQLLY6rvXavgQKjhQUzn7nc1Dd29gjB5Fqi00nrBWctJBOyfVMIVxw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@astrojs/svelte/node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.0.2.tgz", + "integrity": "sha512-MpmF/cju2HqUls50WyTHQBZUV3ovV/Uk8k66AN2gwHogNAG8wnW8xtZDhzNBsFJJuvmq1qnzA5kE7YfMJNFv2Q==", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "svelte-hmr": "^0.15.3", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@astrojs/svelte/node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.0.0.tgz", + "integrity": "sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@astrojs/svelte/node_modules/@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@astrojs/svelte/node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "hasInstallScript": true, + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/@astrojs/svelte/node_modules/rollup": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.1.tgz", + "integrity": "sha512-hFi+fU132IvJ2ZuihN56dwgpltpmLZHZWsx27rMCTZ2sYwrqlgL5sECGy1eeV2lAihD8EzChBVVhsXci0wD4Tg==", + "peer": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.1", + "@rollup/rollup-android-arm64": "4.13.1", + "@rollup/rollup-darwin-arm64": "4.13.1", + "@rollup/rollup-darwin-x64": "4.13.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.1", + "@rollup/rollup-linux-arm64-gnu": "4.13.1", + "@rollup/rollup-linux-arm64-musl": "4.13.1", + "@rollup/rollup-linux-riscv64-gnu": "4.13.1", + "@rollup/rollup-linux-s390x-gnu": "4.13.1", + "@rollup/rollup-linux-x64-gnu": "4.13.1", + "@rollup/rollup-linux-x64-musl": "4.13.1", + "@rollup/rollup-win32-arm64-msvc": "4.13.1", + "@rollup/rollup-win32-ia32-msvc": "4.13.1", + "@rollup/rollup-win32-x64-msvc": "4.13.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/@astrojs/svelte/node_modules/vite": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.6.tgz", + "integrity": "sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA==", + "peer": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.36", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.0.4.tgz", + "integrity": "sha512-A+0c7k/Xy293xx6odsYZuXiaHO0PL+bnDoXOc47sGDF5ffIKdKQGRPFl2NMlCF4L0NqN4Ynbgnaip+pPF0s7pQ==", + "dependencies": { + "ci-info": "^3.8.0", + "debug": "^4.3.4", + "dlv": "^1.1.3", + "dset": "^3.1.2", + "is-docker": "^3.0.0", + "is-wsl": "^3.0.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": ">=18.14.1" + } + }, + "node_modules/@astrojs/telemetry/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/@astrojs/vercel": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@astrojs/vercel/-/vercel-7.5.0.tgz", + "integrity": "sha512-RYFZNHkfNgFNb41nblG26ubw5924hAjLYs+Bpp4kttcsYJAX/wavIfDbfZQ/XesDTKwIH+Gi/+3c5bldZePFDA==", + "dependencies": { + "@astrojs/internal-helpers": "0.4.0", + "@vercel/analytics": "^1.0.2", + "@vercel/edge": "^1.1.1", + "@vercel/nft": "^0.26.4", + "esbuild": "^0.19.6", + "fast-glob": "^3.3.2", + "set-cookie-parser": "^2.6.0", + "web-vitals": "^3.4.0" + }, + "peerDependencies": { + "astro": "^4.2.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", + "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.1", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "dependencies": { + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz", + "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "dependencies": { + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", + "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", + "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", + "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", + "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", + "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", + "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", + "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", + "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", + "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", + "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", + "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", + "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", + "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", + "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", + "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", + "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", + "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", + "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", + "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", + "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", + "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", + "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", + "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@expressive-code/core": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.30.1.tgz", + "integrity": "sha512-z11G1lfzzuTJ63C4dGPUIEKxJse5eKrVxqxQJRiuCDH8hPqfIQs/+by04UceSWB0dt5SIFsL5J+7HvCycbc1iA==", + "dependencies": { + "@ctrl/tinycolor": "^3.6.0", + "hast-util-to-html": "^8.0.4", + "hastscript": "^7.2.0", + "postcss": "^8.4.21", + "postcss-nested": "^6.0.1" + } + }, + "node_modules/@expressive-code/core/node_modules/@types/hast": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", + "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@expressive-code/core/node_modules/hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/hast-util-raw": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/hast-util-to-html": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", + "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-raw": "^7.0.0", + "hast-util-whitespace": "^2.0.0", + "html-void-elements": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/hast-util-to-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/@expressive-code/core/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/@expressive-code/core/node_modules/unist-util-position": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/core/node_modules/vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/plugin-frames": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.30.1.tgz", + "integrity": "sha512-fBqd+NWcmlP63q8kNi73b6EuwWZwb+8OIhqWEsEQ/lsoOmT8FVYqsnH+M+TRC9or+U0PNd7Po/ojcFNnS0TAIQ==", + "dependencies": { + "@expressive-code/core": "^0.30.1", + "hastscript": "^7.2.0" + } + }, + "node_modules/@expressive-code/plugin-frames/node_modules/@types/hast": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", + "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@expressive-code/plugin-frames/node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/plugin-frames/node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/plugin-shiki": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.30.1.tgz", + "integrity": "sha512-VoJZWZ1wjW/I+CsHg4/RwurrHdtnF5C5fbXESQCQlnXWOhWBfJnOX1ilx5B11gsH5kEWNoD5WRAt8t0L0V/VJA==", + "dependencies": { + "@expressive-code/core": "^0.30.1", + "shikiji": "^0.8.0" + } + }, + "node_modules/@expressive-code/plugin-shiki/node_modules/shikiji": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/shikiji/-/shikiji-0.8.7.tgz", + "integrity": "sha512-j5usxwI0yHkDTHOuhuSJl9+wT5CNYeYO82dJMSJBlJ/NYT5SIebGcPoL6y9QOyH15wGrJC4LOP2nz5k8mUDGRQ==", + "dependencies": { + "hast-util-to-html": "^9.0.0" + } + }, + "node_modules/@expressive-code/plugin-text-markers": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.30.1.tgz", + "integrity": "sha512-Dtw2lIsAfcfWy/qUhrEW1NwZdgMsI+qeHQ/7Do+W9fMBIoIIHh2GLwmhwkBitoOvLgOJQWsNoBvT42LUp2+16g==", + "dependencies": { + "@expressive-code/core": "^0.30.1", + "hastscript": "^7.2.0", + "unist-util-visit-parents": "^5.1.3" + } + }, + "node_modules/@expressive-code/plugin-text-markers/node_modules/@types/hast": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", + "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@expressive-code/plugin-text-markers/node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@expressive-code/plugin-text-markers/node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@fontsource/ibm-plex-serif": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-serif/-/ibm-plex-serif-5.0.8.tgz", + "integrity": "sha512-KUp1E9Wzf2Umhr2SbpcF9HwgFJmuxvKAARmpl7GDDkIG30R1PMFJWxfSfQ7oX/oVBtomGq5RUTaMMUeE0ngEgw==" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", + "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-to-js": "^2.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@mdx-js/mdx/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pagefind/darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.0.3.tgz", + "integrity": "sha512-vsHDtvao3W4iFCxVc4S0BVhpj3E2MAoIVM7RmuQfGp1Ng22nGLRaMP6FguLO8TMabRJdvp4SVr227hL4WGKOHA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.0.3.tgz", + "integrity": "sha512-NhEXHHYmB/hT6lx5rCcmnVTxH+uIkMAd43bzEqMwHQosqTZEIQfwihmV39H+m8yo7jFvz3zRbJNzhAh7G4PiwA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/default-ui": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.0.3.tgz", + "integrity": "sha512-WieFJXvezyvjZh49I8j7a7Kz3LsXYY2Uep3IWvG5NG05mmiurURXjXc+KyrpIp/iAycSnjrC1TDJ8CdES/ee3A==" + }, + "node_modules/@pagefind/linux-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.0.3.tgz", + "integrity": "sha512-RGsMt4AmGT8WxCSeP09arU7Za6Vf/We4TWHVSbY7vDMuwWql9Ngoib/q1cP9dIAIMdkXh9ePG/S3mGnJYsdzuQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/linux-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.0.3.tgz", + "integrity": "sha512-o+VCKaqImL42scSH1n5gUfppYSNyu3BuGTvtKKgWHmycbL+A3fkFH+ZOFbaLeN7LVTvJqJIOYbk4j2yaq9784Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/windows-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.0.3.tgz", + "integrity": "sha512-S+Yq4FyvXJm4F+iN/wRiLvEEF8Xs9lTKGtQGaRHXJslQyl65dytDDPIULXJXIadrDbnMrnTt4C2YHmEUIyUIHg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.2.tgz", + "integrity": "sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.2.tgz", + "integrity": "sha512-GdxxXbAuM7Y/YQM9/TwwP+L0omeE/lJAR1J+olu36c3LqqZEBdsIWeQ91KBe6nxwOnb06Xh7JS2U5ooWU5/LgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.2.tgz", + "integrity": "sha512-mCMlpzlBgOTdaFs83I4XRr8wNPveJiJX1RLfv4hggyIVhfB5mJfN4P8Z6yKh+oE4Luz+qq1P3kVdWrCKcMYrrA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.2.tgz", + "integrity": "sha512-yUoEvnH0FBef/NbB1u6d3HNGyruAKnN74LrPAfDQL3O32e3k3OSfLrPgSJmgb3PJrBZWfPyt6m4ZhAFa2nZp2A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.2.tgz", + "integrity": "sha512-GYbLs5ErswU/Xs7aGXqzc3RrdEjKdmoCrgzhJWyFL0r5fL3qd1NPcDKDowDnmcoSiGJeU68/Vy+OMUluRxPiLQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.2.tgz", + "integrity": "sha512-L1+D8/wqGnKQIlh4Zre9i4R4b4noxzH5DDciyahX4oOz62CphY7WDWqJoQ66zNR4oScLNOqQJfNSIAe/6TPUmQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.2.tgz", + "integrity": "sha512-tK5eoKFkXdz6vjfkSTCupUzCo40xueTOiOO6PeEIadlNBkadH1wNOH8ILCPIl8by/Gmb5AGAeQOFeLev7iZDOA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.13.2.tgz", + "integrity": "sha512-zvXvAUGGEYi6tYhcDmb9wlOckVbuD+7z3mzInCSTACJ4DQrdSLPNUeDIcAQW39M3q6PDquqLWu7pnO39uSMRzQ==", + "cpu": [ + "ppc64le" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.2.tgz", + "integrity": "sha512-C3GSKvMtdudHCN5HdmAMSRYR2kkhgdOfye4w0xzyii7lebVr4riCgmM6lRiSCnJn2w1Xz7ZZzHKuLrjx5620kw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.1.tgz", + "integrity": "sha512-U564BrhEfaNChdATQaEODtquCC7Ez+8Hxz1h5MAdMYj0AqD0GA9rHCpElajb/sQcaFL6NXmHc5O+7FXpWMa73Q==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.2.tgz", + "integrity": "sha512-xXMLUAMzrtsvh3cZ448vbXqlUa7ZL8z0MwHp63K2IIID2+DeP5iWIT6g1SN7hg1VxPzqx0xZdiDM9l4n9LRU1A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.2.tgz", + "integrity": "sha512-M/JYAWickafUijWPai4ehrjzVPKRCyDb1SLuO+ZyPfoXgeCEAlgPkNXewFZx0zcnoIe3ay4UjXIMdXQXOZXWqA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.2.tgz", + "integrity": "sha512-2YWwoVg9KRkIKaXSh0mz3NmfurpmYoBBTAXA9qt7VXk0Xy12PoOP40EFuau+ajgALbbhi4uTj3tSG3tVseCjuA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.2.tgz", + "integrity": "sha512-2FSsE9aQ6OWD20E498NYKEQLneShWes0NGMPQwxWOdws35qQXH+FplabOSP5zEe1pVjurSDOGEVCE2agFwSEsw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.2.tgz", + "integrity": "sha512-7h7J2nokcdPePdKykd8wtc8QqqkqxIrUz7MHj6aNr8waBRU//NLDVnNjQnqQO6fqtjrtCdftpbTuOKAyrAQETQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.2.1.tgz", + "integrity": "sha512-KaIS0H4EQ3KI2d++TjYqRNgwp8E3M/68e9veR4QtInzA7kKFgcjeiJqb80fuXW+blDy5fmd11PN9g9soz/3ANQ==" + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", + "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", + "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", + "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", + "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/nlcst": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-1.0.2.tgz", + "integrity": "sha512-ykxL/GDDUhqikjU0LIywZvEwb1NTYXTEWf+XgMSS2o6IXIakafPccxZmxgZcvJPZ3yFl2kdL1gJZz3U3iZF3QA==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", + "integrity": "sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@vercel/analytics": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.2.tgz", + "integrity": "sha512-X0rctVWkQV1e5Y300ehVNqpOfSOufo7ieA5PIdna8yX/U7Vjz0GFsGf4qvAhxV02uQ2CVt7GYcrFfddXXK2Y4A==", + "dependencies": { + "server-only": "^0.0.1" + }, + "peerDependencies": { + "next": ">= 13", + "react": "^18 || ^19" + }, + "peerDependenciesMeta": { + "next": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@vercel/edge": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vercel/edge/-/edge-1.1.1.tgz", + "integrity": "sha512-NtKiIbn9Cq6HWGy+qRudz28mz5nxfOJWls5Pnckjw1yCfSX8rhXdvY/il3Sy3Zd5n/sKCM2h7VSCCpJF/oaDrQ==" + }, + "node_modules/@vercel/nft": { + "version": "0.26.4", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.26.4.tgz", + "integrity": "sha512-j4jCOOXke2t8cHZCIxu1dzKLHLcFmYzC3yqAK6MfZznOL1QIJKd0xcFsXK3zcqzU7ScsE2zWkiMMNHGMHgp+FA==", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.5", + "@rollup/pluginutils": "^4.0.0", + "acorn": "^8.6.0", + "acorn-import-attributes": "^1.9.2", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.2", + "node-gyp-build": "^4.2.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vercel/nft/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.4.tgz", + "integrity": "sha512-dNIX/5UEnZvVL94dV2scl4VIooK36D8AteP4xiz7cPKhDbhLhSuWkzG580g+Q7TXJklp+Z21SiaK7/HpLO84Qg==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/astro": { + "version": "4.5.12", + "resolved": "https://registry.npmjs.org/astro/-/astro-4.5.12.tgz", + "integrity": "sha512-xIJcFI2hbyV8+h5pWjL7SKD1jIP0K01fYVAH+gdAt0mJaXy+u8Mj+goD0cPlK6sEaykR+7zxQLYGKJ44U4qarg==", + "dependencies": { + "@astrojs/compiler": "^2.7.0", + "@astrojs/internal-helpers": "0.4.0", + "@astrojs/markdown-remark": "4.3.2", + "@astrojs/telemetry": "3.0.4", + "@babel/core": "^7.24.3", + "@babel/generator": "^7.23.3", + "@babel/parser": "^7.23.3", + "@babel/plugin-transform-react-jsx": "^7.22.5", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "@types/babel__core": "^7.20.4", + "acorn": "^8.11.2", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "boxen": "^7.1.1", + "chokidar": "^3.5.3", + "ci-info": "^4.0.0", + "clsx": "^2.0.0", + "common-ancestor-path": "^1.0.1", + "cookie": "^0.6.0", + "cssesc": "^3.0.0", + "debug": "^4.3.4", + "deterministic-object-hash": "^2.0.1", + "devalue": "^4.3.2", + "diff": "^5.1.0", + "dlv": "^1.1.3", + "dset": "^3.1.3", + "es-module-lexer": "^1.4.1", + "esbuild": "^0.19.6", + "estree-walker": "^3.0.3", + "execa": "^8.0.1", + "fast-glob": "^3.3.2", + "flattie": "^1.1.0", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "html-escaper": "^3.0.3", + "http-cache-semantics": "^4.1.1", + "js-yaml": "^4.1.0", + "kleur": "^4.1.4", + "magic-string": "^0.30.3", + "mime": "^3.0.0", + "ora": "^7.0.1", + "p-limit": "^5.0.0", + "p-queue": "^8.0.1", + "path-to-regexp": "^6.2.1", + "preferred-pm": "^3.1.2", + "prompts": "^2.4.2", + "rehype": "^13.0.1", + "resolve": "^1.22.4", + "semver": "^7.5.4", + "shiki": "^1.1.2", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0", + "tsconfck": "^3.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.1", + "vite": "^5.1.4", + "vitefu": "^0.2.5", + "which-pm": "^2.1.1", + "yargs-parser": "^21.1.1", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.22.4" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": ">=18.14.1", + "npm": ">=6.14.0" + }, + "optionalDependencies": { + "sharp": "^0.32.6" + } + }, + "node_modules/astro-expressive-code": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.30.1.tgz", + "integrity": "sha512-Dr3VbK4HvIXTT8rsvd8PuRW4uZOpfRz9J8noVSSxmx7/M7o73SBtqauBYvxXpGHnagTJPGzYOa9BQS7jDHNUVw==", + "dependencies": { + "remark-expressive-code": "^0.30.1" + }, + "peerDependencies": { + "astro": "^3.3.0 || ^4.0.0-beta" + } + }, + "node_modules/astro/node_modules/@astrojs/markdown-remark": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-4.3.2.tgz", + "integrity": "sha512-4Oa4VaYiBd0MatB+rWIU/0A8pZH/sK3c2QkRYb+OO2lPl+qzevJtWaZY8hAQc4qurIOlRdn6B6ofDAGhWw+DSg==", + "dependencies": { + "@astrojs/prism": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "import-meta-resolve": "^4.0.0", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.0", + "remark-gfm": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "remark-smartypants": "^2.0.0", + "shiki": "^1.1.2", + "unified": "^11.0.4", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.1" + } + }, + "node_modules/astro/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.2.tgz", + "integrity": "sha512-l4U0KDFwzD36j7HdfJ5/TveEQ1fUTjFFQP5qIt9gBqBgu1G8/kCaq5Ok05kd5TG9F8Lltf3MoYsUMw3rNlJ0Yg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/astro/node_modules/@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/astro/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/astro/node_modules/rollup": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.2.tgz", + "integrity": "sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g==", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.2", + "@rollup/rollup-android-arm64": "4.13.2", + "@rollup/rollup-darwin-arm64": "4.13.2", + "@rollup/rollup-darwin-x64": "4.13.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.2", + "@rollup/rollup-linux-arm64-gnu": "4.13.2", + "@rollup/rollup-linux-arm64-musl": "4.13.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.13.2", + "@rollup/rollup-linux-riscv64-gnu": "4.13.2", + "@rollup/rollup-linux-s390x-gnu": "4.13.2", + "@rollup/rollup-linux-x64-gnu": "4.13.2", + "@rollup/rollup-linux-x64-musl": "4.13.2", + "@rollup/rollup-win32-arm64-msvc": "4.13.2", + "@rollup/rollup-win32-ia32-msvc": "4.13.2", + "@rollup/rollup-win32-x64-msvc": "4.13.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/astro/node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/astro/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/astro/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/astro/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/astro/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/astro/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/astro/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/astro/node_modules/vite": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.6.tgz", + "integrity": "sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA==", + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.36", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/astro/node_modules/vite/node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/async-sema": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==" + }, + "node_modules/axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/boxen/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-selector-parser": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.0.4.tgz", + "integrity": "sha512-pnmS1dbKsz6KA4EW4BznyPL2xxkNDRg62hcD0v8g6DEw2W7hxOln5M953jsp9hmw5Dg57S6o/A8GOn37mbAgcQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent-js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", + "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==" + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", + "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dset": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", + "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==" + }, + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + }, + "node_modules/esbuild": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", + "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.10", + "@esbuild/android-arm": "0.19.10", + "@esbuild/android-arm64": "0.19.10", + "@esbuild/android-x64": "0.19.10", + "@esbuild/darwin-arm64": "0.19.10", + "@esbuild/darwin-x64": "0.19.10", + "@esbuild/freebsd-arm64": "0.19.10", + "@esbuild/freebsd-x64": "0.19.10", + "@esbuild/linux-arm": "0.19.10", + "@esbuild/linux-arm64": "0.19.10", + "@esbuild/linux-ia32": "0.19.10", + "@esbuild/linux-loong64": "0.19.10", + "@esbuild/linux-mips64el": "0.19.10", + "@esbuild/linux-ppc64": "0.19.10", + "@esbuild/linux-riscv64": "0.19.10", + "@esbuild/linux-s390x": "0.19.10", + "@esbuild/linux-x64": "0.19.10", + "@esbuild/netbsd-x64": "0.19.10", + "@esbuild/openbsd-x64": "0.19.10", + "@esbuild/sunos-x64": "0.19.10", + "@esbuild/win32-arm64": "0.19.10", + "@esbuild/win32-ia32": "0.19.10", + "@esbuild/win32-x64": "0.19.10" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-visit/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/expressive-code": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.30.1.tgz", + "integrity": "sha512-iD8xtfN8X29jfk0B2U4/ws1pV/8GgRVIGOIDm9f6U9Zcnse1OnD/i+cYkcaOr5MLpVe8eLEr8GvVtZDOBxekrg==", + "dependencies": { + "@expressive-code/core": "^0.30.1", + "@expressive-code/plugin-frames": "^0.30.1", + "@expressive-code/plugin-shiki": "^0.30.1", + "@expressive-code/plugin-text-markers": "^0.30.1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-yarn-workspace-root2": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", + "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", + "dependencies": { + "micromatch": "^4.0.2", + "pkg-dir": "^4.2.0" + } + }, + "node_modules/flattie": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.0.tgz", + "integrity": "sha512-xU99gDEnciIwJdGcBmNHnzTJ/w5AT+VFJOu6sTB6WM8diOYNA3Sa+K1DiEBQ7XH4QikQq3iFW1U+jRVcotQnBw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/hast-util-from-html": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", + "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/hast-util-from-html/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/hast-util-from-parse5/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", + "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/hast-util-raw/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.2.tgz", + "integrity": "sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "not": "^0.1.0", + "nth-check": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/hast-util-select/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.0.tgz", + "integrity": "sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-raw": "^9.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", + "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", + "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==" + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", + "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", + "dependencies": { + "inline-style-parser": "0.2.2" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz", + "integrity": "sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.0.tgz", + "integrity": "sha512-EWiE1FSArNBPUo1cKWtzqgnuRQwEeQbQtnFJRYV1hb1BWDgrAlBU0ExptvZMM/KSA82cDpm2sFGf3Dmc5Mza3w==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/import-meta-resolve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", + "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/load-yaml-file": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", + "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.13.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/load-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/load-yaml-file/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-directive/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-from-markdown/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", + "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-phrasing/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", + "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/mdast-util-to-markdown/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", + "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", + "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", + "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", + "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/micromark-factory-mdx-expression/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/micromark-util-events-to-acorn/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", + "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "node_modules/nlcst-to-string": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz", + "integrity": "sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==", + "dependencies": { + "@types/nlcst": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-abi": { + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", + "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/not": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", + "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" + }, + "node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", + "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.3.0", + "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", + "string-width": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.0.1.tgz", + "integrity": "sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", + "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pagefind": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.0.3.tgz", + "integrity": "sha512-ws7kmMxW6OuxzsOjj3YAx6TYq/54MiE3wfyBM3J5CInbZyBBvM2Z8c8IYvnMkBcb5v2EoB9DewXEekOEiDRu5g==", + "bin": { + "pagefind": "lib/runner/bin.cjs" + }, + "optionalDependencies": { + "@pagefind/darwin-arm64": "1.0.3", + "@pagefind/darwin-x64": "1.0.3", + "@pagefind/linux-arm64": "1.0.3", + "@pagefind/linux-x64": "1.0.3", + "@pagefind/windows-x64": "1.0.3" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-latin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-5.0.1.tgz", + "integrity": "sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==", + "dependencies": { + "nlcst-to-string": "^3.0.0", + "unist-util-modify-children": "^3.0.0", + "unist-util-visit-children": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/prebuild-install/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/preferred-pm": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.1.2.tgz", + "integrity": "sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==", + "dependencies": { + "find-up": "^5.0.0", + "find-yarn-workspace-root2": "1.2.16", + "path-exists": "^4.0.0", + "which-pm": "2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/preferred-pm/node_modules/which-pm": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", + "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", + "dependencies": { + "load-yaml-file": "^0.2.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8.15" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/property-information": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.3.0.tgz", + "integrity": "sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rehype": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.1.tgz", + "integrity": "sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg==", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.0.tgz", + "integrity": "sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/rehype-parse/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/rehype-raw/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz", + "integrity": "sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/rehype-stringify/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/rehype/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/remark-directive/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/remark-expressive-code/-/remark-expressive-code-0.30.1.tgz", + "integrity": "sha512-1cxsvXn1FyZsgaZXvkV+uoJLkg0rcS/k9Yemw211oD8Fblhh67Gb6ThxbuQdPf346kgg5D4R/iVyR49oAS5kbg==", + "dependencies": { + "expressive-code": "^0.30.1", + "hast-util-to-html": "^8.0.4", + "unist-util-visit": "^4.1.2" + } + }, + "node_modules/remark-expressive-code/node_modules/@types/hast": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", + "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/remark-expressive-code/node_modules/hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/hast-util-raw": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/hast-util-to-html": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", + "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-raw": "^7.0.0", + "hast-util-whitespace": "^2.0.0", + "html-void-elements": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/hast-util-to-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-expressive-code/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/remark-expressive-code/node_modules/unist-util-position": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-expressive-code/node_modules/vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/remark-gfm/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", + "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/remark-parse/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", + "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/remark-rehype/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.0.0.tgz", + "integrity": "sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==", + "dependencies": { + "retext": "^8.1.0", + "retext-smartypants": "^5.1.0", + "unist-util-visit": "^4.1.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/remark-stringify/node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/retext": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-8.1.0.tgz", + "integrity": "sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==", + "dependencies": { + "@types/nlcst": "^1.0.0", + "retext-latin": "^3.0.0", + "retext-stringify": "^3.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-3.1.0.tgz", + "integrity": "sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==", + "dependencies": { + "@types/nlcst": "^1.0.0", + "parse-latin": "^5.0.0", + "unherit": "^3.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-5.2.0.tgz", + "integrity": "sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==", + "dependencies": { + "@types/nlcst": "^1.0.0", + "nlcst-to-string": "^3.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-3.1.0.tgz", + "integrity": "sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==", + "dependencies": { + "@types/nlcst": "^1.0.0", + "nlcst-to-string": "^3.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "optional": true, + "peer": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/server-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", + "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==" + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" + }, + "node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.2.1.tgz", + "integrity": "sha512-u+XW6o0vCkUNlneZb914dLO+AayEIwK5tI62WeS//R5HIXBFiYaj/Hc5xcq27Yh83Grr4JbNtUBV8W6zyK4hWg==", + "dependencies": { + "@shikijs/core": "1.2.1" + } + }, + "node_modules/shikiji": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/shikiji/-/shikiji-0.6.13.tgz", + "integrity": "sha512-4T7X39csvhT0p7GDnq9vysWddf2b6BeioiN3Ymhnt3xcy9tXmDcnsEFVxX18Z4YcQgEE/w48dLJ4pPPUcG9KkA==", + "dependencies": { + "hast-util-to-html": "^9.0.0" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/sitemap": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", + "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", + "dependencies": { + "bl": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/streamx": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", + "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", + "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^10.2.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", + "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svelte": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", + "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-hmr": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", + "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/svelte2tsx": { + "version": "0.6.27", + "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.6.27.tgz", + "integrity": "sha512-E1uPW1o6VsbRz+nUk3fznZ2lSmCITAJoNu8AYefWSvIwE2pSB01i5sId4RMbWNzfcwCQl1DcgGShCPcldl4rvg==", + "dependencies": { + "dedent-js": "^1.0.1", + "pascal-case": "^3.1.1" + }, + "peerDependencies": { + "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", + "typescript": "^4.9.4 || ^5.0.0" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.0.tgz", + "integrity": "sha512-w3wnsIrJNi7avf4Zb0VjOoodoO0woEqGgZGQm+LHH9przdUI+XDKsWAXwxHA1DaRTjeuZNcregSzr7RaA8zG9A==", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "optional": true, + "peer": true + }, + "node_modules/unherit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-3.0.1.tgz", + "integrity": "sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/unist-util-find-after/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-3.1.1.tgz", + "integrity": "sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==", + "dependencies": { + "@types/unist": "^2.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/unist-util-position/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/unist-util-remove": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-4.0.0.tgz", + "integrity": "sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/unist-util-remove-position/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/unist-util-remove/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-2.0.2.tgz", + "integrity": "sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/vfile-location/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", + "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", + "optional": true, + "peer": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/web-vitals": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", + "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-pm": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.1.1.tgz", + "integrity": "sha512-xzzxNw2wMaoCWXiGE8IJ9wuPMU+EYhFksjHxrRT8kMT5SnocBPRg69YAMtyV4D12fP582RA+k3P8H9J5EMdIxQ==", + "dependencies": { + "load-yaml-file": "^0.2.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8.15" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.5.tgz", + "integrity": "sha512-+akaPo6a0zpVCCseDed504KBJUQpEW5QZw7RMneNmKw+fGaML1Z9tUNLnHHAC8x6dzVRO1eB2oEMyZRnuBZg7Q==", + "peerDependencies": { + "zod": "^3.22.4" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/docs copy/package.json b/docs copy/package.json new file mode 100644 index 000000000..520d3f94b --- /dev/null +++ b/docs copy/package.json @@ -0,0 +1,22 @@ +{ + "name": "angular-challenges-docs", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/starlight": "^0.15.1", + "@astrojs/svelte": "^5.2.0", + "@astrojs/vercel": "^7.5.0", + "@fontsource/ibm-plex-serif": "^5.0.8", + "astro": "^4.0.0", + "sharp": "^0.32.5", + "svelte": "^4.2.12", + "typescript": "^5.4.3" + } +} diff --git a/docs copy/public/angular-challenge.ico b/docs copy/public/angular-challenge.ico new file mode 100644 index 000000000..29d85cde0 Binary files /dev/null and b/docs copy/public/angular-challenge.ico differ diff --git a/docs copy/public/angular-challenge.webp b/docs copy/public/angular-challenge.webp new file mode 100644 index 000000000..743d5aaab Binary files /dev/null and b/docs copy/public/angular-challenge.webp differ diff --git a/docs copy/src/assets/4/unknown-person.png b/docs copy/src/assets/4/unknown-person.png new file mode 100644 index 000000000..9ab0a2e7d Binary files /dev/null and b/docs copy/src/assets/4/unknown-person.png differ diff --git a/docs copy/src/assets/4/unknown-student.png b/docs copy/src/assets/4/unknown-student.png new file mode 100644 index 000000000..247a29e91 Binary files /dev/null and b/docs copy/src/assets/4/unknown-student.png differ diff --git a/docs copy/src/assets/PR-code-btn-modal.png b/docs copy/src/assets/PR-code-btn-modal.png new file mode 100644 index 000000000..2cc4b1b27 Binary files /dev/null and b/docs copy/src/assets/PR-code-btn-modal.png differ diff --git a/docs copy/src/assets/PR-header.png b/docs copy/src/assets/PR-header.png new file mode 100644 index 000000000..bb76c8cf6 Binary files /dev/null and b/docs copy/src/assets/PR-header.png differ diff --git a/docs copy/src/assets/angular-challenge.webp b/docs copy/src/assets/angular-challenge.webp new file mode 100644 index 000000000..743d5aaab Binary files /dev/null and b/docs copy/src/assets/angular-challenge.webp differ diff --git a/docs copy/src/assets/codespaces.png b/docs copy/src/assets/codespaces.png new file mode 100644 index 000000000..2b8e8a43c Binary files /dev/null and b/docs copy/src/assets/codespaces.png differ diff --git a/docs copy/src/assets/fork-sync.png b/docs copy/src/assets/fork-sync.png new file mode 100644 index 000000000..7374facc0 Binary files /dev/null and b/docs copy/src/assets/fork-sync.png differ diff --git a/docs copy/src/assets/header-github.png b/docs copy/src/assets/header-github.png new file mode 100644 index 000000000..08da88dca Binary files /dev/null and b/docs copy/src/assets/header-github.png differ diff --git a/docs copy/src/assets/new-pull-request.png b/docs copy/src/assets/new-pull-request.png new file mode 100644 index 000000000..085acccee Binary files /dev/null and b/docs copy/src/assets/new-pull-request.png differ diff --git a/docs copy/src/assets/performance/34/profiler-record.png b/docs copy/src/assets/performance/34/profiler-record.png new file mode 100644 index 000000000..febcbd2a0 Binary files /dev/null and b/docs copy/src/assets/performance/34/profiler-record.png differ diff --git a/docs copy/src/assets/performance/35/memoize-profiler.png b/docs copy/src/assets/performance/35/memoize-profiler.png new file mode 100644 index 000000000..0520fde45 Binary files /dev/null and b/docs copy/src/assets/performance/35/memoize-profiler.png differ diff --git a/docs copy/src/assets/performance/profiler-tab.png b/docs copy/src/assets/performance/profiler-tab.png new file mode 100644 index 000000000..a6d228d73 Binary files /dev/null and b/docs copy/src/assets/performance/profiler-tab.png differ diff --git a/docs copy/src/assets/rxjs/49/prototype.gif b/docs copy/src/assets/rxjs/49/prototype.gif new file mode 100644 index 000000000..32c33528c Binary files /dev/null and b/docs copy/src/assets/rxjs/49/prototype.gif differ diff --git a/docs copy/src/assets/sync-fork-update.png b/docs copy/src/assets/sync-fork-update.png new file mode 100644 index 000000000..c8a1eea7d Binary files /dev/null and b/docs copy/src/assets/sync-fork-update.png differ diff --git a/docs copy/src/components/ActionButtonFooter.astro b/docs copy/src/components/ActionButtonFooter.astro new file mode 100644 index 000000000..ccc03c221 --- /dev/null +++ b/docs copy/src/components/ActionButtonFooter.astro @@ -0,0 +1,56 @@ +--- +import { Icon } from '@astrojs/starlight/components'; +import MyIcon from './MyIcon.astro'; +import type { Props } from '@astrojs/starlight/props'; +import { getEntry } from 'astro:content'; + +const { lang } = Astro.props; +const { data } = await getEntry('i18n', lang); + +--- + + + + diff --git a/docs copy/src/components/Author.astro b/docs copy/src/components/Author.astro new file mode 100644 index 000000000..43b3af29c --- /dev/null +++ b/docs copy/src/components/Author.astro @@ -0,0 +1,51 @@ +--- +import { Icon } from '@astrojs/starlight/components'; + +interface Props { + name: string; + twitter?: string; + linkedin?: string; + github?: string; + youtube?: string; + labels?: Record; +} + +const { name, twitter, linkedin, github, youtube, data } = Astro.props; +--- + +

+ {data['author.createdBy']} {name} + {twitter && + + } + {linkedin && + + } + {github && + + } + {youtube && + + } + +

+ + diff --git a/docs copy/src/components/ChallengeFooter.astro b/docs copy/src/components/ChallengeFooter.astro new file mode 100644 index 000000000..ccd4f1a83 --- /dev/null +++ b/docs copy/src/components/ChallengeFooter.astro @@ -0,0 +1,105 @@ +--- +import VideoButton from './VideoButton.astro'; +import ClipboardCopy from './ClipboardCopy.astro'; +import { getEntry } from 'astro:content'; +import AnsweredUser from './github/AnsweredUser.svelte'; + +const { lang } = Astro.props; +const { author, challengeNumber, title, blogLink, videoLinks, command } = Astro.props.entry.data; +const { data } = await getEntry('i18n', lang); + +const authorLink = `https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A${challengeNumber}+label%3A"answer+author"`; +const communityLink = `https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A${challengeNumber}+label%3Aanswer+sort%3Areactions-%2B1-desc`; +const npxCommand = `npx nx serve ${command}`; + +--- + +
+ + +{command && + + } + + + + + + + + + + + diff --git a/docs copy/src/components/ClipboardCopy.astro b/docs copy/src/components/ClipboardCopy.astro new file mode 100644 index 000000000..c1ab7c340 --- /dev/null +++ b/docs copy/src/components/ClipboardCopy.astro @@ -0,0 +1,106 @@ +--- +import { getEntry } from "astro:content"; + +const { copyText, lang } = Astro.props; +const { data } = await getEntry('i18n', lang); +--- + + + + + + {data['buttons.clipboardCopy']} + + + + + + diff --git a/docs copy/src/components/CommentSection.astro b/docs copy/src/components/CommentSection.astro new file mode 100644 index 000000000..778eba0a2 --- /dev/null +++ b/docs copy/src/components/CommentSection.astro @@ -0,0 +1,34 @@ +--- +import type { Props } from '@astrojs/starlight/props'; + +const {lang, locale} = Astro.props; + +// Chinese needs to `zh-CN` +// const shortLang =lang.split('-')[0]; +--- + +
+ + + + diff --git a/docs copy/src/components/Content.astro b/docs copy/src/components/Content.astro new file mode 100644 index 000000000..c45759d82 --- /dev/null +++ b/docs copy/src/components/Content.astro @@ -0,0 +1,45 @@ +--- +import Default from '@astrojs/starlight/components/MarkdownContent.astro'; +import type { Props } from '@astrojs/starlight/props'; +import { getEntry } from 'astro:content'; +import Author from './Author.astro'; +import ChallengeFooter from './ChallengeFooter.astro'; +import CommentSection from './CommentSection.astro'; +import ContributorsFooter from './ContributorsFooter.astro'; +import AnswerNumber from './github/AnswerNumber.svelte'; + +const { lang } = Astro.props; +const { data } = await getEntry('i18n', lang); +const { challengeNumber } = Astro.props.entry.data; +const author = Astro.props.entry.data.author ? await getEntry(Astro.props.entry.data.author) : null; +const renderCommentSection = !Astro.props.entry.data.noCommentSection; + +--- + +{ challengeNumber ?
+ { author ? : null} + +
:null} + + + + + +{challengeNumber ? + : null} + +{ renderCommentSection && + } + + + + diff --git a/docs copy/src/components/ContributorsFooter.astro b/docs copy/src/components/ContributorsFooter.astro new file mode 100644 index 000000000..d5b4040aa --- /dev/null +++ b/docs copy/src/components/ContributorsFooter.astro @@ -0,0 +1,75 @@ +--- +import { getEntry } from 'astro:content'; + +const contributors = Astro.props.entry.data.contributors ?? []; +const { lang } = Astro.props; +const { data } = await getEntry('i18n', lang); +--- + + +{contributors.length === 0 ? null : +
+

{data['contributor.title']}

+

{data['contributor.subtitle']}

+
    + {contributors.map((contributor: string) => ( +
  • + + {contributor} + +
  • + ))} +
+
+ } + + diff --git a/docs copy/src/components/Hero.astro b/docs copy/src/components/Hero.astro new file mode 100644 index 000000000..8d9500eaa --- /dev/null +++ b/docs copy/src/components/Hero.astro @@ -0,0 +1,63 @@ +--- +import Default from '@astrojs/starlight/components/Hero.astro'; +import MyIcon from './MyIcon.astro'; +import { getEntry } from 'astro:content'; +import SponsorUser from './github/SponsorUser.svelte'; + + + +const { lang } = Astro.props; +const { data } = await getEntry('i18n', lang); +--- + + + + + + + + + diff --git a/docs copy/src/components/MobileMenuFooter.astro b/docs copy/src/components/MobileMenuFooter.astro new file mode 100644 index 000000000..6a8870b03 --- /dev/null +++ b/docs copy/src/components/MobileMenuFooter.astro @@ -0,0 +1,9 @@ +--- +import Default from '@astrojs/starlight/components/MobileMenuFooter.astro'; +import ActionButtonFooter from './ActionButtonFooter.astro'; + +--- + + + + diff --git a/docs copy/src/components/MyIcon.astro b/docs copy/src/components/MyIcon.astro new file mode 100644 index 000000000..25327f49f --- /dev/null +++ b/docs copy/src/components/MyIcon.astro @@ -0,0 +1,33 @@ +--- +import { Icons } from './icons'; + +interface Props { + name: keyof typeof Icons; + label?: string; + color?: string; + size?: string; + class?: string; +} + +const { name, label, size = '1em', color, fill="currentColor", stroke="none", viewBox="0 0 24 24" } = Astro.props; +const a11yAttrs = label ? ({ 'aria-label': label } as const) : ({ 'aria-hidden': 'true' } as const); +--- + + + + + diff --git a/docs copy/src/components/PageTitle.astro b/docs copy/src/components/PageTitle.astro new file mode 100644 index 000000000..6f2cd725d --- /dev/null +++ b/docs copy/src/components/PageTitle.astro @@ -0,0 +1,44 @@ +--- +import { getEntry } from 'astro:content'; +import type { Props } from '@astrojs/starlight/props'; +import Default from '@astrojs/starlight/components/PageTitle.astro'; +const { challengeNumber } = Astro.props.entry.data; +const { lang } = Astro.props; +const { data } = await getEntry('i18n', lang); +--- + +
+ + + + {challengeNumber && +
{data['page.title.challenge']} #{challengeNumber}
} +
+ + diff --git a/docs copy/src/components/SiteTitle.astro b/docs copy/src/components/SiteTitle.astro new file mode 100644 index 000000000..e4fb0c010 --- /dev/null +++ b/docs copy/src/components/SiteTitle.astro @@ -0,0 +1,20 @@ +--- +import Default from '@astrojs/starlight/components/SiteTitle.astro'; +import MyIcon from './MyIcon.astro'; +import SignUp from './github/SignUp.svelte'; +import { Icon } from '@astrojs/starlight/components'; +--- + + + + + + + + + + + + + + diff --git a/docs copy/src/components/SubscriptionForm.astro b/docs copy/src/components/SubscriptionForm.astro new file mode 100644 index 000000000..323ab5390 --- /dev/null +++ b/docs copy/src/components/SubscriptionForm.astro @@ -0,0 +1,102 @@ +--- +import { getEntry } from 'astro:content'; + +const { isNote, lang } = Astro.props; +const { data } = await getEntry('i18n', lang ?? 'en'); +--- + +
+
+
+
+
+
+ +
+
+
+
+ + +{isNote ? + + : +*{data['subscription.note.description']}. + } + + diff --git a/docs copy/src/components/TableOfContents.astro b/docs copy/src/components/TableOfContents.astro new file mode 100644 index 000000000..529b0e166 --- /dev/null +++ b/docs copy/src/components/TableOfContents.astro @@ -0,0 +1,9 @@ +--- +import Default from '@astrojs/starlight/components/TableOfContents.astro'; +import ActionButtonFooter from './ActionButtonFooter.astro'; + +--- + + + + diff --git a/docs copy/src/components/VideoButton.astro b/docs copy/src/components/VideoButton.astro new file mode 100644 index 000000000..723ef30e9 --- /dev/null +++ b/docs copy/src/components/VideoButton.astro @@ -0,0 +1,26 @@ +--- +import { getEntry } from 'astro:content'; + +interface Props { + lang: any; + link: string; + alt: string; + flag?: 'FR' | 'ES'; +} + +const { link, alt, flag, lang } = Astro.props; +const { data } = await getEntry('i18n', lang); +const isFR = flag === 'FR'; +const isES = flag === 'ES'; +--- + + + + {data['challenge.footer.video']} + {isFR && 🇫🇷} + {isES && 🇪🇸} + diff --git a/docs copy/src/components/github/AnswerNumber.svelte b/docs copy/src/components/github/AnswerNumber.svelte new file mode 100644 index 000000000..a43e7171e --- /dev/null +++ b/docs copy/src/components/github/AnswerNumber.svelte @@ -0,0 +1,20 @@ + + +{#if $isLoaded} + Answered by {$totalCount} people +{/if} + + diff --git a/docs copy/src/components/github/AnsweredUser.svelte b/docs copy/src/components/github/AnsweredUser.svelte new file mode 100644 index 000000000..81ae138a6 --- /dev/null +++ b/docs copy/src/components/github/AnsweredUser.svelte @@ -0,0 +1,74 @@ + + +{#if $isLoaded} +
+
Answered by
+ {#each $data as { user, html_url }} + + + + {/each} +
+{/if} + + diff --git a/docs copy/src/components/github/GitHubStats.svelte b/docs copy/src/components/github/GitHubStats.svelte new file mode 100644 index 000000000..8286a2894 --- /dev/null +++ b/docs copy/src/components/github/GitHubStats.svelte @@ -0,0 +1,170 @@ + + +{#if !error && !loading && !loadingStar} +
+ {#if isStarByUser} +
+ + {stargazersCount} +
+ {:else} + + {/if} + + + +
{forksCount}
+
+
+{/if} + + diff --git a/docs copy/src/components/github/SignUp.svelte b/docs copy/src/components/github/SignUp.svelte new file mode 100644 index 000000000..a98a2a943 --- /dev/null +++ b/docs copy/src/components/github/SignUp.svelte @@ -0,0 +1,66 @@ + + +{#if !$token} + + + + +{:else} + + + + + +{/if} + + + diff --git a/docs copy/src/components/github/SponsorUser.svelte b/docs copy/src/components/github/SponsorUser.svelte new file mode 100644 index 000000000..cc29003d7 --- /dev/null +++ b/docs copy/src/components/github/SponsorUser.svelte @@ -0,0 +1,40 @@ + + +{#each sponsors as { username, avatar }} + + {username} + +{/each} + + diff --git a/docs copy/src/components/github/github-store.ts b/docs copy/src/components/github/github-store.ts new file mode 100644 index 000000000..48c4ddee4 --- /dev/null +++ b/docs copy/src/components/github/github-store.ts @@ -0,0 +1,39 @@ +import { derived, writable } from 'svelte/store'; + +export const token = writable(null); +export const isConnected = writable(false); + +export const username = writable(null); + +export const isLoading = writable(true); +export const error = writable(false); +export const data = writable([]); +export const totalCount = writable(0); + +export const isLoaded = derived( + [isLoading, error], + ([$isLoading, $error]) => !$isLoading && !$error, +); + +const TOKEN_KEY = 'TOKEN'; + +export function loadToken() { + const persistedToken = localStorage.getItem(TOKEN_KEY); + if (persistedToken) { + token.set(JSON.parse(persistedToken)); + isConnected.set(true); + } else { + isConnected.set(false); + } +} + +token.subscribe((value) => { + if (value) { + if (value === 'delete') { + localStorage.removeItem(TOKEN_KEY); + token.set(null); + return; + } + localStorage.setItem(TOKEN_KEY, JSON.stringify(value)); + } +}); diff --git a/docs copy/src/components/github/tooltip.js b/docs copy/src/components/github/tooltip.js new file mode 100644 index 000000000..dbc29fd8b --- /dev/null +++ b/docs copy/src/components/github/tooltip.js @@ -0,0 +1,45 @@ +export function tooltip(element) { + let div; + let title; + function mouseOver(event) { + // NOTE: remove the `title` attribute, to prevent showing the default browser tooltip + // remember to set it back on `mouseleave` + title = element.getAttribute('title'); + element.removeAttribute('title'); + + div = document.createElement('div'); + div.textContent = title; + div.style = ` + border: 1px solid #ddd; + box-shadow: 1px 1px 1px #ddd; + background: white; + border-radius: 4px; + padding: 4px; + position: absolute; + top: ${event.pageX + 5}px; + left: ${event.pageY + 5}px; + `; + document.body.appendChild(div); +} + function mouseMove(event) { + div.style.left = `${event.pageX + 5}px`; + div.style.top = `${event.pageY + 5}px`; +} + function mouseLeave() { + document.body.removeChild(div); + // NOTE: restore the `title` attribute + element.setAttribute('title', title); +} + + element.addEventListener('mouseover', mouseOver); + element.addEventListener('mouseleave', mouseLeave); + element.addEventListener('mousemove', mouseMove); + + return { + destroy() { + element.removeEventListener('mouseover', mouseOver); + element.removeEventListener('mouseleave', mouseLeave); + element.removeEventListener('mousemove', mouseMove); +} +} +} diff --git a/docs copy/src/components/icons.ts b/docs copy/src/components/icons.ts new file mode 100644 index 000000000..ba24c6b8a --- /dev/null +++ b/docs copy/src/components/icons.ts @@ -0,0 +1,8 @@ +export const Icons = { + heart: + '', + star: '', + fullStar: + '', + fork: '', +}; diff --git a/docs copy/src/components/leaderboard/LeaderboardAnswer.svelte b/docs copy/src/components/leaderboard/LeaderboardAnswer.svelte new file mode 100644 index 000000000..0ca776b3c --- /dev/null +++ b/docs copy/src/components/leaderboard/LeaderboardAnswer.svelte @@ -0,0 +1,133 @@ + +{#if !$isConnected} +
Log in to Github to see the list
+{:else} +🔥Total Answers: { globalCount } + {#if isUsernamePresent} + + {/if} + {#if loading} + + {:else if error} +

Error: {error}

+ {:else} +
+ {#each users as { avatar, count, login, challengeNumber }, index} + + {count} Answers +
{challengeNumber.join(', ')}
+
+ {/each} +
+ {/if} +{/if} + + diff --git a/docs copy/src/components/leaderboard/LeaderboardChallenge.svelte b/docs copy/src/components/leaderboard/LeaderboardChallenge.svelte new file mode 100644 index 000000000..3cee5229e --- /dev/null +++ b/docs copy/src/components/leaderboard/LeaderboardChallenge.svelte @@ -0,0 +1,103 @@ + + +{#if !$isConnected} +
Log in to Github to see the list
+{:else} + {#if isUsernamePresent} + + {/if} + {#if loading} + + {:else if error} +

Error: {error}

+ {:else} +
+ {#each users as { avatar, count, login }, index} + + {count} Challenges Created + + {/each} +
+ {/if} +{/if} + + diff --git a/docs copy/src/components/leaderboard/LeaderboardCommit.svelte b/docs copy/src/components/leaderboard/LeaderboardCommit.svelte new file mode 100644 index 000000000..e9068576b --- /dev/null +++ b/docs copy/src/components/leaderboard/LeaderboardCommit.svelte @@ -0,0 +1,119 @@ + + +{#if !$isConnected} +
Log in to Github to see the list
+{:else} + {#if isUsernamePresent} + + {/if} + {#if loading} + + {:else if error} +

Error: {error}

+ {:else} +
+ {#each users as { avatar, count, login }, index} + + {count} PRs merged + + {/each} +
+ {/if} +{/if} + + diff --git a/docs copy/src/components/leaderboard/Spinner.svelte b/docs copy/src/components/leaderboard/Spinner.svelte new file mode 100644 index 000000000..07dd361e2 --- /dev/null +++ b/docs copy/src/components/leaderboard/Spinner.svelte @@ -0,0 +1,33 @@ + +
+
+
+ + diff --git a/docs copy/src/components/leaderboard/UserBox.svelte b/docs copy/src/components/leaderboard/UserBox.svelte new file mode 100644 index 000000000..887c95327 --- /dev/null +++ b/docs copy/src/components/leaderboard/UserBox.svelte @@ -0,0 +1,78 @@ + + +
+ +
+ #{index + 1} +
+
+ + diff --git a/docs copy/src/content/authors/Ioannis-Tsironis.json b/docs copy/src/content/authors/Ioannis-Tsironis.json new file mode 100644 index 000000000..9cb257672 --- /dev/null +++ b/docs copy/src/content/authors/Ioannis-Tsironis.json @@ -0,0 +1,5 @@ +{ + "name": "Ioannis Tsironis", + "github": "https://github.com/tsironis13", + "linkedin": "https://www.linkedin.com/in/giannis-tsironis/" +} diff --git a/docs copy/src/content/authors/devesh-chaudhari.json b/docs copy/src/content/authors/devesh-chaudhari.json new file mode 100644 index 000000000..c1bc4bfb4 --- /dev/null +++ b/docs copy/src/content/authors/devesh-chaudhari.json @@ -0,0 +1,4 @@ +{ + "name": "Devesh Chaudhari", + "twitter": "https://twitter.com/DeveshChau" +} diff --git a/docs copy/src/content/authors/lance-finney.json b/docs copy/src/content/authors/lance-finney.json new file mode 100644 index 000000000..be44e3e89 --- /dev/null +++ b/docs copy/src/content/authors/lance-finney.json @@ -0,0 +1,6 @@ +{ + "name": "Lance Finney", + "twitter": "https://twitter.com/LMFinneyCoder", + "linkedin": "https://www.linkedin.com/in/lmfinney/", + "github": "https://github.com/LMFinney" +} diff --git a/docs copy/src/content/authors/stanislav-gavrilov.json b/docs copy/src/content/authors/stanislav-gavrilov.json new file mode 100644 index 000000000..7fa793099 --- /dev/null +++ b/docs copy/src/content/authors/stanislav-gavrilov.json @@ -0,0 +1,5 @@ +{ + "name": "Stanislav Gavrilov", + "linkedin": "https://www.linkedin.com/in/stgavrilov/", + "github": "https://github.com/stillst" +} diff --git a/docs copy/src/content/authors/sven-brodny.json b/docs copy/src/content/authors/sven-brodny.json new file mode 100644 index 000000000..3372743d8 --- /dev/null +++ b/docs copy/src/content/authors/sven-brodny.json @@ -0,0 +1,5 @@ +{ + "name": "Sven Brodny", + "linkedin": "https://www.linkedin.com/in/sven-brodny-0ba603237/", + "github": "https://github.com/svenson95" +} diff --git a/docs copy/src/content/authors/thomas-laforge.json b/docs copy/src/content/authors/thomas-laforge.json new file mode 100644 index 000000000..2bfd96588 --- /dev/null +++ b/docs copy/src/content/authors/thomas-laforge.json @@ -0,0 +1,6 @@ +{ + "name": "Thomas Laforge", + "twitter": "https://twitter.com/laforge_toma", + "linkedin": "https://www.linkedin.com/in/thomas-laforge-2b05a945/", + "github": "https://github.com/tomalaforge" +} diff --git a/docs copy/src/content/authors/timothy-alcaide.json b/docs copy/src/content/authors/timothy-alcaide.json new file mode 100644 index 000000000..a50cd7643 --- /dev/null +++ b/docs copy/src/content/authors/timothy-alcaide.json @@ -0,0 +1,7 @@ +{ + "name": "Timothy Alcaide", + "github": "https://github.com/alcaidio", + "youtube": "https://www.youtube.com/@timothyalcaide", + "twitter": "https://twitter.com/alcaidio", + "linkedin": "https://www.linkedin.com/in/timothyalcaide" +} diff --git a/docs copy/src/content/authors/wandrille-guesdon.json b/docs copy/src/content/authors/wandrille-guesdon.json new file mode 100644 index 000000000..a240cba89 --- /dev/null +++ b/docs copy/src/content/authors/wandrille-guesdon.json @@ -0,0 +1,5 @@ +{ + "name": "Wandrille Guesdon", + "linkedin": "https://www.linkedin.com/in/wandrille-guesdon-53a54684/", + "github": "https://github.com/wandri" +} diff --git a/docs copy/src/content/config.ts b/docs copy/src/content/config.ts new file mode 100644 index 000000000..91a2d506a --- /dev/null +++ b/docs copy/src/content/config.ts @@ -0,0 +1,77 @@ +import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; +import { defineCollection, reference, z } from 'astro:content'; + +const authors = defineCollection({ + type: 'data', + schema: z.object({ + name: z.string(), + twitter: z.string().url().optional(), + linkedin: z.string().url().optional(), + github: z.string().url().optional(), + youtube: z.string().url().optional(), + }), +}); + +const docs = defineCollection({ + schema: (ctx) => + docsSchema({ + extend: z.object({ + noCommentSection: z.boolean().optional().default(false), + challengeNumber: z.union([z.number(), z.boolean()]).default(false), + author: reference('authors').optional(), + contributors: z.array(z.string()).optional(), + command: z.string().optional(), + blogLink: z.string().optional(), + videoLinks: z + .array( + z.object({ + link: z.string(), + alt: z.string(), + flag: z.enum(['FR', 'ES']).optional(), + }), + ) + .optional(), + }), + })(ctx), +}); + +const i18n = defineCollection({ + type: 'data', + schema: i18nSchema({ + extend: z + .object({ + 'page.title.challenge': z.string(), + 'author.createdBy': z.string(), + 'buttons.email': z.string(), + 'buttons.star': z.string(), + 'buttons.sponsor': z.string(), + 'buttons.clipboardCopy': z.string(), + 'challenge.footer.note': z.string(), + 'challenge.footer.running': z.string(), + 'challenge.footer.start': z.string(), + 'challenge.footer.reminder': z.string(), + 'challenge.footer.communityAnswers': z.string(), + 'challenge.footer.authorAnswer': z.string(), + 'challenge.footer.blogPost': z.string(), + 'challenge.footer.video': z.string(), + 'challenge.footer.gettingStarted.title': z.string(), + 'challenge.footer.gettingStarted.link': z.string(), + 'challenge.footer.upvoteAnswer': z.string(), + 'subscription.button': z.string(), + 'subscription.email': z.string(), + 'subscription.note.title': z.string(), + 'subscription.note.description': z.string(), + 'contributor.title': z.string(), + 'contributor.subtitle': z.string(), + 'sponsors.description': z.string(), + 'sponsors.joinButton': z.string(), + }) + .partial(), + }), +}); + +export const collections = { + docs: docs, + i18n: i18n, + authors: authors, +}; diff --git a/docs copy/src/content/docs/challenges/angular/1-projection.md b/docs copy/src/content/docs/challenges/angular/1-projection.md new file mode 100644 index 000000000..127530f03 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/1-projection.md @@ -0,0 +1,51 @@ +--- +title: 🟢 Projection +description: Challenge 1 is about learning how to project DOM element through components +author: thomas-laforge +contributors: + - tomalaforge + - jdegand + - dmmishchenko + - kabrunko-dev + - svenson95 +challengeNumber: 1 +command: angular-projection +blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5 +videoLinks: + - link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq + alt: Projection video by Arthur Lannelucq + flag: FR + - link: https://www.youtube.com/watch?v=yNrfvu7vTa4 + alt: Projection video by Amos Lucian Isaila + flag: ES +sidebar: + order: 1 +--- + +## Information + +In Angular, content projection is a powerful technique for creating highly customizable components. Utilizing and understanding the concepts of ng-content and ngTemplateOutlet can significantly enhance your ability to create shareable components. + +You can learn all about ng-content [here](https://angular.dev/guide/components/content-projection) from simple projection to more complex ones. + +To learn about ngTemplateOutlet, you can find the API documentation [here](https://angular.dev/api/common/NgTemplateOutlet) along with some basic examples. + +With these two tools in hand, you are now ready to take on the challenge. + +## Statement + +You will start with a fully functional application that includes a dashboard containing a teacher card and a student card. The goal is to implement the city card. + +While the application works, the developer experience is far from being optimal. Every time you need to implement a new card, you have to modify the `card.component.ts`. In real-life projects, this component can be shared among many applications. The goal of the challenge is to create a `CardComponent` that can be customized without any modifications. Once you've created this component, you can begin implementing the `CityCardComponent` and ensure you are not touching the `CardComponent`. + +## Constraints + +- You must refactor the `CardComponent` and `ListItemComponent`. +- The `@for` must be declared and remain inside the `CardComponent`. You might be tempted to move it to the `ParentCardComponent` like `TeacherCardComponent`. +- `CardComponent` should not contain any conditions. +- CSS: try to avoid using `::ng-deep`. Find a better way to handle CSS styling. + +## Bonus Challenges + +- Use the signal API to manage your components state (documentation [here](https://angular.dev/guide/signals)) +- To reference the template, use a directive instead of magic strings ([What is wrong with magic strings?](https://softwareengineering.stackexchange.com/a/365344)) diff --git a/docs copy/src/content/docs/challenges/angular/10-utility-wrapper-pipe.md b/docs copy/src/content/docs/challenges/angular/10-utility-wrapper-pipe.md new file mode 100644 index 000000000..f74bb1612 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/10-utility-wrapper-pipe.md @@ -0,0 +1,39 @@ +--- +title: 🔴 Utility Wrapper Pipe +description: Challenge 10 is about creating a pipe to wrap utilities +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - LMFinney +challengeNumber: 10 +command: angular-utility-wrapper-pipe +sidebar: + order: 202 +--- + +## Information + +This is the third of three `@Pipe()` challenges. The goal of this series is to master **pipes** in Angular. + +Pipes are a very powerful way to transform data in your template. The difference between calling a function and a pipe is that pure pipes are memoized. So, they won't be recalculated every change detection cycle if their inputs haven't changed. + +Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improve rendering performance. + +By default, a pipe is pure. You should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders. + +:::note +A **pure** pipe is only called when the value changes.\ +A **impure** pipe is called every change detection cycle. +::: + +There are some useful predefined pipes like the DatePipe, UpperCasePipe and CurrencyPipe. To learn more about pipes in Angular, check the API documentation [here](https://angular.dev/guide/pipes). + +## Statement + +In this exercise, you want to access utils functions. Currently, you cannot access them directly from your template. The goal is to create a specific pipe for this utils file, where you will need to pass the name of the function you want to call and the needed arguments. + +## Constraints + +- Must be strongly typed diff --git a/docs copy/src/content/docs/challenges/angular/13-highly-customizable-css.md b/docs copy/src/content/docs/challenges/angular/13-highly-customizable-css.md new file mode 100644 index 000000000..b08786ea3 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/13-highly-customizable-css.md @@ -0,0 +1,24 @@ +--- +title: 🟠 Highly Customizable CSS +description: Challenge 13 is about creating highly customizable CSS styles +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - kabrunko-dev + - LMFinney +challengeNumber: 13 +command: angular-highly-customizable-css +sidebar: + order: 104 +--- + +## Information + +Styling is an important aspect of a frontend developer's day job, but it is often underestimated. In Angular applications, I frequently see people using `@Input()` to customize the style of their components. However, `@Input()` should only be used for logic. Other techniques, such as **CSS variables** and **host-context**, should be used for styling. + +In this challenge, you will need to use both CSS variables and `:host-context` to remove all `@Input()` from your code. + +## Constraints + +- In your final submission, your component should not contain any lines of code. All styling should be handled within the decorator _(or external css files if you prefer)_ diff --git a/docs copy/src/content/docs/challenges/angular/16-master-dependency-injection.md b/docs copy/src/content/docs/challenges/angular/16-master-dependency-injection.md new file mode 100644 index 000000000..caf99bd90 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/16-master-dependency-injection.md @@ -0,0 +1,30 @@ +--- +title: 🔴 Master Dependency Injection +description: Challenge 16 is about mastering how dependancy injection works +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - kabrunko-dev +challengeNumber: 16 +command: angular-master-dependency-injection +sidebar: + order: 203 +--- + +## Information + +To successfully complete this challenge, you will need to have a good understanding of how [Dependency Injection](https://angular.dev/guide/di/dependency-injection) works inside Angular. + +The goal is to provide the `CurrencyService` at the row level, so that each row displays the correct currency. Currently, the `CurrencyService` is only provided at the table level, which results in an error as the same currency is displayed for each row, despite each product having a different currency. + +One way to achieve this is by adding a second argument to the pipe, but this is not allowed for this challenge. + +## Statement + +- Your task is to display the correct currency for each row. + +## Constraints + +- You cannot modify the pipe. +- You cannot wrap the row inside a component, as this will break the layout. diff --git a/docs copy/src/content/docs/challenges/angular/21-anchor-navigation.md b/docs copy/src/content/docs/challenges/angular/21-anchor-navigation.md new file mode 100644 index 000000000..f094023b8 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/21-anchor-navigation.md @@ -0,0 +1,21 @@ +--- +title: 🟢 Anchor Navigation +description: Challenge 21 is about navigating inside the page with anchor +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 +challengeNumber: 21 +command: angular-anchor-navigation +sidebar: + order: 4 +--- + +## Information + +You begin with an application that has basic navigation and anchor navigation in the `HomeComponent`. However, using `href` recreates the path each time and refreshes the page. + +## Statement + +- Your task is to refactor this application to use the built-in navigation tool to better fit within the Angular Framework. You can explore the router, but it's better to stay within the template and use the `RouterLink` directive. +- To improve the user experience, add smooth scrolling. diff --git a/docs copy/src/content/docs/challenges/angular/22-router-input.md b/docs copy/src/content/docs/challenges/angular/22-router-input.md new file mode 100644 index 000000000..1a5127e89 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/22-router-input.md @@ -0,0 +1,31 @@ +--- +title: 🟢 @RouterInput() +description: Challenge 22 is about using the @Input decorator to retrieve router params. +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - LMFinney +challengeNumber: 22 +command: angular-router-input +blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617 +sidebar: + order: 5 +--- + +## Information + +In this application, we retrieve three pieces of information inside our `TestComponent` provided by the router: + +- We want to retrieve `testId` found inside the params of the URL. +- We want to obtain `user` located within the query parameters of the URL. +- We want to access `permission` set inside the `data` object of the route. + +In Angular versions 15 or earlier, we use `ActivatedRoute` to obtain all this information and receive them through observables to listen for URL changes. + +In version 16, Angular introduced a new `Input` that can listen to route data. You can read more about it [here](https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617). + +## Statement + +The goal of this exercise is to refactor the code to use the new `RouterInput` strategy. diff --git a/docs copy/src/content/docs/challenges/angular/3-directive-enhancement.md b/docs copy/src/content/docs/challenges/angular/3-directive-enhancement.md new file mode 100644 index 000000000..2937e5800 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/3-directive-enhancement.md @@ -0,0 +1,52 @@ +--- +title: 🟠 Directive Enhancement +description: Challenge 3 is about enhancing a built-in directive +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - kabrunko-dev + - svenson95 + - LMFinney +challengeNumber: 3 +command: angular-directive-enhancement +blogLink: https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c +sidebar: + order: 101 +--- + +:::note +This exercise can feel obsolete with the new control flow and the empty block inside the `@for` block. However **structural directives** are not going to be deleted any time soon, so you can still learn a lot from this exercise. +::: + +## Information + +Directives are a very powerful tool only offered by the Angular framework. You can apply the DRY principle by having shared logic inside a directive and applying it to any component you want. + +But the real power is that you can enhance an already-existing directive, which moreover doesn't **belong** to you. + +## Statement + +In this exercise, we have a want to display a list of persons. If the list is empty, you must display _" the list is empty !! "_. + +Currently, we have: + +```typescript + +
+ {{ person.name }} +
+
+ The list is empty !! +``` + +We want to get rid of the `ng-container` by writing: + +```typescript +
+ {{ person.name }} +
+ The list is empty !! +``` + +The goal is to **improve the ngFor directive**. diff --git a/docs copy/src/content/docs/challenges/angular/31-module-to-standalone.md b/docs copy/src/content/docs/challenges/angular/31-module-to-standalone.md new file mode 100644 index 000000000..93b0850ef --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/31-module-to-standalone.md @@ -0,0 +1,29 @@ +--- +title: 🟢 Module to Standalone +description: Challenge 31 is about migrating a module based application to a standalone application. +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 31 +command: angular-module-to-standalone +sidebar: + order: 6 +--- + +## Information + +In v14, standalone components were released and made stable in v15. If you haven't played with them, it's never too late. You can try them out in this challenge. + +Moreover, the goal is to see how **Nx** and **standalone components** work together, and experience the process of decoupling your app with Nx lib and standalone components. + +Finally, standalone components are very simple to understand, but **routing/lazy-loaded components** can be a bit harder to grasp. This challenge will allow you to manipulate components at different levels of nesting and work with lazy loaded routes. + +After completing this challenge, standalone components will no longer hold any secrets for you. + +## Statement + +The goal of this challenge is to migrate your application from module based components to standalone components. + +## Note + +You can also test the [Angular schematic](https://angular.dev/reference/migrations/standalone) to migrate NgModule to Standalone components. _(Since we are using nx, start your command with nx instead of ng)_ diff --git a/docs copy/src/content/docs/challenges/angular/32-change-detection-bug.md b/docs copy/src/content/docs/challenges/angular/32-change-detection-bug.md new file mode 100644 index 000000000..633d41721 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/32-change-detection-bug.md @@ -0,0 +1,46 @@ +--- +title: 🟠 Change Detection Bug +description: Challenge 32 is about debugging an application that has issue when change detection is triggered +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - jdegand + - LMFinney +challengeNumber: 32 +command: angular-change-detection-bug +blogLink: https://medium.com/ngconf/function-calls-inside-template-are-dangerous-15f9822a6629 +sidebar: + order: 105 +--- + +:::note +This challenge is inspired by a real-life example that I simplified to create this nice challenge. +::: + +## Information + +In this small application, we have a navigation menu to route our application to either `BarComponent` or `FooComponent`. However, our application is not loading and no errors are displayed inside the console. + +## Statement + +The goal of the challenge is to debug this application and make it work. + +:::note +Without knowing the exact reason for the issue, you can "fix" the error and get the program to function. One such approach would be to memoize `getMenu`. The application might work again, but make sure you really understand the problem and its consequences. Making it work isn't always enough; fixing this bug in the wrong way can cause a loss of performance or lead to other problems later on. +::: + +## Hints + +
+ Hint 1 + + If you comment out `routerLinkActive="isSelected"` inside `NavigationComponent`, the application loads correctly. +
+ +
+ Hint 2 + +If you open the [`RouterLinkActive` source code](https://github.com/angular/angular/blob/main/packages/router/src/directives/router_link_active.ts) and go to **line 196**, Angular is calling `this.cdr.markForCheck` inside a microTask, which triggers a new CD cycle. If you comment out this line, the application loads again, however, the bug should not be fixed by changing the Angular source code. 😅😯 + +
diff --git a/docs copy/src/content/docs/challenges/angular/33-decoupling-components.md b/docs copy/src/content/docs/challenges/angular/33-decoupling-components.md new file mode 100644 index 000000000..2b900c7a6 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/33-decoupling-components.md @@ -0,0 +1,35 @@ +--- +title: 🟠 Decoupling Components +description: Challenge 33 is about decoupling two strongly coupled components using Injection Token +author: thomas-laforge +contributors: + - tomalaforge + - jdegand + - LMFinney +challengeNumber: 33 +command: angular-decoupling-components +sidebar: + order: 106 +--- + +> Big thanks to **Robin Goetz** and his [Spartan Project](https://github.com/goetzrobin/spartan). +> This challenge was proposed by Robin and is strongly inspired by his project. + +## Information + +The goal of this challenge is to separate the behavior of a component from its style. For the purpose of this challenge, we will be working on a button element. When we click on it, we will toggle a _disabled_ property which will change the style of the element. This is quite useless in real life but the challenge aims to demonstrate a useful concept. + +The behavior of the component (referred to as the _brain_ in the Spartan stack) is located in the brain library. The styling part (referred to as the _helmet_) is located inside the helmet library. Both libraries cannot depend on each other because we want to be able to publish them separately. To help us address the issue, we are using the Nx `enforce-module-boundaries` eslint rule. You can find more details [here](https://nx.dev/core-features/enforce-module-boundaries). + +However, the button's helmet needs to access the state of the component to style the button differently based on its state. As mentioned above, we cannot import the `BtnDisabledDirective` directly into the helmet library as done currently. If you go to [`BtnHelmetDirective`](../../libs/decoupling/helmet/src/lib/btn-style.directive.ts), you will encounter a linting error. **A project tagged with `type:hlm` can only depend on libs tagged with `type:core`**. + +## Statement + +The goal of this challenge is to find a way to decouple both Directives. + +### Hint + +
+ Hint 1 + Carefully read the title of the challenge 😇 +
diff --git a/docs copy/src/content/docs/challenges/angular/39-injection-token.md b/docs copy/src/content/docs/challenges/angular/39-injection-token.md new file mode 100644 index 000000000..4e2f3119d --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/39-injection-token.md @@ -0,0 +1,38 @@ +--- +title: 🟠 InjectionToken +description: Challenge 39 is about learning the power of dependency injection +author: thomas-laforge +contributors: + - tomalaforge + - jdegand + - LMFinney +challengeNumber: 39 +command: angular-injection-token +videoLinks: + - link: https://www.youtube.com/watch?v=ntggdQycFyc + alt: Injection Token by Arthur Lannelucq + flag: FR +sidebar: + order: 118 +--- + +## Information + +In this small application, we start with a `VideoComponent` containing a **1-second** timer. The development team decided to use a global constant to store the timer value: `DEFAULT_TIMER`. However, a few weeks later, the product team wants to add a new screen for phone calls called `PhoneComponent`, and we want to reuse the `TimerComponent`. However, the product team wants a timer of **2 seconds**. How can we achieve this? + +## Statement + +Currently, the timer is still 1 second for the `PhoneComponent`. The goal of this challenge is to change the timer value to 2 seconds for the `PhoneComponent`. + +## Constraints + +The use of `@Input` is forbidden. This example is basic, and using `@Input` could be a good option, but in more complex applications, the component we need to update can be deeply nested, making the use of `@Input` a really bad design. + +## Hint + +
+ Hint 1 + +Looking at this [blog post](https://itnext.io/stop-being-scared-of-injectiontokens-ab22f72f0fe9) can be of great help. + +
diff --git a/docs copy/src/content/docs/challenges/angular/4-typed-context-outlet.md b/docs copy/src/content/docs/challenges/angular/4-typed-context-outlet.md new file mode 100644 index 000000000..86d43e5f1 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/4-typed-context-outlet.md @@ -0,0 +1,46 @@ +--- +title: 🔴 Typed ContextOutlet +description: Challenge 4 is about strongly typing ngContextOutlet directives +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - jdegand + - LMFinney +challengeNumber: 4 +command: angular-typed-context-outlet +blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6 +sidebar: + order: 201 +--- + +## Information + +You can improve template type checking for custom directives by adding template guard properties to your directive definition. Angular offers the static function [`ngTemplateContextGuard`](https://angular.dev/guide/directives/structural-directives#improving-template-type-checking-for-custom-directives) to strongly type structural directives. + +However, the context of **NgTemplateOutlet** type is **Object**. But with the help of the above guard, we can improve that behavior. + +## Statement + +In this exercise, we want to learn how to strongly type our `ng-template` in our `AppComponent`. + +This exercise has two levels of complexity. + +### Level 1: Known Interface + +Currently, we have the following piece of code. + +![Unknown Person](../../../../assets/4/unknown-person.png 'Unknown Person') + +As we can see, `name` is of type `any`. We want to infer the correct type using the custom directive `PersonDirective`. + +### Level 2: Generic Interface + +Currently, we have the following piece of code. + +![Unknown Student](../../../../assets/4/unknown-student.png 'Unknown Student') + +As we can see, `student` is of type `any`. We want to infer the correct type using the custom directive `ListDirective`. + +But in this part, we want to pass a list of **any object** to `ListComponent`. And we still want the correct type to be inferred. diff --git a/docs copy/src/content/docs/challenges/angular/44-view-transition.md b/docs copy/src/content/docs/challenges/angular/44-view-transition.md new file mode 100644 index 000000000..74d0a88bb --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/44-view-transition.md @@ -0,0 +1,84 @@ +--- +title: 🔴 View Transition +description: Challenge 44 is about learning the new view transition animation API +author: thomas-laforge +contributors: + - tomalaforge + - jdegand + - LMFinney +challengeNumber: 44 +command: angular-view-transition +sidebar: + order: 208 +--- + +## Information + +This is the second of two animation challenges. The goal of this series is to master animations in Angular. + +The View Transition API is a brand-new API that provides a set of features that allow developers to control and manipulate the transitions and animations between views within an application. +It plays a pivotal role in enhancing the user experience (UX), bringing applications to life with engaging and captivating transitions to guide users through different pages or sections of the app. + +The goal of this challenge is to learn about and manipulate all types of transitions proposed by the API. + +To use the API, Angular provides a function `withViewTransitions()` that needs to be injected inside the router config. + +I would advise you to read the [Chrome documentation](https://developer.chrome.com/docs/web-platform/view-transitions). You will learn everything that is necessary to successfully complete the challenge. + +Here, however, is a short summary: +Firstly, each target DOM element has two states: an `old` one when the element is leaving the page, and a `new` one when it's entering the page: + +```css +::view-transition-old(root) { +/ / animation +} + +::view-transition-new(root) { +/ / animation +} +``` + +In order to target a specific element, you must add the selector `view-transition-name` to a CSS class on the DOM node, as shown below: + +```css +.specific-element { + view-transition-name: specific-element; +} +``` + +This allows you to create an animation for this element only. + +Lastly, if the same element is present in both views, you can automate the transition by assigning the same **transition name**. + +:::danger +Remember, you can have only ONE UNIQUE `view-transition-name` per page. +::: + +## Statement + +The goal of this challenge is to transition from the state shown in this video: + + + +To the final state shown in the following video: + + + +Observe the following: + +- The header slides in and out. +- Each element smoothly transitions to its new location. + +### Level 1 + +Focus only on the first thumbnail and create a seamless and pleasing transition. + +### Level 2 + +Create the same appealing transition for all thumbnails without duplicating the `view-transition-name`. Note that this page has only 3 thumbnails; in a real-life scenario, you could have significantly more. + +### Level 3 + +Shift to the correct Y location when navigating back and forth. diff --git a/docs copy/src/content/docs/challenges/angular/45-react-in-angular.md b/docs copy/src/content/docs/challenges/angular/45-react-in-angular.md new file mode 100644 index 000000000..cef0a4841 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/45-react-in-angular.md @@ -0,0 +1,81 @@ +--- +title: 🔴 React in angular +description: Challenge 45 is about learning how to benefit from the numerous libraries in React +author: wandrille-guesdon +contributors: + - wandri + - tomalaforge + - jdegand + - LMFinney +challengeNumber: 45 +command: angular-react-in-angular +sidebar: + order: 209 +--- + +The goal of this challenge is to use a React component inside an Angular application. + +Many components are available in React, and it can be interesting to use them in an Angular application. The goal is to create a React component and use it in an Angular application. + +## Information + +In this challenge, we have a simple application and a React component `ReactPost` in `app/react` to illustrate a React component from a library. + +## Statement + +- Your task is to display the posts with the React component `ReactPost`. +- When you select a post, the post should be highlighted. + +In order to play with the React component, you should start by installing the React dependencies. + +```bash +npm i --save react react-dom +npm i --save-dev @types/react @types/react-dom +``` + +## Constraints + +- Do not transform the React component into an Angular component. The React component is pretty simple and can be written with ease in Angular. But **the goal is to use the React component**. + +### Hint + +
+ Hint 1 - Configuration + Allow the React files in tsconfig.json + +``` +{ +... +"compilerOptions": { + ... + "jsx": "react" +}, +... +} +``` + +
+ +
+ Hint 2 - Initialization + Create a React root with `createRoot(...)` +
+ +
+ Hint 3 - Display + To render the component, it should look like this: + + ``` + .render( + + ... + + ) + ``` + +
+ +
+ Hint 4 - Design + Do not forget to allow the React file in Tailwind. +
diff --git a/docs copy/src/content/docs/challenges/angular/46-simple-animations.md b/docs copy/src/content/docs/challenges/angular/46-simple-animations.md new file mode 100644 index 000000000..aa8887977 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/46-simple-animations.md @@ -0,0 +1,49 @@ +--- +title: 🟢 Simple Animations +description: Challenge 46 is about learning Angular's integrated animation API +author: sven-brodny +contributors: + - svenson95 + - LMFinney +challengeNumber: 46 +command: angular-simple-animations +sidebar: + order: 17 +--- + +## Information + +This is the first of two animation challenges. The goal of this series is to master animations in Angular. + +Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic. Animations can improve your application and user experience in a number of ways: + +- Without animations, web page transitions can seem abrupt and jarring. +- Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions. +- Good animations intuitively call the user's attention to where it is needed. + +I would recommend you read the [official documentation](https://angular.dev/guide/animations). You will learn everything that is necessary to successfully complete the challenge. + +Otherwise, look at this [working example](https://svenson95.github.io/ng-xmp-animations/) and [git repo](https://github.com/svenson95/ng-xmp-animations) to get inspired. + +## Statement + +The goal of this challenge is to add animations, they should run when the user arrives on the page or reload the page. + +## Constraints + +- Don't use any CSS and utilize Angular's integrated `@angular/animations` API. +- Don't trigger the animations with a button like in the examples, rather when the user enter or reload the page. + +### Level 1 + +Add a fading or moving animation for the paragraphs on the left side. + + + +### Level 2 + +Add a stagger animation for the list on the right side. + + diff --git a/docs copy/src/content/docs/challenges/angular/5-crud-application.md b/docs copy/src/content/docs/challenges/angular/5-crud-application.md new file mode 100644 index 000000000..1e439150a --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/5-crud-application.md @@ -0,0 +1,56 @@ +--- +title: 🟢 Crud application +description: Challenge 5 is about refactoring a crud application +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - jdegand + - LMFinney +challengeNumber: 5 +command: angular-crud-application +sidebar: + order: 2 +--- + +## Information + +Communicating and having a global/local state in sync with your backend is the heart of any application. You will need to master these following best practises to build strong and reliable Angular Applications. + +## Statement + +In this exercise, you have a small CRUD application, which get a list of TODOS, update and delete some todos. + +Currently, we have a working example but filled with lots of bad practices. + +### Step 1: refactor with best practices + +What you will need to do: + +- Avoid **any** as a type. Using Interface to leverage Typescript type system prevent errors +- Use a **separate service** for all your http calls and use a **Signal** for your todoList +- Don't **mutate** data + +```typescript +// Avoid this +this.todos[todoUpdated.id - 1] = todoUpdated; + +// Prefer something like this, but need to be improved because we still want the same order +this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]; +``` + +### Step 2: Improve + +- Add a **Delete** button: _Doc of fake API_ +- Handle **errors** correctly. _(Globally)_ +- Add a Global **loading** indicator. _You can use MatProgressSpinnerModule_ + +### Step 3: Maintainability!! add some test + +- Add 2/3 tests + +### Step 4: Awesomeness!!! master your state. + +- Use the **component store of ngrx**, **ngrx/store**, **rxAngular**, **tanstack-query** or **ngrx/signal-store** as a local state of your component. +- Have a **localized** Loading/Error indicator, e.g. only on the Todo being processed and **disable** all buttons of the processed Todo. _(Hint: you will need to create an ItemComponent)_ diff --git a/docs copy/src/content/docs/challenges/angular/52-lazy-load-component.md b/docs copy/src/content/docs/challenges/angular/52-lazy-load-component.md new file mode 100644 index 000000000..f71c57d48 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/52-lazy-load-component.md @@ -0,0 +1,48 @@ +--- +title: 🟢 Lazy Load a Component +description: Challenge 52 is about understanding how to lazy load a component in Angular. +author: lance-finney +contributors: + - LMFinney +challengeNumber: 52 +command: angular-lazy-load-component +sidebar: + order: 21 +--- + +## Information + +Angular has long had route-based lazy loading for entire modules, but lazy loading individual components was much more complicated. This challenge is about understanding how to lazy load a component easily with a feature that was introduced in Angular 17. + +## Statement + +This is a simple application that can display a `TopComponent` that we are pretending would slow the application down if it were part of the initial bundle (it actually contains just a bit of text, but we are pretending). + +The current implementation shows a `PlaceholderComponent` until the user clicks a button to display the `TopComponent`. However, even though the `TopComponent` isn't visible until the button is clicked, it is still loaded as part of the initial bundle. + +Use a new feature of Angular 17 to lazy load the `TopComponent` so that it is visible _and loaded_ when the user clicks the button to display it. + +When you are done, you should be able to see the `TopComponent` being loaded into the browser in a separate bundle when you click the button to display it. In Chrome, you should see this by opening the DevTools, going to the Network tab, and then clicking the button to display the `TopComponent`. + +## Hints + +
+ Hint 1 + +You should be able to remove the `topLoaded` signal when you are done. + +
+ +
+ Hint 2 + +The new Angular feature will hide the `TopComponent` from view, but it will still be loaded in the initial bundle unless you change how both `AppComponent` and `TopComponent` are defined in their decorators. This challenge start with the old `NgModule`-based architecture, but you will need to change it to use the new feature. + +
+ +
+ Hint 3 + +The new feature is [Deferrable Views](https://angular.dev/guide/defer), which provides several different triggers. One of them is ideal for this challenge. + +
diff --git a/docs copy/src/content/docs/challenges/angular/55-back-button-navigation.md b/docs copy/src/content/docs/challenges/angular/55-back-button-navigation.md new file mode 100644 index 000000000..3a2255f49 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/55-back-button-navigation.md @@ -0,0 +1,56 @@ +--- +title: 🟠 Back-Button-Navigation +description: Challenge 55 is about overriding browser back button navigation +author: Ioannis-Tsironis +contributors: + - tsironis13 +challengeNumber: 55 +command: angular-back-button-navigation +sidebar: + order: 123 +--- + +## Information + +The goal of this challenge is to override the default behavior of the browser back button in Angular applications. + +We have been prompted by the team's PO to provide a specific implementation when displaying dialog components and +native browser back button is clicked. Currently, Angular's default behavior when the native back button is clicked is +to remove the current history entry and go back to the previous route. + +The initial state of the application is as follows: +When any dialog is displayed and the back button is clicked, any opened dialog is closed, and the app redirects to the previous page. + +This behavior should be changed according to these requirements: + +1. The requirements dictate a few different behaviors depending on which type of dialog is currently visible. +2. For example, we have a simple + action dialog that should be closed on the back button click, but we **MUST** remain on the current visited route (/simple-action). +3. In addition, we have sensitive dialogs like the one on the '/sensitive-action' page that must open a confirmation dialog on a back button click. +4. The confirmation dialog in combination with the back button click should behave like the simple dialog action one; the confirmation dialog must be closed, and we must remain on the '/sensitive-action' page with the initial dialog still visible. + +## Statement + +Provide an abstract, generic approach to handling any type of dialog behavior when the native browser back button is clicked. +Some Typescript design patterns, in combination with the Angular features, could be utilized to support this kind of infrastructure. + +## Constraints + +- The implementation must not be static depending on the 2 dialog type behaviors presenting on this challenge but also scalable to support any + new behavior requirements may arise in the future. + +### Hint + +
+ Hint 1 + +Use the `CanDeactivate` functional guard + +
+ +
+ Hint 2 + +Material Design dialog documentation can be found [here](https://material.angular.io/components/dialog/overview) + +
diff --git a/docs copy/src/content/docs/challenges/angular/57-content-projection-default.md b/docs copy/src/content/docs/challenges/angular/57-content-projection-default.md new file mode 100644 index 000000000..68bc9454a --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/57-content-projection-default.md @@ -0,0 +1,36 @@ +--- +title: 🟢 Content Projection Default +description: Challenge 57 is about content projection default container +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 57 +command: angular-content-projection-default +sidebar: + order: 22 +--- + +## Information + +Content projection in Angular allows developers to create flexible and customizable components by passing content from the parent component to the child component dynamically using ``. + +Currently, we have a shared component that relies on `input` properties to receive and display data. However, we want to improve its flexibility by replacing all `inputs` with content projection while maintaining the same appearance and behavior. + +## Statement + +Your task is to refactor the existing shared component to remove all `input` properties and instead use Angular’s `` for content projection. After your modifications, the application should look and function exactly as before, but without any `input`. + +### Steps to complete: + +- Identify all `input` properties in the shared component. +- Remove them and replace them with appropriate `` containers. +- Adjust the parent component to pass the necessary content using content projection instead of binding to `input`s. +- Ensure that the application still displays the same UI and behavior after the changes. + +## Constraints + +- You must not use any `input` in the shared component. +- The application’s UI and functionality must remain unchanged after the refactoring. +- You must use `` for content projection. +- Do not introduce additional properties or services to pass data. +- Ensure that projected content is correctly styled and positioned as before. diff --git a/docs copy/src/content/docs/challenges/angular/58-content-projection-condition.md b/docs copy/src/content/docs/challenges/angular/58-content-projection-condition.md new file mode 100644 index 000000000..7dead94de --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/58-content-projection-condition.md @@ -0,0 +1,38 @@ +--- +title: 🟠 Content Projection Condition +description: Challenge 58 is about conditional content projection in Angular +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 58 +command: angular-content-projection-condition +sidebar: + order: 124 +--- + +## Information + +Content projection in Angular allows you to create flexible and reusable components by dynamically inserting content from a parent component using ``. However, debugging content projection issues can sometimes be tricky. + +In this challenge, we have a `CardComponent` that supports a small mode, which conditionally changes how the projected content is displayed. However, there is a bug: when `small` is `false`, the card does not render properly. + +Your task is to identify and fix this issue without adding `inputs` while ensuring that the intended behavior remains unchanged. + +## Statement + +Your goal is to fix the issue where the `CardComponent` does not render when `small` is `false`. + +## Steps to complete: + +- Analyze how the `small` property is used inside the template. +- Identify why the content is not displayed when `small` is `false`. +- Modify the component to ensure that both cases (`small` = `true` and `small` = `false`) work as expected, while keeping the same structure and behavior. +- Ensure that no new `input` properties are introduced in the component. + +## Constraints + +- You must not add any new `input` properties. +- The expected UI and behavior must remain unchanged. +- The `@if` directive must be correctly handled to ensure content projection works. +- Do not introduce additional services or state management solutions. +- The fix should be minimal and focused on resolving the rendering issue. diff --git a/docs copy/src/content/docs/challenges/angular/59-content-projection-defer.md b/docs copy/src/content/docs/challenges/angular/59-content-projection-defer.md new file mode 100644 index 000000000..0a8ab685e --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/59-content-projection-defer.md @@ -0,0 +1,28 @@ +--- +title: 🔴 content-projection-defer +description: Challenge 59 is about deferring fetching data +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 59 +command: angular-content-projection-defer +sidebar: + order: 212 + badge: New +--- + +# Challenge: Deferred Loading for Expandable Card Content + +## Information + +Within the application, specifically on page2, there is an expandable card component. This component consists of a permanently visible title and a content section that is hidden until the card is expanded. This content section is populated with a list of posts retrieved via a backend API call. The current implementation presents an issue: upon navigating to page2, although the card defaults to a collapsed state, the API call to load the list of posts is triggered immediately during the page load process, before the user has chosen to expand the card and view the content. + +## Statement + +The goal of this challenge is to optimize the data loading behavior for the expandable card component on `page2`. Modify the implementation so that the backend API call to fetch the list of posts is **deferred**. The data should **only** be fetched when the user explicitly interacts with the card to **expand** it. No data fetching for the post list should occur upon the initial load of `page2` while the card remains collapsed. + +## Constraints + +- The expandable card must retain its core functionality: display a title, be initially collapsed (on `page2` load), and expand/collapse upon user interaction. +- When the card is expanded, the list of posts must be fetched from the backend and displayed within the content area. +- The data fetching mechanism itself (e.g., the API endpoint) should not be changed, only _when_ it is triggered. diff --git a/docs copy/src/content/docs/challenges/angular/6-structural-directive.md b/docs copy/src/content/docs/challenges/angular/6-structural-directive.md new file mode 100644 index 000000000..48cae6f56 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/6-structural-directive.md @@ -0,0 +1,63 @@ +--- +title: 🟠 Structural Directive +description: Challenge 6 is about creating a structural directive to handle permissions +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - kabrunko-dev + - svenson95 +challengeNumber: 6 +command: angular-structural-directive +blogLink: https://medium.com/@thomas.laforge/create-a-custom-structural-directive-to-manage-permissions-like-a-pro-11a1acad30ad +sidebar: + order: 102 +--- + +## Information + +Structural directives are directives which change the DOM layout by adding and removing DOM elements. This is an important concept you'll need to improve your angular skills and knowledge. This will be the first part of this challenge. For more information check out the [official documentation](https://angular.dev/guide/directives/structural-directives). + +Guards like `CanActivate` or `CanMatch` are also very important, since you'll need it in the most application's you build. If you're not very familiar with route guards, check out this two articles. + +- [Everything you need to know about route Guard in Angular](https://itnext.io/everything-you-need-to-know-about-route-guard-in-angular-697a062d3198) +- [Create a route Guard to manage permissions](https://medium.com/@thomas.laforge/create-a-route-guard-to-manage-permissions-26f16cc9a1ca) + +## Statement + +In `LoginComponent` you'll find 6 buttons corresponding to 6 different user's role. + +- Admin +- Manager +- Reader +- Writer +- Reader and Writer +- Client +- Everyone + +## Step 1 + +In `InformationComponent` you'll need to display the correct piece of information for each role using a structural directive. + +### Constraints + +- No `ngIf` or `@if` inside `InformationComponent`. +- Importing the store inside `InformationComponent` is not allowed. + +You should end up with something like below: + +```html +
Info for Role1
+``` + +```html +
Info for Role1 and Role2
+``` + +```html +
Info Only for superadmin
+``` + +## Step 2 + +In `Routes.ts` you should route all users to the correct `DashboardComponent` using `CanMatch` guard. diff --git a/docs copy/src/content/docs/challenges/angular/8-pure-pipe.md b/docs copy/src/content/docs/challenges/angular/8-pure-pipe.md new file mode 100644 index 000000000..c981cda55 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/8-pure-pipe.md @@ -0,0 +1,41 @@ +--- +title: 🟢 Pure Pipe +description: Challenge 8 is about creating a pure pipe +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - kabrunko-dev + - svenson95 + - LMFinney +challengeNumber: 8 +command: angular-pure-pipe +blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d +sidebar: + order: 3 +--- + +## Information + +This is the first of three `@Pipe()` challenges. The goal of this series is to master **pipes** in Angular. + +Pipes are a very powerful way to transform data in your template. The difference between calling a function and a pipe is that pure pipes are memoized. So, they won't be recalculated every change detection cycle if their inputs haven't changed. + +Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improve rendering performance. + +By default, a pipe is pure. You should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders. + +:::note +A **pure** pipe is only called when the value changes.\ +A **impure** pipe is called every change detection cycle. +::: + +There are some useful predefined pipes like the DatePipe, UpperCasePipe and CurrencyPipe. To learn more about pipes in Angular, check the API documentation [here](https://angular.dev/guide/pipes). + +## Statement + +In this exercise, you need to refactor a transform function inside a component, which is called inside your template. The goal is to convert this function to a pipe. + +## Constraints + +- Must be strongly typed diff --git a/docs copy/src/content/docs/challenges/angular/9-wrap-function-pipe.md b/docs copy/src/content/docs/challenges/angular/9-wrap-function-pipe.md new file mode 100644 index 000000000..5213fb079 --- /dev/null +++ b/docs copy/src/content/docs/challenges/angular/9-wrap-function-pipe.md @@ -0,0 +1,42 @@ +--- +title: 🟠 Wrap Function Pipe +description: Challenge 9 is about creating a pipe to wrap component fonctions +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - kabrunko-dev + - svenson95 + - LMFinney +challengeNumber: 9 +command: angular-wrap-function-pipe +blogLink: https://medium.com/ngconf/boost-your-apps-performance-by-wrapping-your-functions-inside-a-pipe-7e889a901d1d +sidebar: + order: 103 +--- + +## Information + +This is the second of three `@Pipe()` challenges. The goal of this series is to master **pipes** in Angular. + +Pipes are a very powerful way to transform data in your template. The difference between calling a function and a pipe is that pure pipes are memoized. So, they won't be recalculated every change detection cycle if their inputs haven't changed. + +Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improve rendering performance. + +By default, a pipe is pure. You should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders. + +:::note +A **pure** pipe is only called when the value changes.\ +A **impure** pipe is called every change detection cycle. +::: + +There are some useful predefined pipes like the DatePipe, UpperCasePipe and CurrencyPipe. To learn more about pipes in Angular, check the API documentation [here](https://angular.dev/guide/pipes). + +## Statement + +In this exercise, you are calling multiple functions inside your template. You can create a specific pipe for each of the functions, but this will be too cumbersome. +The goal is to create a `wrapFn` pipe to wrap your callback function through a pipe. Your function MUST remain inside your component. **`WrapFn` must be highly reusable.** + +## Constraints + +- Must be strongly typed diff --git a/docs copy/src/content/docs/challenges/forms/41-control-value-accessor.md b/docs copy/src/content/docs/challenges/forms/41-control-value-accessor.md new file mode 100644 index 000000000..57f4473c4 --- /dev/null +++ b/docs copy/src/content/docs/challenges/forms/41-control-value-accessor.md @@ -0,0 +1,43 @@ +--- +title: 🟠 Control Value Accessor +description: Challenge 41 is about creating a custom form control that implements Control Value Accessor interface. +author: stanislav-gavrilov +contributors: + - stillst +challengeNumber: 41 +command: forms-control-value-accessor +sidebar: + order: 1 +--- + +## Information + +In this challenge, the goal is to create a custom form field that is using the Form API of Angular `ControlValueAccessor`. You can find the documentation [here](https://angular.dev/api/forms/ControlValueAccessor). This interface is crucial for creating custom form controls that can interact seamlessly with Angular's forms API. + +## Statement + +The primary goal is to use control in the `feedbackForm` to eliminate the need for using `@Output` to retrieve the value and inject it into the `FormGroup`. +Additionally, you are required to integrate validation for the new control to ensure that rating data exist. (The form submission button should be disabled if the form is invalid). + +Currently, rating is coded this way: + +```html + +``` + +```ts +rating: string | null = null; + +onFormSubmit(): void { + this.feedBackSubmit.emit({ + ...this.feedbackForm.value, + rating: this.rating, // not inside the FormGroup and no validation + }); +} +``` + +The goal is to include rating into the `FormGroup` + +```html + +``` diff --git a/docs copy/src/content/docs/challenges/forms/48-avoid-losing-form-data.md b/docs copy/src/content/docs/challenges/forms/48-avoid-losing-form-data.md new file mode 100644 index 000000000..1af6c52c4 --- /dev/null +++ b/docs copy/src/content/docs/challenges/forms/48-avoid-losing-form-data.md @@ -0,0 +1,40 @@ +--- +title: 🟠 Avoid losing form data +description: Challenge 48 is about Bob 🧙‍♂️ the product owner, he wants to develop a new feature in response to customer complaints about losing form input information. +author: timothy-alcaide +contributors: + - alcaidio + - svenson95 + - LMFinney +challengeNumber: 48 +command: forms-avoid-losing-form-data +sidebar: + order: 121 +--- + +## Context + +As a member of the development team, you need to address a specific request from the product owner, 🧙‍♂️ Bob. He wants to develop a new feature in response to customer complaints about losing form input information. + +## User Story + +Here's the feature expressed as a user story with a functional expectation: + +> As a user, I would like to have an alert dialog box that appears when +> I attempt to navigate away from the page, after I have started +> entering information into the form. + +## Acceptance Criteria + +1. If one of the form fields is not empty and the user tries to navigate to a different route or page, or wants to reload the page, show an alert dialog to _avoid losing form data_. +2. The content of `dialog.component.ts` must be used for your alert. +3. The appearance and behavior of the alert dialog box must comply with W3C conventions, see [alert dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/). +4. Maximize the use of the new concepts and syntax in the latest version of Angular. + +
+ Tips 🤫 (if you really need it and after careful consideration) +
    +
  • Use the Material CDK Dialog or Overlay - don't forget to add @import '@angular/cdk/overlay-prebuilt.css' in styles.scss
  • +
  • Use the CanDeactivate guard in the new functional approach.
  • +
+
diff --git a/docs copy/src/content/docs/challenges/nx/25-generator-lib-ext.md b/docs copy/src/content/docs/challenges/nx/25-generator-lib-ext.md new file mode 100644 index 000000000..891be9b16 --- /dev/null +++ b/docs copy/src/content/docs/challenges/nx/25-generator-lib-ext.md @@ -0,0 +1,56 @@ +--- +title: 🔴 Extend Lib Generator +description: Challenge 25 is about creating a Nx generator to extend the built-in Library Generator +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 25 +sidebar: + order: 207 +--- + +## Information + +Welcome to the marvelous world of Nx generators. + +Generators are awesome tools that can help you and your team generate code more quickly, especially for pieces of code that you use frequently. While using Nx, you create libraries regularly, but sometimes the default generator doesn't perfectly meet your needs. + +## Statement + +The goal of this challenge is to create a generator that extends the default library generator of Nx. You will need to override the default `jest.config.ts` and a `eslintrc.json` with a custom one. + +You can either use all the default parameters of the Nx library generator or choose to modify some and keep others as defaults. The choice is yours. + +## Constraints + +You should only override the jest configuration is the `unitTestRunner` option is set at `jest`, and you should only update the eslint configuration if the `linter` is set to `eslint`. + +--- + +`jest.config.ts` + +```ts +/* eslint-disable */ +export default { + displayName: '< libName >', // 👈 lib name + preset: '../../../jest.preset.js', // 👈 be careful with the path + setupFilesAfterEnv: ['/src/subscription-setup.ts'], + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!(.*\\.mjs$|lodash-es))'], +}; +``` + +--- + +`eslintrc.json` + +Add the rule `"@typescript-eslint/member-ordering": "off"` inside the rules properties of ts files. diff --git a/docs copy/src/content/docs/challenges/nx/26-generator-comp.md b/docs copy/src/content/docs/challenges/nx/26-generator-comp.md new file mode 100644 index 000000000..308296418 --- /dev/null +++ b/docs copy/src/content/docs/challenges/nx/26-generator-comp.md @@ -0,0 +1,149 @@ +--- +title: 🟠 Component Generator +description: Challenge 26 is about creating a Nx generator to create a custom component +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - Sagardevkota + - LMFinney +challengeNumber: 26 +sidebar: + order: 116 +--- + +## Information + +Welcome to the marvelous world of Nx generators. + +Generators are awesome tools that can help you and your team generate code more quickly, especially for pieces of code that you use frequently. Inside an enterprise project, you often have to create components that look similar. And most of the time, you end up copy/pasting other components. In Nx, you can create this boilerplate in a simple command using generators. + +## Statement + +The goal of this challenge is to create a generator that will create all the boilerplate of a component for you. + +Below are the end result of your generator for a `UserComponent` associated with a `@ngrx/component-store`. + +## Options + +- name : name of your component/store/service +- createService: flag to tell if a http service should be created + - yes : create as below + - no: don't create the inject/import/effect/function call (anything related to the service call) +- inlineTemplate: flag to decide if template should be inline or in a separate file + +--- + +`user.component.ts` + +```ts +@Component({ + selector: 'app-user', + standalone: true, + imports: [LetDirective], + providers: [provideComponentStore(UserStore)], + template: ` + // do things + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class UserComponent { + private userStore = inject(UserStore); + + readonly vm$ = this.userStore.vm$; +} +``` + +--- + +`user.store.ts` + +```ts +import { Injectable, inject } from '@angular/core'; +import { ComponentStore, OnStateInit, OnStoreInit } from '@ngrx/component-store'; +import { tapResponse } from '@ngrx/operators'; +import { mergeMap, pipe, tap } from 'rxjs'; +import { User } from './user.model'; +import { UserService } from './user.service'; + +export interface UserState { + users: User[]; + loading: boolean; + error?: string; +} + +const initialState: UserState = { + users: [], + loading: false, + error: undefined, +}; + +@Injectable() +export class UserStore extends ComponentStore implements OnStateInit, OnStoreInit { + private userService = inject(UserService); + + private readonly users$ = this.select((state) => state.users); + private readonly loading$ = this.select((state) => state.loading); + private readonly error$ = this.select((state) => state.error); + + readonly vm$ = this.select( + { + users: this.users$, + loading: this.loading$, + error: this.error$, + }, + { debounce: true }, + ); + + ngrxOnStateInit() { + this.setState(initialState); + } + + ngrxOnStoreInit() { + this.loadUsers(); + } + + readonly loadUsers = this.effect( + pipe( + tap(() => this.patchState({ loading: true })), + mergeMap(() => + this.userService.loadUsers().pipe( + tapResponse( + (users) => this.patchState({ users, loading: false }), + (err: string) => this.patchState({ error: err, loading: false }), + ), + ), + ), + ), + ); +} +``` + +--- + +`user.service.ts` + +```ts +import { BASE_URL } from '@angular-challenges/fake-utils'; +import { HttpClient } from '@angular/common/http'; +import { Injectable, inject } from '@angular/core'; +import { User } from './user.model'; + +@Injectable({ providedIn: 'root' }) +export class UserService { + private http = inject(HttpClient); + private BASE_URL = inject(BASE_URL); + + loadUsers = () => this.http.get(`${this.BASE_URL}/users`); +} +``` + +--- + +`user.model.ts` + +```ts +export interface User { + name: string; +} +``` diff --git a/docs copy/src/content/docs/challenges/nx/27-forbid-enum-rule.md b/docs copy/src/content/docs/challenges/nx/27-forbid-enum-rule.md new file mode 100644 index 000000000..998e11c49 --- /dev/null +++ b/docs copy/src/content/docs/challenges/nx/27-forbid-enum-rule.md @@ -0,0 +1,27 @@ +--- +title: 🟢 Custom Eslint Rule +description: Challenge 27 is about creating a custom ESLint Rule to forbid enums +author: thomas-laforge +contributors: + - tomalaforge + - jdegand +challengeNumber: 27 +sidebar: + order: 12 +--- + +## Information + +ESLint is an amazing tool that helps developers avoid simple mistakes and adhere to company style guides. + +In this first example, we will create a rule that forbids the use of enums. The rule will suggest using string unions instead of enums whenever an enum is present in this repo's code. This is a straightforward rule for learning how to create rules. + +You will also need to write tests to verify the rule's functionality. + +The starter code for this challenge can be found (from the root folder) inside `tools/eslint-rules/rules`. + +To test the rule inside your project, add `"@nx/workspace/forbidden-enum": "error"` to the `eslintrc.json`. You can navigate to Challenge 47, `Enums vs. Union Types', and you should immediately see an error. + +To assist you with AST (Abstract Syntax Tree) definitions, you can visit the [AST Explorer](https://astexplorer.net/) and use `JavaScript`, `@typescript-eslint/parser`, and `ESLint-v8` as the transformation methods. However, please note that you will only get the `type` information there. The transformation function may not work for TypeScript types since the editor is in JavaScript. + +You can also check this [repo](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin/src/rules) for ESLint rule examples. diff --git a/docs copy/src/content/docs/challenges/nx/42-static-vs-dynamic-import.md b/docs copy/src/content/docs/challenges/nx/42-static-vs-dynamic-import.md new file mode 100644 index 000000000..2e04e1447 --- /dev/null +++ b/docs copy/src/content/docs/challenges/nx/42-static-vs-dynamic-import.md @@ -0,0 +1,31 @@ +--- +title: 🟢 Static vs Dynamic Import +description: Challenge 42 is about understanding and fixing the eslint rule - Static imports of lazy-loaded libraries are forbidden. +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 42 +command: nx-static-vs-dynamic-import +sidebar: + order: 15 +--- + +## Information + +If you are using **Nx**, you might have encountered this error: + +```ts +Static imports of lazy-loaded libraries are forbidden. + +Library "users" is lazy-loaded in these files: + +- apps/nx/static-dynamic-import/src/app/app.config.ts eslint@nx/enforce-module-boundaries +``` + +This error is part of the ESLint rule embedded by Nx to prevent people from mixing lazy-loading and eagerly-loading code from the same library. Although this error will not break at runtime or build time, it can lead to consequences for bundle size. The lazy-loaded code will end up in the main bundle, nullifying all the benefits of lazy-loading a library. + +## Statement + +The goal of this challenge is to improve the code architecture to eliminate this ESLint error. + +You will learn how to create a library and how to rearrange code. diff --git a/docs copy/src/content/docs/challenges/performance/12-optimize-change-detection.md b/docs copy/src/content/docs/challenges/performance/12-optimize-change-detection.md new file mode 100644 index 000000000..5fa698a43 --- /dev/null +++ b/docs copy/src/content/docs/challenges/performance/12-optimize-change-detection.md @@ -0,0 +1,41 @@ +--- +title: 🟠 Optimize Change Detection +description: Challenge 12 about optimizing the number of change detection cycle while scrolling +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 12 +command: performance-optimize-change-detection +sidebar: + order: 107 +--- + +## Information + +In Angular, there is a library called Zone.js that performs a lot of magic to simplify a developer's life. Zone.js monkey patches all DOM events so that it will recheck and rerender the view when something has changed inside the application. The developer doesn't have to manually trigger change detection. + +However, sometimes Zone.js triggers a lot more change detection than needed. For example, when you are listening to a scroll event, each scroll event will dispatch a new change detection cycle. + +In this challenge, we only need to refresh the view at a specific scroll position to display or hide a button. All other cycles are unnecessary. + +To have a better visualization of the problem, profile your application with Angular Dev Tools. + +:::note +If you don't know how to use it, read [the performance introduction page](/challenges/performance/) first and come back after. +::: + +You can learn more details about zone pollution and how to resolve it [here](https://angular.dev/best-practices/zone-pollution). + +The following video will explain more in-depth the issue of this application. + + + +## Statement + +Your goal for this challenge is to avoid all unnecessary change detection cycles and trigger a change detection only when needed. + +## Constraint: + +You cannot opt out of Zone.js globally. If this code is part of a large project, and you opt out of Zone.js, you will break your application without any doubt. diff --git a/docs copy/src/content/docs/challenges/performance/34-default-vs-onpush.md b/docs copy/src/content/docs/challenges/performance/34-default-vs-onpush.md new file mode 100644 index 000000000..779af5324 --- /dev/null +++ b/docs copy/src/content/docs/challenges/performance/34-default-vs-onpush.md @@ -0,0 +1,57 @@ +--- +title: 🟢 Default vs OnPush +description: Challenge 34 is about learning the difference between Default and OnPush Change Detection Strategy. +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 34 +command: performance-default-vs-onpush +sidebar: + order: 7 +--- + +## Information + +In this challenge, we will explore the differences and impacts of using `ChangeDetectionStrategy.Default` versus `ChangeDetectionStrategy.OnPush`. + +You can read the [Angular documentation](https://angular.dev/best-practices/skipping-subtrees) to learn more about the differences between these strategies. + +In this challenge, all components start with the `Default` strategy. When you type letters inside the input field, you will notice that all components are highlighted in orange. + +:::note +I added color highlighting to each component and each row to provide a better visualization of when a component is rerendered. +::: + +As you can see, each letter triggers a new change detection cycle, and all components are rerendered, causing performance issues. + +Let's use the Angular DevTool to profile our application and understand how this tool can help us understand what is happening inside our application. + +:::note +If you don't know how to use it, read [the performance introduction page](/challenges/performance/) first and come back after. +::: + +Now, start profiling your application and type some letters inside the input field to trigger some change detection cycles. + +If you click on one of the bars (indicated by the yellow arrow in the picture below), you can see that `PersonListComponent`, `RandomComponent`, and all the `MatListItem` are impacted by the change detection cycle, even when we only interact with the input field. + +![profiler record](../../../../assets/performance/34/profiler-record.png 'Profiler Record') + +## Statement + +The goal of this challenge is to improve the clustering of change detection within the application using the `OnPush` change detection strategy, but not only... + +## Hints: + +
+ Hint 1 + +Use `ChangeDetectionStrategy.OnPush` but this will not be enough. + +
+ +
+ Hint 2 + +Create smaller components to better separate the input field from the list. + +
diff --git a/docs copy/src/content/docs/challenges/performance/35-memoization.md b/docs copy/src/content/docs/challenges/performance/35-memoization.md new file mode 100644 index 000000000..52f61389b --- /dev/null +++ b/docs copy/src/content/docs/challenges/performance/35-memoization.md @@ -0,0 +1,51 @@ +--- +title: 🟢 Memoization +description: Challenge 35 is about learning how pure pipe works +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 35 +command: performance-memoization +sidebar: + order: 8 +--- + +## Information + +In Angular, pure Pipes are very powerful because the value is memoized, which means if the input value doesn't change, the `transform` function of the pipe is not recomputed, and the cached value is outputted. + +You can learn more about pipes in the [Angular documentation](https://angular.dev/guide/pipes) and inside this [deep dive article](https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d). + +In this challenge, we start with a button to load a list of people. Each person is associated with a number, and we will use the Fibonacci calculation to create a heavy computation that will slow down the application. + +Once the list is loaded, try typing some letters inside the input field. You will notice that the application is very slow, even though you are only performing very basic typing. + +:::note +We will not focus on the initial loading of the list in this challenge. +::: + +Let's use the Angular DevTool to profile our application and understand how this tool can help us understand what is happening inside our application. + +:::note +If you don't know how to use it, read [the performance introduction page](/challenges/performance/) first and come back after. +::: + +Now, start profiling your application and type some letters inside the input field. You will see some red bars showing up inside the profiler panel. + +If you click on one of the bars (indicated by the yellow arrow in the picture below), you will see that the change detection cycle is taking more than 3s in `PersonListComponent`. + +![profiler record](../../../../assets/performance/35/memoize-profiler.png 'Profiler Record') + +## Statement + +The goal of this challenge is to understand what is causing this latency and to improve it. + +## Hints: + +
+ Hint 1 + +Use `Pipes` to memoize the Fibonacci computation. + +
diff --git a/docs copy/src/content/docs/challenges/performance/36-ngfor-optimization.md b/docs copy/src/content/docs/challenges/performance/36-ngfor-optimization.md new file mode 100644 index 000000000..336f525fa --- /dev/null +++ b/docs copy/src/content/docs/challenges/performance/36-ngfor-optimization.md @@ -0,0 +1,34 @@ +--- +title: 🟢 NgFor Optimization +description: Challenge 36 is about learning how trackby works +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 36 +command: performance-ngfor-optimization +sidebar: + order: 13 +--- + +## Information + +In this application, we have a list of individuals that we can add, delete or update. If you open the developer Chrome panel by pressing **F12**, go to the Elements tab, and expand the element to see the list, you will notice that each time you add, delete or update a list item, all the DOM elements are destroyed and initialized again. (See video below). + + + +We can also use the Angular DevTool to profile our application and understand what is happening inside our application. I will show you how to do it inside the following video. + + + +:::note +If you don't know how to use it, read [the performance introduction page](/challenges/performance/) first and come back after. +::: + +If you need more information about `NgFor`, I invite you to read the [documentation](https://angular.dev/api/common/NgFor) first. + +## Statement + +The goal of this challenge is to understand what is causing this DOM refresh and to solve it. diff --git a/docs copy/src/content/docs/challenges/performance/37-optimize-big-list.md b/docs copy/src/content/docs/challenges/performance/37-optimize-big-list.md new file mode 100644 index 000000000..daeb5aec9 --- /dev/null +++ b/docs copy/src/content/docs/challenges/performance/37-optimize-big-list.md @@ -0,0 +1,39 @@ +--- +title: 🟠 Optimize Big List +description: Challenge 37 is about learning how virtualization optimize big list rendering +author: thomas-laforge +contributors: + - tomalaforge + - jdegand + - LMFinney +challengeNumber: 37 +command: performance-optimize-big-list +sidebar: + order: 117 +--- + +## Information + +In this application, we will render a list of 100,000 individuals by clicking on the **loadList** button. If you open the Chrome developer panel by pressing **F12**, go to the Elements tab, and expand the element to see the list, you will notice that all 100,000 elements are rendered in the DOM, even though we can only see about 20 elements in the viewport. This process takes a lot of time, which is why the application is very slow at displaying the list. + +We can use the Angular DevTool to profile our application and understand what is happening inside our application. I will show you how to do it inside the following video. + + + +:::note +If you don't know how to use it, read [the performance introduction page](/challenges/performance/) first and come back after. +::: + +## Statement + +The goal of this challenge is to implement a better alternative to display big list of items. + +## Hints: + +
+ Hint 1 + +If you're unsure where to begin, I recommend reading the [Angular CDK virtualization documentation](https://material.angular.io/cdk/scrolling/overview). + +
diff --git a/docs copy/src/content/docs/challenges/performance/40-web-worker.md b/docs copy/src/content/docs/challenges/performance/40-web-worker.md new file mode 100644 index 000000000..522e19d28 --- /dev/null +++ b/docs copy/src/content/docs/challenges/performance/40-web-worker.md @@ -0,0 +1,36 @@ +--- +title: 🟠 Web workers +description: Challenge 40 is about learning how to create and use a web worker +author: thomas-laforge +contributors: + - tomalaforge + - jdegand +challengeNumber: 40 +command: performance-web-workers +sidebar: + order: 119 +--- + +## Information + +This challenge has been created for [Angular Advent Calendar](https://angularchristmascalendar.com) 2023. + +This application is basic. We click on the **Discover** button to reveal the surprise hidden behind the black screen. However, the current application provides an awful user experience. When we click on the button, the page freezes, and after a while, it reveals the secret all at once without a smooth animation. + +> Note: To create the application freeze, the loader is based on a very heavy computation function. We could have used a basic timer, but that's not the point of this challenge. + +Since JavaScript is single-threaded, when we perform a heavy task, the browser cannot update the UI or respond to mouse clicks or any events. To free the main thread, the goal is to isolate the heavy computation into a different thread. To do so, we will need to use web workers. Web workers can run any scripts in the background, in isolation from the main thread, allowing the browser to still provide your user with a good experience. + +In Angular, this technology is often underused, however, it's straightforward to create one. There is a schematic that you can find [here](https://angular.dev/ecosystem/web-workers). + +## Statement + +The goal of this challenge is to create a smooth animation by isolating the heavy computation function into a web worker. + +First, create a web worker using a schematic, then move the issuing function. Finally, the animation should be smooth and the progress percentage should update, which will provide an awesome user experience. + +:::note +Since we are inside an Nx workspace, simply replace the `ng` command with `nx` when running the schematic. + +If `nx` is not installed globally on your machine, prefix your command with `npx`. +::: diff --git a/docs copy/src/content/docs/challenges/performance/index.mdx b/docs copy/src/content/docs/challenges/performance/index.mdx new file mode 100644 index 000000000..5a7bb0abe --- /dev/null +++ b/docs copy/src/content/docs/challenges/performance/index.mdx @@ -0,0 +1,71 @@ +--- +title: Angular Performance +prev: false +next: false +contributors: + - tomalaforge + - tomer953 + - LMFinney +description: Learn how to use the Angular Devtool chrome extension. +noCommentSection: true +sidebar: + order: 1 +--- + +import { LinkCard } from '@astrojs/starlight/components'; + +In this series of challenges about performance, you will learn how to optimize and enhance the performance of your Angular application. + +Before starting to resolve any challenge, I invite you to download the [Angular DevTools Chrome extension](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh) if you haven't already done so. + +This extension allows you to profile your application and detect performance issues, which is very useful for understanding where performance issues can occur. + +## How to use it + +When you serve an Angular application, you can inspect a page by pressing F12, which will open the Chrome developer tools. Then navigate to the Angular tab. From there, you can select the Profiler tab as shown below. + +![profiler tab](../../../../assets/performance/profiler-tab.png 'Profiler tab') + +You can now profile your application by clicking on the record button. You can play with your application and see when change detection is triggered and which components are rerendered. + +:::tip[Learn more] +You can learn more on the [documentation page](https://angular.io/guide/devtools). +::: + +Now that you know how to use the Angular DevTool, you can choose a challenge, profile it, and resolve it. + + + + + + + + + + + + diff --git a/docs copy/src/content/docs/challenges/rxjs/11-high-order-operator-bug.md b/docs copy/src/content/docs/challenges/rxjs/11-high-order-operator-bug.md new file mode 100644 index 000000000..dbc0b53d0 --- /dev/null +++ b/docs copy/src/content/docs/challenges/rxjs/11-high-order-operator-bug.md @@ -0,0 +1,32 @@ +--- +title: 🟠 High Order Operator Bug +description: Challenge 11 is about resolving a Rxjs bug because of high order operators +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 11 +command: rxjs-high-order-operator-bug +sidebar: + order: 114 +--- + +Let's dive inside the wonderful word of RxJS. + +This challenge is inspired by a real-life example. + +## Information + +### User Story + +We need a button for each `Topic`. When we click on it, we delete all objects with this `Topic` in our database _(Fake DB in our case)_. Finally, we display **All [topic] have been deleted** if everything was deleted successfully or **Error: deletion of some [topic] failed** if some deletions failed + +### Constraints + +We can only pass one object to our DB for deletion at the time. The DB will respond true if the data was successfully deleted and false otherwise. + +### Statement + +The QA team reports a **bug**. The UI shows **All [topic] have been deleted** all the time, even if some deletions fail. + +👉 Spot the bug and correct it. diff --git a/docs copy/src/content/docs/challenges/rxjs/14-race-condition.md b/docs copy/src/content/docs/challenges/rxjs/14-race-condition.md new file mode 100644 index 000000000..b4fbb8d95 --- /dev/null +++ b/docs copy/src/content/docs/challenges/rxjs/14-race-condition.md @@ -0,0 +1,30 @@ +--- +title: 🟢 Race Condition +description: Challenge 14 is about race condition in Rxjs +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 14 +command: rxjs-race-condition +sidebar: + order: 11 +--- + +## Information + +The goal of this application is to display a list of topics in a modal when a button is clicked. The application functions correctly. However, your tech lead has asked you to add tests and they are failing. + +## Statement + +Correct your application to pass the test + +## Constraints + +- I can see you coming 🤣 => You CANNOT change the test (the test is working fine) 😳 +- You CANNOT change the `fakeGetHttpTopic` method. A delay has been added to fake a slow network. + +## Run the test + +HEADLESS : `npx nx test rxjs-race-condition` +WATCH MODE : `npx nx test rxjs-race-condition --watch` diff --git a/docs copy/src/content/docs/challenges/rxjs/38-rxjs-catch-error.md b/docs copy/src/content/docs/challenges/rxjs/38-rxjs-catch-error.md new file mode 100644 index 000000000..5680d1544 --- /dev/null +++ b/docs copy/src/content/docs/challenges/rxjs/38-rxjs-catch-error.md @@ -0,0 +1,37 @@ +--- +title: 🟢 catchError +description: Challenge 38 is about learning observable completion. +author: devesh-chaudhari +command: rxjs-catch-error +contributors: + - DeveshChau + - tomalaforge + - LMFinney +challengeNumber: 38 +sidebar: + order: 14 +--- + +## Information + +### How to Use the Application + +Our application features a form with a text input box and a "Fetch" button. Upon clicking the "Fetch" button, data is retrieved from a [free API](https://jsonplaceholder.typicode.com/). + +The correct values for a successful response are limited to: posts, comments, albums, photos, todos, and users. Any other values will result in an error response. + +### Bug + +A bug has been identified in our application. Users are only able to successfully fetch data until an invalid request is sent. Once an error response is received, users are unable to send additional requests. + +### Learnings + +This application provides an opportunity to understand the correct placement of a [`catchError`](https://rxjs.dev/api/operators/catchError) operator. If placed incorrectly, the overall subscription will be completed, preventing users from sending more requests. The goal is to preserve the overall subscription by handling error notifications from inner observables appropriately. + +## Statement + +The goal is to use the catchError operator to handle error management inside your Rxjs stream. + +## Constraints + +Users should be able to log the value/error each time they click the "Fetch" button. diff --git a/docs copy/src/content/docs/challenges/rxjs/49-hold-to-save-button.md b/docs copy/src/content/docs/challenges/rxjs/49-hold-to-save-button.md new file mode 100644 index 000000000..050ccc48a --- /dev/null +++ b/docs copy/src/content/docs/challenges/rxjs/49-hold-to-save-button.md @@ -0,0 +1,46 @@ +--- +title: 🟠 Hold to save button +description: You're tasked with implementing Lucie's button design, requiring holding it for a set time to save, taking over from Sacha; functionalities include configuring duration, countdown initiation on "mousedown", progress bar reset on "mouseleave" or "mouseup", reflecting remaining time, and simulating save request on hold completion, using RxJS operators and ensuring declarative code. +author: timothy-alcaide +contributors: + - alcaidio + - LMFinney +challengeNumber: 49 +command: rxjs-hold-to-save-button +sidebar: + order: 19 +--- + +## Context + +As a member of the development team, you have to respond to a specific request from the UX designer, 👩🏻‍🎨 Lucie, who has designed a button that must be held down for X amount of time to save a save request. + +Sacha 👶🏼 the trainee has already integrated the design but doesn't know how to perform the "holdable" functionality. + +So you're going to take over from him. + +## Functional expectation + +> "As a user, I would like to save something by holding down the button for a certain amount of time." + +Here is the prototype made by Lucie: + +![prototype gif](../../../../assets/rxjs/49/prototype.gif) + +## Acceptance Criteria + +1. We should be able to configure a maintenance duration in milliseconds. +2. Pressing and holding the button triggers the countdown on the `mousedown` event. +3. On `mouseleave` or `mouseup` events, the progress bar is reset to 0. +4. The progress bar representing the remaining relative time should reflect the remaining time. +5. Simulates a backend request when the hold time is over (console log or alert). +6. You must maximize the use of RxJS operators and be as declarative as possible. + +
+ Tips 🤫 (if you really need it and after careful consideration) +
    +
  • Create the `HoldableDirective`
  • +
  • Use `TemplateRef` and `fromEvent` from RxJS to catch events or `@HostListener`
  • +
  • Perhaps the following RxJS operators can help you: interval, takeUntil, switchMap, takeWhile/retry...
  • +
+
diff --git a/docs copy/src/content/docs/challenges/signal/30-interop-rxjs-signal.md b/docs copy/src/content/docs/challenges/signal/30-interop-rxjs-signal.md new file mode 100644 index 000000000..08489c8f7 --- /dev/null +++ b/docs copy/src/content/docs/challenges/signal/30-interop-rxjs-signal.md @@ -0,0 +1,22 @@ +--- +title: 🔴 Interoperability Rxjs/Signal +description: Challenge 30 is about learning how to mix signal with Rxjs +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 +challengeNumber: 30 +command: signal-interop-rxjs-signal +sidebar: + order: 204 +--- + +## Information + +In this challenge, we have a small reactive application using **RxJS** and **NgRx/Component-Store**. + +The goal of this challenge is to use the new **Signal API** introduced in Angular v16. However, we should not convert everything. Certain portions of the code are better suited for RxJS rather than Signal. It is up to you to determine the threshold and observe how **Signal and RxJS coexist**, as well as how the interoperability is achieved in Angular. + +## Note + +- You can use any third party library if you want to like **ngrx/signal-store**, **tanstack-query** or **rxAngular**. diff --git a/docs copy/src/content/docs/challenges/signal/43-signal-input.md b/docs copy/src/content/docs/challenges/signal/43-signal-input.md new file mode 100644 index 000000000..0ab0498e5 --- /dev/null +++ b/docs copy/src/content/docs/challenges/signal/43-signal-input.md @@ -0,0 +1,55 @@ +--- +title: 🟢 Signal Input +description: Challenge 43 is about learning how to use signal inputs +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 43 +command: signal-signal-input +sidebar: + order: 16 +--- + +## Information + +Finally, the day has arrived when the Angular team introduces a reactive input. This highly requested feature has been awaited for many years. Version 17.1 introduces `SignalInput`. Instead of utilizing the well-known `@Input` decorator, you now have a function that returns a signal. + +```ts +// old way +@Input() age?: number; + +// new way +age = input() +``` + +If you want required inputs + +```ts +// old way +@Input({required: true}) age!: number; + +// new way +age = input.required() +``` + +If you wanted to obtain a signal from an input, you had to go through a setter to configure your signal from the input. + +```ts +// old way +age = signal(0) +@Input({alias: 'age'}) set _age(age: number){ + this.age.set(age) +}; + +// new way +age = input() +``` + +You can read more about signal inputs [here](https://angular.dev/guide/signals/inputs). + +## Statement + +In this small application, the goal is to refactor the `UserComponent` to utilize `SignalInput`. + +- You have required and optional inputs. +- You can use the `transform` function for the `age` input to directly convert the property to a number. diff --git a/docs copy/src/content/docs/challenges/signal/50-bug-effect-signal.md b/docs copy/src/content/docs/challenges/signal/50-bug-effect-signal.md new file mode 100644 index 000000000..46f07c6bd --- /dev/null +++ b/docs copy/src/content/docs/challenges/signal/50-bug-effect-signal.md @@ -0,0 +1,40 @@ +--- +title: 🟢 Bug in Effect +description: Challenge 50 is about understanding why an effect is not triggered. +author: thomas-laforge +contributors: + - tomalaforge + - svenson95 + - LMFinney +challengeNumber: 50 +command: signal-bug-in-effect +sidebar: + order: 19 +--- + +## Information + +In this basic exercise, we aim to display an alert whenever at least one checkbox is checked. You are in the process of buying a MacBook, which can be upgraded with some extras, like more drive space, more RAM or a better GPU. + +Bildschirmfoto 2024-05-09 um 08 57 57 + +## Statement + +The actual implementation doesn't work as expected, and your task is to fix a bug that your team discovered. An alert should be shown if at least one of the three checkboxes is checked (independent of any other checkboxes). But if the first one is checked, checking one or both of the other two checkboxes does not cause the alert to display. Why does this happen? + +The objective of this challenge is to understand the issue and fix the problem that prevents the alert from appearing when the second checkbox is clicked. + +## Acceptance Criteria + +To ensure this feature works properly, try this out to reproduce the bug after solving the challenge, to check if the bug is gone. + +- Check box 1 (Alert should be shown) +- Check box 2 (Alert should be shown) +- Uncheck box 1 +- Check box 3 (Alert should be shown) +- Uncheck box 2 +- Uncheck box 3 + +## Bonus Challenge + +- Try to implement this feature with a `computed` signal. diff --git a/docs copy/src/content/docs/challenges/signal/51-function-call-effect.md b/docs copy/src/content/docs/challenges/signal/51-function-call-effect.md new file mode 100644 index 000000000..e2a94694c --- /dev/null +++ b/docs copy/src/content/docs/challenges/signal/51-function-call-effect.md @@ -0,0 +1,25 @@ +--- +title: 🟢 Function call in effect +description: Challenge 51 is about understanding why an effect is triggered too often. +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 51 +command: signal-function-call-effect +sidebar: + order: 20 +--- + +## Information + +In this second challenge focusing on Signal effects, we've introduced an input select that allows users to choose an action. Whenever an action is selected, it is logged in the console. The application also permits changes to the selected user. + +## Problem Statement + +Ideally, the system should log an action only when one is specifically selected. However, we currently face an issue where changing the user also triggers a log entry, even though we do not explicitly monitor user changes. + +The objective of this challenge is to identify and resolve the cause of these extra triggers. We aim to ensure that logging only occurs when an action is selected. + +## Constraints + +- You cannot modify the `UserService` file. diff --git a/docs copy/src/content/docs/challenges/signal/53-big-signal-performance.md b/docs copy/src/content/docs/challenges/signal/53-big-signal-performance.md new file mode 100644 index 000000000..d3b4ea4a2 --- /dev/null +++ b/docs copy/src/content/docs/challenges/signal/53-big-signal-performance.md @@ -0,0 +1,24 @@ +--- +title: 🟠 Big Signal Performance +description: Challenge 53 is about performance while using big signal object +author: thomas-laforge +contributors: + - tomalaforge + - jdegand +challengeNumber: 53 +command: signal-big-signal-performance +sidebar: + order: 122 +--- + +## Information + +For this challenge, you can imagine a large-scale application where you use a service to save and retrieve your user state at any time within the application. + +The problem is that updating a single user property updates the entire application. + +I added the `CDFlashingDirective` to visualize when one component is rendering. + +## Statement + +With signals, you can now be more fine-grained in what the UI is rendering. The goal of this challenge is to understand why everything is re-rendering and to refactor the application to be more performant. diff --git a/docs copy/src/content/docs/challenges/signal/54-pipe-observable-to-signal.md b/docs copy/src/content/docs/challenges/signal/54-pipe-observable-to-signal.md new file mode 100644 index 000000000..2b88b528f --- /dev/null +++ b/docs copy/src/content/docs/challenges/signal/54-pipe-observable-to-signal.md @@ -0,0 +1,22 @@ +--- +title: 🔴 Pipe Observable to Signal +description: Challenge 54 is about refactoring an application using observable to signals +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 54 +command: signal-pipe-observable-to-signal +sidebar: + order: 210 +--- + +## Information + +We have a legacy application that is using observables to store a state. Signals are a very good fit for that. + +## Statement + +So, the goal of this challenge is to refactor the following application to be a fully signal-based application. When you are done, neither the pipe nor the service should import RxJS. + +Be careful along the way; everything might not work as you wish. diff --git a/docs copy/src/content/docs/challenges/signal/56-forms-and-signal.md b/docs copy/src/content/docs/challenges/signal/56-forms-and-signal.md new file mode 100644 index 000000000..077fd822f --- /dev/null +++ b/docs copy/src/content/docs/challenges/signal/56-forms-and-signal.md @@ -0,0 +1,27 @@ +--- +title: 🔴 forms and signal +description: Challenge 56 is about working with reactive forms and signals +author: thomas-laforge +contributors: + - tomalaforge +challengeNumber: 56 +command: signal-forms-and-signal +sidebar: + order: 211 +--- + +## Information + +We are working within a large e-commerce codebase that utilizes a substantial number of forms. The team predominantly uses reactive forms, and since the release of signals, we have been integrating them extensively. + +The current feature in development is a multi-step form process. The steps include: selecting a product, choosing the quantity, and finally proceeding to the checkout step to complete the billing details. However, an issue has been identified: when a user navigates back from the checkout step to the quantity step, the previously selected quantity is not retained. This needs to be fixed. + +## Challenge Statement + +The objective of this challenge is to make sure that the selected quantity is preserved when navigating back from the checkout step to the quantity step. + +## Constraints + +The solution must use reactive forms and signals. + +Additionally, as an optional side challenge, you may refactor the code to use template-driven forms. diff --git a/docs copy/src/content/docs/challenges/testing/17-router.md b/docs copy/src/content/docs/challenges/testing/17-router.md new file mode 100644 index 000000000..2af0c8d77 --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/17-router.md @@ -0,0 +1,28 @@ +--- +title: 🟠 Router +description: Challenge 17 is about testing the router +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 17 +command: testing-router +sidebar: + order: 108 +--- + +## Information + +We have a functional application that lists available books for borrowing inside a library. If the book you searched for is available, you will be directed to the corresponding book(s), otherwise, you will end up on an error page. + +The file named `app.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-router-outlet`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks. + +For testing with Cypress, you will execute your test inside the `app.component.cy.ts` and run `npx nx component-test testing-router-outlet` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode. + +# Statement + +The goal is to test multiple behaviors of the application described in each test file using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview). + +:::note +I have created some `it` blocks but feel free to add more tests if you want. +::: diff --git a/docs copy/src/content/docs/challenges/testing/18-nested-components.md b/docs copy/src/content/docs/challenges/testing/18-nested-components.md new file mode 100644 index 000000000..d7ba391c2 --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/18-nested-components.md @@ -0,0 +1,32 @@ +--- +title: 🟠 Nested Components +description: Challenge 18 is about testing nested components +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 18 +command: testing-nested-components +sidebar: + order: 109 +--- + +## Information + +We have a small application that sends a title to a fake backend when the user types the value into an input. +If the title is correctly typed, you can send the request; otherwise you receive an error, and the request is not sent. +The application is created with nested components. `ChildComponent` is the container that includes four components: `ResultComponent`, `ButtonComponent`, `InputComponent` and `ErrorComponent`. However, since we are testing our component as a black box, the architecture of our components doesn't change anything. You can create your test, change how the components are structured, and your tests should still pass. That's the goal of integration tests. Never test internal implementation details!!!. + +You can play with it by running : `npx nx serve testing-nested`. + +The file named `child.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-nested`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks. + +For testing with Cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-nested` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode. + +# Statement + +The goal is to test multiple behaviors of the application describe inside each test files using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview). + +:::note +I have created some `it` blocks but feel free to add more tests if you want. +::: diff --git a/docs copy/src/content/docs/challenges/testing/19-input-output.md b/docs copy/src/content/docs/challenges/testing/19-input-output.md new file mode 100644 index 000000000..d77db7eb0 --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/19-input-output.md @@ -0,0 +1,33 @@ +--- +title: 🟠 Input Output +description: Challenge 19 is about testing inputs and ouputs +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - jdegand + - LMFinney +challengeNumber: 19 +command: testing-input-output +sidebar: + order: 110 +--- + +## Information + +We have a small counter application that increments or decrements a number. The `CounterComponent` takes an initial value as an `@Input` and emits the result of the counter as an `@Output` when we click on the **Send** button. Since we are testing our component as a black box, we only have access to our inputs and listen to the output values. We should not rely on any internal implementation details!!! + +You can play with it by running : `npx nx serve testing-input-output`. + +The file named `counter.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-input-output`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks. + +For testing with Cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-input-output` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode. + +# Statement + +The goal is to test multiple behaviors of the application described inside each test file using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview). + +:::note +I have created some `it` blocks but feel free to add more tests if you want. +::: diff --git a/docs copy/src/content/docs/challenges/testing/20-modal.md b/docs copy/src/content/docs/challenges/testing/20-modal.md new file mode 100644 index 000000000..8a1d34c8b --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/20-modal.md @@ -0,0 +1,37 @@ +--- +title: 🟠 Modal +description: Challenge 20 is about testing modals +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - jdegand + - LMFinney +challengeNumber: 20 +command: testing-modal +sidebar: + order: 111 +--- + +## Information + +In this small application, you have an input prompting you to enter a name, and a **Confirm** button to submit your form. +If you enter a name, a confirmation modal will appear; otherwise an error modal will be displayed. +In the confirmation modal, if you click the **Confirm** button, a message confirming the submission of the form will appear. If the user clicks on **Cancel**, an error message will be displayed. + +The goal of this challenge is to test the dialogs inside your application. To do so, we will test the full application like an end-to-end test will do. This means, we will test the `AppComponent` as a black box and react to events on the page. No internal details should be tested. The difference between an e2e test and integration test is that we will mock all API calls. _(All http requests are faked inside this application, but this would not be the case in a real enterprise application.)_ + +You can play with it by running : `npx nx serve testing-modal`. + +The file named `app.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-modal`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks. + +For testing with Cypress, you will execute your test inside `app.component.cy.ts` and run `npx nx component-test testing-modal` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode. + +# Statement + +The goal is to test multiple behaviors of the application described inside each test file using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview). + +:::note +I have created some `it` blocks but feel free to add more tests if you want. +::: diff --git a/docs copy/src/content/docs/challenges/testing/23-harness.md b/docs copy/src/content/docs/challenges/testing/23-harness.md new file mode 100644 index 000000000..629ffdf5d --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/23-harness.md @@ -0,0 +1,30 @@ +--- +title: 🟢 Harness +description: Challenge 23 is about testing with component harnesses +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - jdegand + - LMFinney +challengeNumber: 23 +command: testing-harness +sidebar: + order: 9 +--- + +## Information + +A component harness is a class that lets a test interact with a component via a supported API. + +The objective of this challenge is to have a better understanding of the CDK test harness API. In this initial challenge, we will only use Angular Material's built-in harnesses. + +Documentation for CDK Component Harness is [here](https://material.angular.io/cdk/test-harnesses/overview#api-for-test-authors). +Documentation for Angular Material component is [here](https://material.angular.io/components/button/overview). + +## Statement + +Test the functionality of `child.component.ts`, which consists of some inputs & checkboxes related to a `mat-slider`. Implement the prepared test suite, but feel free to include additional tests as well. + +**Note:** You are welcome to use [Angular Testing Library](https://testing-library.com/) if you wish. diff --git a/docs copy/src/content/docs/challenges/testing/24-harness-creation.md b/docs copy/src/content/docs/challenges/testing/24-harness-creation.md new file mode 100644 index 000000000..d60456b01 --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/24-harness-creation.md @@ -0,0 +1,48 @@ +--- +title: 🟠 Harness Creation +description: Challenge 24 is about creating a component harness. +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - jdegand +challengeNumber: 24 +command: testing-harness-creation +sidebar: + order: 112 +--- + +## Information + +The goal of this challenge is to create a test harness for `slider.component.ts`. The harness file, `slider.harness.ts`, has already been created. + +The following API needs to be implemented: + +```ts + async clickPlus(): Promise ; + + async clickMinus(): Promise; + + async getValue(): Promise ; + + async getMinValue(): Promise; + + async disabled(): Promise; + + async setValue(value: number): Promise; +``` + +Additionally, you should create a `HarnessPredicate` with the default predicate and the `minValue` property. + +```ts + static with( + this: ComponentHarnessConstructor, + options: SliderHarnessFilters = {} + ): HarnessPredicate; +``` + +Lastly, you will need to create the test suite for `app.component`. Some default tests have already been written, but feel free to add as many tests as you want and create as many harness methods as you need. + +> Angular Material documentation can be found [here](https://material.angular.io/cdk/test-harnesses/overview). + +Good luck !!! 💪 diff --git a/docs copy/src/content/docs/challenges/testing/28-checkbox.md b/docs copy/src/content/docs/challenges/testing/28-checkbox.md new file mode 100644 index 000000000..15b66eb73 --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/28-checkbox.md @@ -0,0 +1,30 @@ +--- +title: 🟢 Checkbox +description: Challenge 28 is about testing a simple checkbox +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - jdegand + - LMFinney +challengeNumber: 28 +command: testing-checkbox +sidebar: + order: 10 +--- + +## Information + +This application is very simple. It consists of a checkbox that enables or disables a button. The primary goal of this application is to become familiar with the debug API of [Angular Testing Library](https://testing-library.com/). Knowing how to debug your tests is a crucial tool you need to have in your toolkit. + +You can find the documentation about debugging in Angular Testing Library [here](https://testing-library.com/docs/dom-testing-library/api-debugging#screenlogtestingplaygroundurl). + +The main functions to remember are as follows: + +- `logRoles(myDOMElement)`: prints out all ARIA roles within the tree of the given DOM element. ARIA roles are the primary selectors you should reach for in the first place. +- `screen.debug()` or `screen.debug(myDOMElement)`: prints the DOM inside the console. +- `screen.logTestingPlaygroundURL()` or `screen.logTestingPlaygroundURL(myDOMElement)`: this function is very powerful. It will create a playground to expose all elements, and you can interact with it to see the selectors you should choose for a DOM element. + +## Statement + +The goal of this challenge is not to submit an answer, but you can if you want. It's more about using the debugging API to play around. These tools will be of great help for the upcoming testing challenges. diff --git a/docs copy/src/content/docs/challenges/testing/29-real-life-application.md b/docs copy/src/content/docs/challenges/testing/29-real-life-application.md new file mode 100644 index 000000000..1546bf9e7 --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/29-real-life-application.md @@ -0,0 +1,38 @@ +--- +title: 🔴 Real-life Application +description: Challenge 29 is about testing a real-life application +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - LMFinney +challengeNumber: 29 +command: testing-real-life-application +sidebar: + order: 205 +--- + +## Information + +This application presents a greater challenge because it closely resembles a real-life application that you might encounter in your day-to-day activities as an Angular developer. What makes it more difficult is the need to handle asynchronous tasks and create appropriate mocks. + +The application is a typical todo list application. You can filter tickets, create new ones, assign each ticket, close others, and navigate to the details of each ticket. + +In this challenge, you will write tests for the `ListComponent`, which represents the global view, and the `RowComponent`, which represents a specific ticket. Additionally, you will need to write unit tests for the `TicketStoreService` using [Angular Testing Library](https://testing-library.com/) . _This library allows you to test services effectively._ + +Handling asynchronous tasks will be particularly challenging. It's important not to introduce any explicit waits in your tests, as this would introduce unnecessary delays. Instead, it's better to look for an element that needs to appear or disappear from the DOM. In this case, the test will naturally wait for the correct period of time, as the waits are already implemented within both libraries. Take advantage of these built-in functionalities to create efficient and reliable tests. + +You can play with it by running : `npx nx serve testing-todos-list`. + +To run [Angular Testing Library](https://testing-library.com/) test suites, you need to run `npx nx test testing-todos-list`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks. + +For testing with Cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-todos-list` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode. + +# Statement + +The goal is to test multiple behaviors of the application describe inside each test files using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview). + +:::note +I have created some `it` blocks but feel free to add more tests if you want. +::: diff --git a/docs copy/src/content/docs/challenges/testing/index.mdx b/docs copy/src/content/docs/challenges/testing/index.mdx new file mode 100644 index 000000000..0231ad2ed --- /dev/null +++ b/docs copy/src/content/docs/challenges/testing/index.mdx @@ -0,0 +1,74 @@ +--- +title: Testing +prev: false +next: false +contributors: + - tomalaforge + - LMFinney +description: Introduction to testing challenges. +noCommentSection: true +sidebar: + order: 1 +--- + +import { LinkCard } from '@astrojs/starlight/components'; + +Testing is a crucial step in building scalable, maintainable, and trustworthy applications. +Testing should never be avoided, even in the face of short deadlines or strong pressure from the product team. +Nowadays, there are numerous awesome tools available that make it easy to test your code and provide a great developer experience. + +In this series of testing exercises, we will learn and master [Angular Testing Library](https://testing-library.com/docs/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/angular/overview) that simplifies DOM manipulation for testing any Angular component. + +The benefits of using Angular Testing Library or Cypress Component Testing are to test your component as a black box. You will only interact with what the user can do on the UI. However, the difference with end-to-end tests is that the backend is mocked, which makes the tests faster and more maintainable. +The goal is to mock as little as possible to test your component at a higher level than unit testing, which will make refactoring easier. +Within a real application, integration tests are the tests you will write the most. Learning how to write them will make your application more robust and more maintainable. + +Here is a series of 8 challenges that you can take in any order. + + + + + + + + + + + + + + + + diff --git a/docs copy/src/content/docs/challenges/typescript/15-function-overload.md b/docs copy/src/content/docs/challenges/typescript/15-function-overload.md new file mode 100644 index 000000000..44d289a77 --- /dev/null +++ b/docs copy/src/content/docs/challenges/typescript/15-function-overload.md @@ -0,0 +1,27 @@ +--- +title: 🟠 Function Overload +description: Challenge 15 is about creating overload functions +author: thomas-laforge +contributors: + - tomalaforge + - LMFinney +challengeNumber: 15 +command: typescript-function-overload +blogLink: https://medium.com/ngconf/function-overloading-in-typescript-8236706b2c05 +sidebar: + order: 115 +--- + +## Information + +Angular uses TypeScript, and mastering TypeScript can help you avoid runtime errors by catching them at compile time. + +In this challenge, we have a function to create a vehicle. However, each vehicle type requires different mandatory properties. +Currently, we are getting an error at runtime if one property is missing, and we don't get the return Type, which is not ideal. +One solution would be to create a separate function for each vehicle type, but for this challenge, I want to use the same function and have TypeScript automatically complete the properties depending on the type passed as the first parameter. + +To achieve this, we will use overload functions. + +## Statement + +- Use function overload diff --git a/docs copy/src/content/docs/challenges/typescript/47-enums-vs-union-types.md b/docs copy/src/content/docs/challenges/typescript/47-enums-vs-union-types.md new file mode 100644 index 000000000..6ae54a72e --- /dev/null +++ b/docs copy/src/content/docs/challenges/typescript/47-enums-vs-union-types.md @@ -0,0 +1,80 @@ +--- +title: 🟢 Enums vs Union Types +description: Challenge 47 is about the comparison between enums and union types +author: sven-brodny +contributors: + - svenson95 + - jdegand + - LMFinney +challengeNumber: 47 +command: typescript-enums-vs-union-types +sidebar: + order: 18 +--- + +## Information + +[Enums](https://www.typescriptlang.org/docs/handbook/enums.html) allow developers to define a set of named constants that represent a specific type. TypeScript provides both numeric and string-based enums. + +```typescript +enum Difficulty { + EASY = 'EASY', + NORMAL = 'NORMAL', +} +``` + +On the other hand, [Union Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) are simpler than enums, as they don't require any additional runtime or compilation overhead. + +```typescript +type Difficulty = 'EASY' | 'NORMAL'; +``` + +### Reasons to use Union Types + +Enums are a concept borrowed from languages like C# and Java. TypeScript enums are compiled into JavaScript objects with keys for both the names and values of the enum members. This results in larger output files and additional memory consumption, which can be particularly problematic in performance-critical applications. + +Enums have some more pitfalls as well: + +- Non-const enums do not fit the concept of "a typed superset of JavaScript." They violate the concept by emitting global JavaScript objects that live in runtime with a syntax that is not compatible with JavaScript (JavaScript uses dynamic typing rather than static typing; enums are a form of static typing). Since JavaScript has no compilation step, there is little or no value in having static typing. +- Const enums, in contrast, cannot be transpiled with Babel. But there are workarounds for this issue, e.g., using the `babel-plugin-const-enum` plugin. The TypeScript documentation about [const enums](https://www.typescriptlang.org/docs/handbook/enums.html#const-enums) says "_Do not use const enums at all_". +- To use enums, you have to import them. If you want to use enum values in a template, you'll need to declare a variable in your component too. +- Numeric enums are not type safe ... + +```typescript +enum Difficulty { + EASY = 0, + NORMAL = 1, +} +const hard: Difficulty = 2; // no error +``` + +### Reasons to use Enums + +Enums are the best option for code maintainability. It is easy to find all usages of a value in a project and enforce constraints. If you stick to assigning strings to the enum keys all the time, you can avoid a lot of issues. + +It's true that enums produce larger output files, but that's not always a real problem. As long as the enum does its job without any problems, it shouldn't be something you care that much about. + +Another good thing is that the necessary enum prefixes add meaning to otherwise meaningless values, so they can improve readability. For example, `HttpStatus.Forbidden` gives more information than `Forbidden`. + +### Mapped types + +A [mapped type](https://learntypescript.dev/08/l2-mapped-type) is the process of creating a new type by mapping type information from an existing type. + +```typescript +type Difficulty = { [K in 'EASY' | 'NORMAL']: string }; +``` + +### Conclusion + +Enums are not redundant, but in most cases, union types are preferred. Unless you care a lot about maintainability, enums may fit better. Here are some more interesting articles discussing this subject: + +- [Should You Use Enums or Union Types in Typescript?](https://www.bam.tech/article/should-you-use-enums-or-union-types-in-typescript) +- [Typescript has unions, so are enums redundant?](https://stackoverflow.com/questions/40275832/typescript-has-unions-so-are-enums-redundant) +- [Tidy TypeScript: Prefer union types over enums](https://fettblog.eu/tidy-typescript-avoid-enums/) + +## Statement + +The goal of this challenge is to refactor the enums `Difficulty` and `Direction`. + +- Refactor the `Difficulty` enum to **union type**. +- Refactor the `Direction` enum to **mapped type**. diff --git a/docs copy/src/content/docs/es/challenges/angular/1-projection.md b/docs copy/src/content/docs/es/challenges/angular/1-projection.md new file mode 100644 index 000000000..0b9d5cc17 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/1-projection.md @@ -0,0 +1,42 @@ +--- +title: 🟢 Proyección +description: Desafio 1 trata sobre aprender a proyectar elementos del DOM a través de componentes, +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 1 +command: angular-projection +blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5 +videoLinks: + - link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq + alt: Projection video by Arthur Lannelucq + flag: FR + - link: https://www.youtube.com/watch?v=yNrfvu7vTa4 + alt: Projection video by Amos Lucian Isaila + flag: ES +sidebar: + order: 1 +--- + +## Información + +En Angular, la proyección de contenido es una técnica poderosa para crear componentes altamente personalizables. Utilizar y comprender los conceptos de ng-content y ngTemplateOutlet puede mejorar significativamente su capacidad para crear componentes reutilizables. + +Puedes aprender todo sobre ng-content [aquí](https://angular.dev/guide/components/content-projection) desde la proyección simple hasta las más complejas. + +Para aprender sobre ngTemplateOutlet, puedes encontrar la documentación de la API [aquí](https://angular.dev/api/common/NgTemplateOutlet) junto con algunos ejemplos básicos. + +Con estas dos herramientas en la mano, ahora estás listo para asumir el desafío. + +## Declaración + +Comenzarás con una aplicación completamente funcional que incluye un tablero con una tarjeta de profesor y una tarjeta de estudiante. El objetivo es implementar la tarjeta de la ciudad. + +Aunque la aplicación funciona, la experiencia del desarrollador está lejos de ser óptima. Cada vez que necesitas implementar una nueva tarjeta, tienes que modificar el `card.component.ts`. En proyectos reales, este componente puede ser compartido entre muchas aplicaciones. El objetivo del desafío es crear un `CardComponent` que se pueda personalizar sin ninguna modificación. Una vez que hayas creado este componente, puedes comenzar a implementar el `CityCardComponent` y asegurarte de que no estás tocando el `CardComponent`. + +## Restricciones + +- Debes refactorizar el `CardComponent` and `ListItemComponent`. +- La directiva NgFor debe ser declarada y permanecer dentro del `CardComponent`. Puedes sentirte tentado a moverla al `ParentCardComponent` como `TeacherCardComponent`. +- CardComponent no debe contener ningún `NgIf` o `NgSwitch`. +- CSS: intenta evitar usar `::ng-deep`. Encuentra una mejor manera de manejar los estilos de CSS. diff --git a/docs copy/src/content/docs/es/challenges/angular/10-utility-wrapper-pipe.md b/docs copy/src/content/docs/es/challenges/angular/10-utility-wrapper-pipe.md new file mode 100644 index 000000000..1afacbdcc --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/10-utility-wrapper-pipe.md @@ -0,0 +1,23 @@ +--- +title: 🔴 Pipe Wrapper para utilidades +description: El desafío 10 trata sobre la creación de un pipe para envolver utilidades +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 10 +command: angular-utility-wrapper-pipe +sidebar: + order: 202 +--- + +El objetivo de esta serie de 3 desafíos de pipes es dominar **pipe** en Angular. + +Los pipes puros son una forma muy útil de transformar datos desde tu plantilla. La diferencia entre llamar a una función y un pipe es que los pipes puros son memorizados. Así que no serán recalculados en cada ciclo de detección de cambios si sus entradas no han cambiado. + +## Información: + +En este tercer ejercicio, quieres acceder a funciones de utilidades. Actualmente no puedes acceder a ellas directamente desde tu plantilla. El objetivo es crear un pipe específico para este archivo de utilidades donde necesitarás pasar el nombre de la función que quieres llamar y los argumentos necesarios. + +## Restricciones: + +- El tipo debe ser fuertemente definido. diff --git a/docs copy/src/content/docs/es/challenges/angular/13-highly-customizable-css.md b/docs copy/src/content/docs/es/challenges/angular/13-highly-customizable-css.md new file mode 100644 index 000000000..a3aaa71c2 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/13-highly-customizable-css.md @@ -0,0 +1,21 @@ +--- +title: 🟠 Estilos CSS Altamente Personalizables +description: El desafío 13 trata sobre la creación de estilos CSS altamente personalizables +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 13 +command: angular-highly-customizable-css +sidebar: + order: 104 +--- + +## Información + +El estilo es un aspecto importante del trabajo diario de un desarrollador de frontend, pero a menudo se subestima. En las aplicaciones de Angular, frecuentemente veo a personas usando `@Input()` para personalizar el estilo de sus componentes. Sin embargo, `@Input()` solo debe usarse para lógica. Otras técnicas, como las **variables CSS** y **host-context** deben usarse para el estilo. + +En este desafío, necesitarás usar tanto variables CSS como `:host-context` para eliminar todos los `@Input()` de tu código. + +## Restricciones: + +- En tu presentación final, tu componente no debe contener ninguna línea de código. Todo el estilo debe manejarse dentro del decorador _(o archivos CSS externos si lo prefieres)_ diff --git a/docs copy/src/content/docs/es/challenges/angular/16-master-dependency-injection.md b/docs copy/src/content/docs/es/challenges/angular/16-master-dependency-injection.md new file mode 100644 index 000000000..8822f6f28 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/16-master-dependency-injection.md @@ -0,0 +1,28 @@ +--- +title: 🔴 Dominar la Inyección de Dependencias +description: El desafío 16 trata sobre dominar y entender como funciona la inyección de dependencias +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 16 +command: angular-master-dependency-injection +sidebar: + order: 203 +--- + +## Información + +Para completar exitosamente este desafío, necesitarás tener un buen entendimiento de cómo funciona la Inyección de [Dependencias dentro](https://angular.dev/guide/di/dependency-injection) de Angular. + +El objetivo es proporcionar en la tabla el `CurrencyService` a nivel de fila, para que cada fila muestre la moneda correcta. Actualmente, el `CurrencyService` solo se proporciona a nivel de tabla, lo que resulta en un error ya que se muestra la misma moneda en cada fila, a pesar de que cada producto tiene una moneda diferente. + +Una forma de lograr esto es agregando un segundo argumento al pipe, pero esto no está permitido para este desafío. + +## Declaración + +- Tu tarea es mostrar la moneda correcta para cada fila. + +## Restricciones + +- No puedes modificar el pipe. +- No puedes envolver la fila dentro de un componente, ya que esto rompería el diseño. diff --git a/docs copy/src/content/docs/es/challenges/angular/21-anchor-navigation.md b/docs copy/src/content/docs/es/challenges/angular/21-anchor-navigation.md new file mode 100644 index 000000000..2a20954e8 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/21-anchor-navigation.md @@ -0,0 +1,20 @@ +--- +title: 🟢 Navegación con Anclas +description: El desafío 21 trata sobre la navegación dentro de la página con anclas +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 21 +command: angular-anchor-navigation +sidebar: + order: 4 +--- + +## Información + +Comienzas con una aplicación que tiene navegación básica y navegación con anclas en el `HomeComponent`. Sin embargo, usar `href` recrea la ruta cada vez y recarga la página. + +## Declaración + +- Tu tarea es refactorizar esta aplicación para usar la herramienta de navegación integrada para que se ajuste mejor dentro del Marco de Angular. Puedes explorar el enrutador (comúnmente conocido como router), pero es mejor permanecer dentro de la plantilla y usar la directiva `RouterLink`. +- Para mejorar la experiencia del usuario, añade desplazamiento suave. diff --git a/docs copy/src/content/docs/es/challenges/angular/22-router-input.md b/docs copy/src/content/docs/es/challenges/angular/22-router-input.md new file mode 100644 index 000000000..854461e98 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/22-router-input.md @@ -0,0 +1,28 @@ +--- +title: 🟢 @RouterInput() +description: El desafío 22 trata sobre el uso del decorador @Input para utilizar parámetros del router. +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 22 +command: angular-router-input +blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617 +sidebar: + order: 5 +--- + +## Información + +En esta aplicación, tomaremos tres pedazos de información dentro de nuestro `TestComponent` proporcionadas por el router: + +- Queremos obtener el `testId` que tenemos como parte de los parámetros de la URL. +- Queremos obtener `user` ubicado dentro de los parámetros de consulta (query params) de la URL. +- Queremos acceder a `permission` establecido dentro del objeto `data` de la ruta. + +En las versiones 15 o anteriores de Angular, usamos `ActivatedRoute` para obtener toda esta información y recibirla a través de observables para escuchar los cambios de URL. + +En la versión 16, Angular introdujo un nuevo `Input` que puede 'escuchar' los datos de la ruta. Puedes leer más al respecto [aquí](https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617). + +## Declaración + +El objetivo de este ejercicio es refactorizar el código para usar la nueva estrategia `RouterInput`. diff --git a/docs copy/src/content/docs/es/challenges/angular/3-directive-enhancement.md b/docs copy/src/content/docs/es/challenges/angular/3-directive-enhancement.md new file mode 100644 index 000000000..71bd239e2 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/3-directive-enhancement.md @@ -0,0 +1,54 @@ +--- +title: 🟠 Mejorar Directiva +description: El desafío 3 se trata de una directive incorporada. +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 3 +command: angular-directive-enhancement +blogLink: https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c +sidebar: + order: 101 +--- + +:::note[Nota] + +Este desafío puede parecer obsoleto ahora que disponemos del nuevo control de flujo y el bloque vacío dentro de los bloques `@for`. Sin embargo, las **directivas estructuradas** no serán borradas en ningún momento, de esta manera usted tendrá la oportunidad de aprender bastante de este desafío. + +::: + +## Información + +Las Directivas en Angular Framework son una herramienta muy poderosa. Usted puede aplicar los principios de DRY para aplicar una lógica compartida dentro de una directiva y aplicarla a cualquier componente. + +Pero el verdadero poder esta en mejorar una directiva ya existente que además **no te pertenece**. + +## Declaración + +En este desafío, queremos mostrar una lista de personas. Si la lista esta vacía, usted deberá mostrar _" the list is empty !! "_. (La lista esta vacía) + +:::note[Nota] + +En caso que hayan test automáticos para validar este desafío, se ha preferido dejar la frase en ingles, en vez de utilizar una traducción directa al español. + +::: + +```typescript + +
+ {{ person.name }} +
+
+ The list is empty !! +``` + +Queremos desechar el uso de ng-container al escribir: + +```typescript +
+ {{ person.name }} +
+ The list is empty !! +``` + +La meta de este desafío es **mejorar la directiva ngFor** diff --git a/docs copy/src/content/docs/es/challenges/angular/31-module-to-standalone.md b/docs copy/src/content/docs/es/challenges/angular/31-module-to-standalone.md new file mode 100644 index 000000000..307fc64b3 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/31-module-to-standalone.md @@ -0,0 +1,29 @@ +--- +title: 🟢 De Módulo a Standalone (Independiente) +description: El desafío 31 trata sobre migrar una aplicación basada en módulos a una aplicación independiente. +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 31 +command: angular-module-to-standalone +sidebar: + order: 6 +--- + +## Información + +En la versión 14 de Angular, se lanzaron los componentes standalone (o independientes, los cuales por traducción en español se hacen más fáciles de entender) y se estabilizaron en la versión 15. Si no has experimentado con ellos, nunca es tarde. Puedes probarlos en este desafío. + +Además, el objetivo es ver cómo **Nx** y los **componentes independientes** trabajan juntos, y experimentar el proceso de desacoplar tu aplicación con la librería en Nx y componentes independientes. + +Finalmente, los componentes independientes son muy simples de entender, pero los **componentes cargados con el método diferido routing/lazy-loaded** pueden ser un poco más difíciles de comprender. Este desafío te permitirá manipular componentes en diferentes niveles de anidación y trabajar con rutas de carga diferida. + +Después de completar este desafío, los componentes independientes no tendrán más secretos para ti. + +## Declaración + +El objetivo de este desafío es migrar tu aplicación de componentes basados en módulos a componentes independientes. + +## Nota + +También puedes probar el [esquema de Angular](https://angular.dev/reference/migrations/standalone) para migrar NgModule a componentes independientes. _(Dado que estamos usando nx, comienza tu comando con nx en lugar de ng)_ diff --git a/docs copy/src/content/docs/es/challenges/angular/32-change-detection-bug.md b/docs copy/src/content/docs/es/challenges/angular/32-change-detection-bug.md new file mode 100644 index 000000000..f1dee1443 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/32-change-detection-bug.md @@ -0,0 +1,39 @@ +--- +title: 🟠 Bug de Detección de Cambios +description: El desafío 32 trata sobre depurar una aplicación que tiene problemas cuando se activa la detección de cambios +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 32 +command: angular-change-detection-bug +blogLink: https://medium.com/ngconf/function-calls-inside-template-are-dangerous-15f9822a6629 +sidebar: + order: 105 +--- + +:::note +Este desafío está inspirado en un ejemplo de la vida real que hemos simplificado para crear este interesante desafío. +::: + +## Información + +En esta pequeña aplicación, tenemos un menú de navegación para dirigir nuestra aplicación ya sea al `BarComponent` o al `FooComponent`. Sin embargo, nuestra aplicación no se está cargando y no se muestran errores en la consola. + +## Declaración + +El objetivo del desafío es depurar esta aplicación y hacer que funcione. + +## Pistas + +
+ Pista 1 + + Si comentas `routerLinkActive="isSelected"` dentro de `NavigationComponent`, la aplicación se carga correctamente. +
+ +
+ Pista 2 + +Si abres el [código fuente de `RouterLinkActive`](https://github.com/angular/angular/blob/main/packages/router/src/directives/router_link_active.ts) y vas a la **línea 196**, Angular está llamando a `this.cdr.markForCheck` dentro de una microTarea, lo que desencadena un nuevo ciclo de Detección de Cambios. Si comentas esta línea, la aplicación se carga de nuevo, sin embargo, el bug no está dentro del Framework de Angular. 😅😯 + +
diff --git a/docs copy/src/content/docs/es/challenges/angular/33-decoupling-components.md b/docs copy/src/content/docs/es/challenges/angular/33-decoupling-components.md new file mode 100644 index 000000000..1af6a2d1a --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/33-decoupling-components.md @@ -0,0 +1,33 @@ +--- +title: 🟠 Desacoplando Componentes +description: El desafío 33 trata sobre desacoplar dos componentes fuertemente unidos utilizando Token de Inyección +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 33 +command: angular-decoupling-components +sidebar: + order: 106 +--- + +> Muchas gracias a **Robin Goetz** y su [Proyecto Spartan](https://github.com/goetzrobin/spartan). +> Este desafío fue propuesto por Robin y está fuertemente inspirado en su proyecto. + +## Información + +El objetivo de este desafío es separar el comportamiento de un componente a traves de su estilo. Para el propósito de este desafío, trabajaremos en un elemento botón. Al hacer clic en él, alternaremos una propiedad llamada _disabled_ para que cambie el estilo del elemento. Esto es bastante inútil en la vida real, pero el desafío tiene como objetivo demostrar un concepto útil. + +El comportamiento del componente (referido como el _cerebro_ en el stack de Spartan) se encuentra en la biblioteca del cerebro, la cual es llamada _"brain"_. La parte de estilo (referida como el casco y llamado como _helmet_) está dentro de la biblioteca _helmet_. Ambas bibliotecas no pueden depender una de la otra porque queremos poder publicarlas por separado. Para ayudarnos a abordar el problema, estamos utilizando la regla eslint de Nx. Puedes encontrar más detalles [aquí](https://nx.dev/core-features/enforce-module-boundaries). + +Sin embargo, el _helmet_ del botón necesita acceder al estado del componente para estilizar el botón de manera diferente según su estado. Como se mencionó anteriormente, no podemos importar la `BtnDisabledDirective` directamente en la biblioteca _helmet_ como se hace actualmente. Si vas a [`BtnHelmetDirective`](../../libs/decoupling/helmet/src/lib/btn-style.directive.ts), te encontrarás con un error de linting. **Un proyecto etiquetado con `type:hlm` solo puede depender de libs etiquetadas con `type:core`**. + +## Declaración + +El objetivo de este desafío es encontrar una forma de desacoplar ambas Directivas. + +### Pista + +
+ Pista 1 + Lee cuidadosamente el título del desafío 😇 +
diff --git a/docs copy/src/content/docs/es/challenges/angular/39-injection-token.md b/docs copy/src/content/docs/es/challenges/angular/39-injection-token.md new file mode 100644 index 000000000..03422d342 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/39-injection-token.md @@ -0,0 +1,36 @@ +--- +title: 🟠 InjectionToken +description: Desafio de Angular 39 para aprender sobre el poder del InjectionToken +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 39 +command: angular-injection-token +videoLinks: + - link: https://www.youtube.com/watch?v=ntggdQycFyc + alt: Injection Token by Arthur Lannelucq + flag: FR +sidebar: + order: 118 +--- + +## Información + +En esta pequeña aplicación, comenzamos con un `VideoComponent` que contiene un timer de **1 segundo**. El equipo de desarrollo decidió usar una constante global para almacenar el valor del temporizador: `DEFAULT_TIMER`. Sin embargo, unas semanas más tarde, el equipo de producto quiere agregar una nueva pantalla para llamadas telefónicas llamada `PhoneComponent`, y queremos reutilizar el `TimerComponent`. Sin embargo, el equipo de producto quiere un temporizador de **2 segundos**. ¿Cómo podemos lograr esto? + +## Enunciado + +Actualmente, el temporizador sigue siendo de 1 segundo para el `PhoneComponent`. El objetivo de este desafío es cambiar el valor del temporizador a 2 segundos para el `PhoneComponent`. + +## Restricciones + +Se prohíbe el uso de `@Input`. Este ejemplo es básico, y el uso de `@Input` podría ser una buena opción, pero en aplicaciones más complejas, el componente que necesitamos actualizar puede estar profundamente anidado, lo que hace que el uso de `@Input` sea un diseño realmente malo. + +## Pista + +
+ Pista 1 + +Mirar este [blog post](https://itnext.io/stop-being-scared-of-injectiontokens-ab22f72f0fe9) puede ser de gran ayuda. + +
diff --git a/docs copy/src/content/docs/es/challenges/angular/4-typed-context-outlet.md b/docs copy/src/content/docs/es/challenges/angular/4-typed-context-outlet.md new file mode 100644 index 000000000..7cd7e957a --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/4-typed-context-outlet.md @@ -0,0 +1,48 @@ +--- +title: 🔴 ContextOutlet en forma de tipo +description: El desafío 4 se trata de tipificar de manera fuerte las directivas de ngContextOutlet +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 4 +command: angular-typed-context-outlet +blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6 +sidebar: + order: 201 +--- + +## Información + +:::note[Nota] + +Las declaraciones de tipos permanecerán en ingles, asi como los nombres de los objetos y sus miembros. + +::: + +Angular ofrece la function estática [`ngTemplateContextGuard`](https://angular.dev/guide/directives/structural-directives#improving-template-type-checking-for-custom-directives) para reforzar el tipo de una directiva estructural. + +Sin embargo, el contexto de **NgTemplateOutlet** es de tipo **Object**. Con la ayuda de la guardia mencionada anteriormente, podemos mejorar ese comportamiento. + +## Declaración + +En este desafío, queremos aprender como reforzar el tipo de nuestro ng-template en AppComponent. + +Este desafío ofrece dos niveles de complejidad: + +### Nivel 1: una Interfase conocida + +A continuación tenemos estas lineas de código: + +![Any en Person](../../../../../assets/4/unknown-person.png) + +Como se puede observar, "name" es de tipo "any". La meta es inferir el tipo correcto. + +### Nivel 2: una Interfase genérica + +Actualmente, tenemos estas lineas de código: + +![Any en Student](../../../../../assets/4/unknown-student.png) + +Como puede apreciarse, "student" es de tipo "any". Queremos inferir el tipo de manera correcta. + +Pero en esta parte, podemos pasar a ListComponent, una lista de **cualquier cosa**. Aun asi, queremos inferir de manera correcta el tipo de dato. diff --git a/docs copy/src/content/docs/es/challenges/angular/5-crud-application.md b/docs copy/src/content/docs/es/challenges/angular/5-crud-application.md new file mode 100644 index 000000000..803a33d6f --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/5-crud-application.md @@ -0,0 +1,52 @@ +--- +title: 🟢 Aplicación CRUD +description: El desafío 5 se trata de refactorizar una aplicación CRUD. +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 5 +command: angular-crud-application +sidebar: + order: 2 +--- + +## Información + +Comunicar y tener acceso a un estado global o local en sincronización con tu backend es el corazón de cualquier aplicación. Usted necesita dominar las siguientes mejores practicas para construir aplicaciones en Angular de manera solida y confiable. + +## Declaración + +En este desafió tenemos una pequeña aplicación CRUD, la cual puede obtener una lista de COSAS POR HACER, actualizar y borrar algunos de los elementos de dicha lista. + +Actualmente tenemos un ejemplo funcional, pero repleto de practicas erróneas. + +### Paso 1: Refactorizar con mejores practicas. + +Usted necesitara: + +- Evite el uso del tipo **any**. Use interfaces para prevenir los errores de tipo en Typescript. +- Use un **servicio separado** para todas las llamadas de http, y use **Signals** para la lista de cosas por hacer. +- No **mutar** los datos + +```typescript +// Evite esto +this.todos[todoUpdated.id - 1] = todoUpdated; + +// en vez de ello, use algo como esto, pero necesitara mejorar la lógica de manera que preserve el mismo orden. +this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]; +``` + +### Step 2: Mejorar + +- Agregue un botón para **borrar** : _Documentación de la API falsa_ +- Opera de manera correcta los **errores**. _(Globalmente)_ +- Agrega un indicador global de **carga**. _Puedes utilizar MatProgressSpinnerModule_ + +### Step 3: Mantenibilidad!! adiciona algunos tests + +- Adiciona 2/3 tests + +### Step 4: Creatividad!!! Domina tu estado. + +- Usa de manera apropiada **un component store de ngrx**, **ngrx/store**, **rxAngular**, **tanstack-query** o **ngrx/signal-store** como estado local de tu componente. +- Tener un indicador de Carga/Error **localizado**. Por ejemplo: Solo en el elemento seleccionado de la lista siendo procesado y **desactivar** todos los botones de dicho elemento. _(Pista: Necesitaras crear un ItemComponent)_ diff --git a/docs copy/src/content/docs/es/challenges/angular/6-structural-directive.md b/docs copy/src/content/docs/es/challenges/angular/6-structural-directive.md new file mode 100644 index 000000000..c81967383 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/6-structural-directive.md @@ -0,0 +1,63 @@ +--- +title: 🟠 Directiva Estructural +description: El Desafío 6 se trata de generar una Directiva Estructural que manipule los permisos +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 6 +command: angular-structural-directive +blogLink: https://medium.com/@thomas.laforge/create-a-custom-structural-directive-to-manage-permissions-like-a-pro-11a1acad30ad +sidebar: + order: 102 +--- + +## Información + +Las Directivas Estructurales son in concepto importante que necesitaras dominar para mejorar tus habilidades y conocimientos en Angular. Esta es la primera parte del desafío. + +En Angular, "Guard" es un concepto muy importante por que siempre las vas a necesitar en cada aplicación que construyas. + +## Declaración + +En LoginComponent, encontraras 6 botones correspondientes a 6 tipos de roles de usuario: + +:::note[Nota] + +Se dejaran los nombres de los roles en ingles. + +::: + +- Admin (Administrador) +- Manager (Gerente) +- Reader (Lector) +- Writer (Escritor) +- Reader and Writer (Lector y escritor) +- Client (Cliente) +- Everyone (Todos) + +## Paso 1 + +En `InformationComponent`, necesitaras mostrar la pieza de información correcta por cada rol usando una directiva estructural. + +### Restricciones: + +- No puedes usar `ngIf` o `@if` dentro de `InformationComponent`. +- No puedes importar un store dentro de `InformationComponent`. + +You should end up with something like below: + +```html +
Información del Role1
+``` + +```html +
Información del Role1 y Role2
+``` + +```html +
Información solo para el Super Administrador
+``` + +## Paso 2 + +En `Routes.ts`, deberás usar la guardia `CanMatch` para dirigir a todos los usuarios al correcto `DashboardComponent`. diff --git a/docs copy/src/content/docs/es/challenges/angular/8-pure-pipe.md b/docs copy/src/content/docs/es/challenges/angular/8-pure-pipe.md new file mode 100644 index 000000000..814783e3f --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/8-pure-pipe.md @@ -0,0 +1,25 @@ +--- +title: 🟢 Pipe Puro +description: El desafío 8 trata sobre la creación de un pipe puro +author: thomas-laforge +contributors: + - ErickRodrCodes + - kabrunko - dev +challengeNumber: 8 +command: angular-pure-pipe +blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d +sidebar: + order: 3 +--- + +El objetivo de esta serie de 3 desafíos de pipes es dominar **pipe** en Angular. + +Los pipes puros son una forma muy útil de transformar datos desde tu plantilla. La diferencia entre llamar a una función y un pipe es que los pipes puros son memorizados. Así que no serán recalculados en cada ciclo de detección de cambios si sus entradas no han cambiado. + +## Información + +En este primer ejercicio, llamas a una función simple dentro de tu plantilla. El objetivo es convertirla en un pipe. + +## Restricciones + +- El tipo debe ser fuertemente definido. diff --git a/docs copy/src/content/docs/es/challenges/angular/9-wrap-function-pipe.md b/docs copy/src/content/docs/es/challenges/angular/9-wrap-function-pipe.md new file mode 100644 index 000000000..11b652f94 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/angular/9-wrap-function-pipe.md @@ -0,0 +1,25 @@ +--- +title: 🟠 Pipe Wrapper para funciones +description: El desafío 9 trata sobre la creación de un tubo para envolver funciones de componentes +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 9 +command: angular-wrap-function-pipe +blogLink: https://medium.com/ngconf/boost-your-apps-performance-by-wrapping-your-functions-inside-a-pipe-7e889a901d1d +sidebar: + order: 103 +--- + +El objetivo de esta serie de 3 desafíos de pipes es dominar **pipe** en Angular. + +Los pipes puros son una forma muy útil de transformar datos desde tu plantilla. La diferencia entre llamar a una función y un pipe es que los pipes puros son memorizados. Así que no serán recalculados en cada ciclo de detección de cambios si sus entradas no han cambiado. + +## Información: + +En este segundo ejercicio, estás llamando a múltiples funciones dentro de tu plantilla. Puedes crear un pipe específico para cada una de las funciones, pero esto sería demasiado engorroso. +El objetivo es crear un pipe `wrapFn` para envolver tu función de retorno a través de un pipe. Tu función DEBE permanecer dentro de tu componente. **`WrapFn` debe ser altamente reutilizable.** + +## Restricciones: + +- El tipo debe ser fuertemente definido. diff --git a/docs copy/src/content/docs/es/challenges/performance/12-optimize-change-detection.md b/docs copy/src/content/docs/es/challenges/performance/12-optimize-change-detection.md new file mode 100644 index 000000000..7990d893a --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/performance/12-optimize-change-detection.md @@ -0,0 +1,40 @@ +--- +title: 🟠 Optimizar el Change Detection al desplazarse +description: Desafío 12 sobre la optimización del número de ciclos de detección de cambios al desplazarse +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 12 +command: performance-optimize-change-detection +sidebar: + order: 107 +--- + +## Información + +En Angular, hay una biblioteca llamada Zone.js que realiza mucha magia para simplificar la vida del desarrollador. Zone.js parchea todos los eventos del DOM para que vuelva a verificar y volver a renderizar la vista cuando algo ha cambiado dentro de la aplicación. El desarrollador no tiene que activar manualmente la detección de cambios. + +Sin embargo, a veces Zone.js activa mucha más detección de cambios de la necesaria. Por ejemplo, cuando se está escuchando un evento de desplazamiento, cada evento de desplazamiento generará un nuevo ciclo de detección de cambios. + +En este desafío, solo necesitamos actualizar la vista en una posición de desplazamiento específica para mostrar u ocultar un botón. Todos los demás ciclos son innecesarios. + +Para tener una mejor visualización del problema, perfila tu aplicación con Angular Dev Tools. + +:::note +Si no sabes cómo usarlo, lee [la página de introducción al rendimiento](/es/challenges/performance/) primero y vuelve después. +::: + +Puedes obtener más detalles sobre la contaminación de la zona y cómo resolverla [aquí](https://angular.dev/best-practices/zone-pollution). + +El siguiente video explicará más a fondo el problema de esta aplicación. + + + +## Enunciado + +Tu objetivo para este desafío es evitar todos los ciclos de detección de cambios innecesarios y activar una detección de cambios solo cuando sea necesario. + +## Restricción: + +No puedes optar por no usar Zone.js globalmente. Si este código forma parte de un proyecto grande y optas por no usar Zone.js, sin duda romperás tu aplicación. diff --git a/docs copy/src/content/docs/es/challenges/performance/34-default-vs-onpush.md b/docs copy/src/content/docs/es/challenges/performance/34-default-vs-onpush.md new file mode 100644 index 000000000..d96367299 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/performance/34-default-vs-onpush.md @@ -0,0 +1,57 @@ +--- +title: 🟢 Default vs OnPush +description: El desafío 34 trata sobre aprender la diferencia entre las estrategias de detección de cambios Default y OnPush. +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 34 +command: performance-default-vs-onpush +sidebar: + order: 7 +--- + +## Información + +En este desafío, exploraremos las diferencias e impactos de usar `ChangeDetectionStrategy.Default` versus `ChangeDetectionStrategy.OnPush`. + +Puedes leer la [documentación de Angular](https://angular.dev/best-practices/skipping-subtrees) para aprender más sobre las diferencias entre estas estrategias. + +En este desafío, todos los componentes comienzan con la estrategia `Default`. Cuando escribas letras dentro del campo de entrada, notarás que todos los componentes se resaltan en naranja. + +:::note[Nota] +Agregué resaltado de color a cada componente y cada fila para proporcionar una mejor visualización de cuándo se vuelve a renderizar un componente. +::: + +Como puedes ver, cada letra desencadena un nuevo ciclo de detección de cambios, y todos los componentes se vuelven a renderizar, lo que causa problemas de rendimiento. + +Utilicemos la Angular DevTool para perfilar nuestra aplicación y comprender cómo esta herramienta puede ayudarnos a entender qué está sucediendo dentro de nuestra aplicación. + +:::note[Nota] +Si no sabes cómo usarlo, lee primero [la página de introducción al rendimiento](/es/challenges/performance/) y vuelve después. +::: + +Ahora, comienza a perfilar tu aplicación y escribe algunas letras dentro del campo de entrada para desencadenar algunos ciclos de detección de cambios. + +Si haces clic en una de las barras (indicada por la flecha amarilla en la imagen a continuación), puedes ver que `PersonListComponent`, `RandomComponent` y todos los `MatListItem` se ven afectados por el ciclo de detección de cambios, incluso cuando solo interactuamos con el campo de entrada. + +![profiler record](../../../../../assets/performance/34/profiler-record.png 'Registro del Profiler') + +## Enunciado + +El objetivo de este desafío es mejorar el agrupamiento de la detección de cambios dentro de la aplicación utilizando la estrategia de detección de cambios `OnPush`, pero no solo eso... + +## Pistas: + +
+ Pista 1 + +Utiliza `ChangeDetectionStrategy.OnPush`, pero esto no será suficiente. + +
+ +
+ Pista 2 + +Crea componentes más pequeños para separar mejor el campo de entrada de la lista. + +
diff --git a/docs copy/src/content/docs/es/challenges/performance/35-memoization.md b/docs copy/src/content/docs/es/challenges/performance/35-memoization.md new file mode 100644 index 000000000..89a657f5f --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/performance/35-memoization.md @@ -0,0 +1,52 @@ +--- +title: 🟢 Memoización +description: El desafío 35 trata sobre cómo funcionan las tuberías puras +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 35 +command: performance-memoization +sidebar: + order: 8 +--- + +
Desafío #35
+ +## Información + +En Angular, los pure pipes son muy poderosas porque el valor se memoiza, lo que significa que si el valor de entrada no cambia, la función `transform` del pipe no se vuelve a calcular y se emite el valor en caché. + +Puedes aprender más sobre pipes en la [documentación de Angular](https://angular.dev/guide/pipes) y en este [artículo de inmersión profunda](https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d). + +En este desafío, comenzamos con un botón para cargar una lista de personas. Cada persona está asociada con un número y utilizaremos el cálculo de Fibonacci para crear una computación pesada que ralentizará la aplicación. + +Una vez que se carga la lista, intenta escribir algunas letras dentro del campo de entrada. Te darás cuenta de que la aplicación es muy lenta, a pesar de que solo estás realizando una escritura muy básica. + +:::note[Nota] +No nos centraremos en la carga inicial de la lista en este desafío. +::: + +Utilicemos la Angular DevTool para perfilar nuestra aplicación y comprender cómo esta herramienta puede ayudarnos a entender qué está sucediendo dentro de nuestra aplicación. + +:::note[Nota] +Si no sabes cómo usarlo, lee primero [la página de introducción al rendimiento](/es/challenges/performance/) y vuelve después. +::: + +Ahora, comienza a perfilar tu aplicación y escribe algunas letras dentro del campo de entrada. Verás que aparecen algunas barras rojas en el panel del perfilador. + +Si haces clic en una de las barras (indicada por la flecha amarilla en la imagen a continuación), verás que el ciclo de detección de cambios está tardando más de 3 segundos en `PersonListComponent`. + +![profiler record](../../../../../assets/performance/35/memoize-profiler.png 'Registro del perfilador') + +## Enunciado + +El objetivo de este desafío es comprender qué está causando esta latencia y mejorarla. + +## Pistas: + +
+ Pista 1 + +Utiliza `Pipes` para memoizar el cálculo de Fibonacci. + +
diff --git a/docs copy/src/content/docs/es/challenges/performance/36-ngfor-optimization.md b/docs copy/src/content/docs/es/challenges/performance/36-ngfor-optimization.md new file mode 100644 index 000000000..ae7ae7911 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/performance/36-ngfor-optimization.md @@ -0,0 +1,33 @@ +--- +title: 🟢 Optimización de NgFor +description: El Desafío 36 trata sobre como funciona trackby +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 36 +command: performance-ngfor-optimization +sidebar: + order: 13 +--- + +## Información + +En esta aplicación, tenemos una lista de individuos que podemos agregar, eliminar o actualizar. Si abres el panel de desarrollador de Chrome presionando **F12**, ve a la pestaña source y expande el elemento para ver la lista, notarás que cada vez que agregas, eliminas o actualizas un elemento de la lista, se destruyen y vuelven a inicializar todos los elementos del DOM. (Ver video a continuación). + + + +También podemos usar la Angular DevTool para perfilar nuestra aplicación y entender qué está sucediendo dentro de ella. Te mostraré cómo hacerlo en el siguiente video. + + + +:::note +Si no sabes cómo usarlo, lee primero [la página de introducción al rendimiento](/es/challenges/performance/) y vuelve después. +::: + +Si necesitas más información sobre `NgFor`, te invito a leer primero la [documentación](https://angular.dev/api/common/NgFor). + +## Enunciado + +El objetivo de este desafío es entender qué está causando esta actualización del DOM y solucionarlo. diff --git a/docs copy/src/content/docs/es/challenges/performance/37-optimize-big-list.md b/docs copy/src/content/docs/es/challenges/performance/37-optimize-big-list.md new file mode 100644 index 000000000..e1ac099d4 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/performance/37-optimize-big-list.md @@ -0,0 +1,34 @@ +--- +title: 🟠 Optimizando una lista larga +description: El desafio 37 trata sobre como optimizar una lista grande de elementos +author: thomas-laforge +contributors: + - nelsongutidev +challengeNumber: 37 +command: performance-optimize-big-list +sidebar: + order: 117 +--- + +## Información + +En esta aplicación, renderizaremos una lista de 100,000 individuos al hacer clic en el botón loadList. Si abres el panel de desarrollo de Chrome presionando F12, ve al ícono de Fuente y expande el elemento para ver la lista, notarás que los 100,000 elementos se renderizan en el DOM, aunque solo podemos ver alrededor de 20 elementos en el área visible. Este proceso lleva mucho tiempo, por lo que la aplicación es muy lenta al mostrar la lista. + +Podemos utilizar la Herramienta de Desarrollo de Angular para perfilar nuestra aplicación y entender lo que está sucediendo en su interior. Te mostraré cómo hacerlo en el siguiente video. + + +:::[nota] +Si no sabes cómo usarlo, lee la página de introducción al rendimiento primero y regresa después. +::: + +Enunciado +El objetivo de este desafío es implementar una alternativa mejor para mostrar una lista grande de elementos. + +Pistas: + +
+ Pista 1 +Si no estás seguro por dónde empezar, te recomiendo leer la documentación de virtualización de Angular CDK. + +
diff --git a/docs copy/src/content/docs/es/challenges/performance/index.mdx b/docs copy/src/content/docs/es/challenges/performance/index.mdx new file mode 100644 index 000000000..b5a690310 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/performance/index.mdx @@ -0,0 +1,51 @@ +--- +title: Rendimiento en Angular +prev: false +next: false +contributors: + - nelsongutidev +description: Aprende a usar la extensión de Chrome Angular Devtools. +noCommentSection: true +sidebar: + order: 1 +--- + +import { LinkCard } from '@astrojs/starlight/components'; + +En esta serie de desafíos sobre rendimiento, aprenderás cómo optimizar y mejorar el rendimiento de tu aplicación Angular. + +Antes de comenzar a resolver cualquier desafío, te invito a descargar la [extensión de Chrome Angular DevTools](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh) si aún no lo has hecho. + +Esta extensión te permite perfilar tu aplicación y detectar problemas de rendimiento, lo cual es muy útil para entender dónde pueden ocurrir problemas de rendimiento. + +## Cómo usarlo + +Cuando sirves una aplicación Angular, puedes inspeccionar una página presionando F12, lo cual abrirá las herramientas de desarrollo de Chrome. Luego navega a la pestaña Angular. Desde allí, puedes seleccionar la pestaña Profiler como se muestra a continuación. + +![profiler tab](../../../../../assets/performance/profiler-tab.png 'Profiler tab') + +Ahora puedes perfilar tu aplicación haciendo clic en el botón de grabación. Puedes interactuar con tu aplicación y ver cuándo se activa la detección de cambios y qué componentes se vuelven a renderizar. + +:::tip[Aprende más] +Puedes obtener más información en la [página de documentación](https://angular.io/guide/devtools). +::: + +Ahora que sabes cómo usar la Angular DevTool, puedes elegir un desafío, perfilarlo y resolverlo. + + + + + + diff --git a/docs copy/src/content/docs/es/challenges/signal/30-interop-rxjs-signal.md b/docs copy/src/content/docs/es/challenges/signal/30-interop-rxjs-signal.md new file mode 100644 index 000000000..0f6f85315 --- /dev/null +++ b/docs copy/src/content/docs/es/challenges/signal/30-interop-rxjs-signal.md @@ -0,0 +1,21 @@ +--- +title: 🔴 Interoperatividad Rxjs/Signal (Señales) +description: El desafío 30 trata sobre aprender a mezclar señales con Rxjs +author: thomas-laforge +contributors: + - ErickRodrCodes +challengeNumber: 30 +command: signal-interop-rxjs-signal +sidebar: + order: 204 +--- + +## Información + +En este desafío, tenemos una pequeña aplicación reactiva utilizando **RxJS** y **NgRx/Component-Store**. + +El objetivo de este desafío es usar la nueva **API de Señales** introducida en Angular v16. Sin embargo, no debemos convertir todo. Ciertas partes del código son más adecuadas para RxJS que para Señales. Dependerá de ti determinar el umbral y observar cómo **Señal y RxJS coexisten**, así como cómo se logra la interoperatividad en Angular. + +## Nota + +- Puedes usar cualquier biblioteca de terceros si lo deseas, como **ngrx/signal-store**, **tanstack-query** o **rxAngular**. diff --git a/docs copy/src/content/docs/es/guides/checkout-answer.md b/docs copy/src/content/docs/es/guides/checkout-answer.md new file mode 100644 index 000000000..1d5962b70 --- /dev/null +++ b/docs copy/src/content/docs/es/guides/checkout-answer.md @@ -0,0 +1,38 @@ +--- +title: Revisar la Respuesta de Alguien +description: Guía para revisar la respuesta de otra persona. +contributors: + - nelsongutidev +sidebar: + order: 3 +--- + +Todas las respuestas a los Desafíos de Angular se presentarán en forma de Pull Request (PR). Para verlas y seguirlas, navega a través de la página **Files Changes** en GitHub. Sin embargo, entender y seguir este proceso puede no ser sencillo si no estás familiarizado con la interfaz. En muchos casos, puedes preferir revisar la rama y revisar la solución en tu IDE preferido. + +Esta guía ha sido creada para ayudarte a lograr esto. + +## Revisar localmente una PR de otra persona + +### Sincroniza tu repositorio + +Primero necesitas sincronizar tu fork para asegurarte de que está al día con el repositorio del que hiciste fork. + +Esto se puede lograr haciendo clic en el botón **Sync fork** en la página principal de tu fork. + +![Sync project header](../../../../assets/fork-sync.png) + +La imagen de arriba muestra que mi rama está atrasada respecto a la rama principal por 8 commits, y necesito sincronizarla para estar al día. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Revisar localmente + +Navega a la PR que deseas revisar localmente y obtén su ID. La encontrarás en el título de la PR (como se muestra a continuación). + +![PR header](../../../../assets/PR-header.png) + +A continuación, ve a cualquier terminal dentro de tu directorio de proyecto y ejecuta el siguiente comando: + +```bash +gh pr checkout +``` diff --git a/docs copy/src/content/docs/es/guides/contribute.md b/docs copy/src/content/docs/es/guides/contribute.md new file mode 100644 index 000000000..9b3a8684c --- /dev/null +++ b/docs copy/src/content/docs/es/guides/contribute.md @@ -0,0 +1,22 @@ +--- +title: Contribuye +description: Guía para contribuir al proyecto +contributors: + - nelsongutidev +sidebar: + order: 4 +--- + +Puedes contribuir a este repositorio de muchas maneras: + +🔥 Crea un nuevo desafío siguiendo las instrucciones [aquí](/guides/create-challenge). + +🔥 Resuelve desafíos y envía los resultados. (guía [aquí](/guides/resolve-challenge)). + +🔥 Comenta las soluciones de otros proporcionando retroalimentación constructiva y afectuosa. + +🔥 Corrige errores tipográficos o de inglés dentro de la documentación. + +🔥 Envía un issue para sugerir nuevas ideas de desafíos o reportar un error. + +🔥 Patrocina el proyecto [aquí](https://github.com/sponsors/tomalaforge) diff --git a/docs copy/src/content/docs/es/guides/create-challenge.md b/docs copy/src/content/docs/es/guides/create-challenge.md new file mode 100644 index 000000000..e44afbb45 --- /dev/null +++ b/docs copy/src/content/docs/es/guides/create-challenge.md @@ -0,0 +1,62 @@ +--- +title: Crea tu propio desafío +description: Guía para crear un desafío +contributors: + - nelsongutidev +sidebar: + order: 5 +--- + +Tienes una idea que quieres compartir, un error interesante con el que estás luchando en uno de tus proyectos privados o secundarios, o un tip de Angular que descubriste. Todas estas posibilidades son un buen punto de partida para crear un desafío y compartir la solución con los demás. + +Pero, ¿cómo empiezas a crear estos desafíos? + +## Configuración de Plantillas (Boilerplate) + +Para agilizar el proceso, he creado un generador Nx que configurará todo el boilerplate por ti y te preparará más rápido. La forma más sencilla de ejecutarlo es utilizando la consola Nx: ve a Nx Console > generate > @angular-challenges/cli - challenge + +### Parámetros + +#### parámetros obligatorios + +- title: El título que quieres darle a tu desafío. + :::note[Nota] + El título debe tener un máximo de 25 caracteres. + ::: + +- challengeDifficulty: La dificultad que crees que tiene tu desafío. Hay tres niveles de dificultad: 🟢 fácil / 🟠 medio / 🔴 difícil + +- name: nombre de la aplicación Nx. + :::note[Nota] + Debe escribirse en **kebab-case** + ::: + +- docRepository: La categoría de tu Desafío: Nx, Angular, Angular Performance, Rxjs, NgRx, Typescript. + +#### parámetros opcionales + +- directory: Si quieres que tu aplicación se encuentre en una carpeta específica dentro de `apps`. + +- addTest: Si quieres agregar configuración de pruebas. + +### Qué se crea + +- El generador creará todos los archivos necesarios para tener una nueva aplicación de trabajo. Todos estos archivos se crearán dentro de `apps/${directory}/${name}` + +- Se creará un archivo Markdown con la configuración mínima dentro de `docs/src/content/docs/challenges/${docRepository}` + +## Creación del Desafío + +Lo único que queda por hacer es crear tu desafío. 🚀 + +:::danger[Importante] + +No olvides actualizar la documentación para presentar tu desafío y proporcionar tus instrucciones. + +::: + +¡Es tu turno de actuar! 💪 + +## Envío de la Solución + +Después de una semana más o menos, no olvides proporcionar tu solución a tu desafío. diff --git a/docs copy/src/content/docs/es/guides/faq.md b/docs copy/src/content/docs/es/guides/faq.md new file mode 100644 index 000000000..da1e95f18 --- /dev/null +++ b/docs copy/src/content/docs/es/guides/faq.md @@ -0,0 +1,19 @@ +--- +title: Preguntas Frecuentes +description: Preguntas frecuentes sobre el proyecto +contributors: + - nelsongutidev +sidebar: + order: 7 +--- + +
+ ¿Por qué mi aplicación no se está iniciando o por qué encuentro errores en mi terminal cuando ejecuto `nx serve`? + + La mayoría de las veces, este problema surge porque sus node_modules están desactualizados y necesita actualizarlos ejecutando `npm ci`. + +Si el proceso de instalación falla, puede resolverlo eliminando su carpeta node_modules usando el comando `rm -rf node_modules` o `npx npkill` y luego volviendo a ejecutar `npm ci`. + +Si el problema persiste, informe el problema [aquí](https://github.com/tomalaforge/angular-challenges/issues/new). + +
diff --git a/docs copy/src/content/docs/es/guides/getting-started.md b/docs copy/src/content/docs/es/guides/getting-started.md new file mode 100644 index 000000000..f533f94fd --- /dev/null +++ b/docs copy/src/content/docs/es/guides/getting-started.md @@ -0,0 +1,60 @@ +--- +title: Inicio +description: Una guía para comenzar con los Desafíos de Angular +contributors: + - nelsongutidev + - 1fbr +sidebar: + order: 1 +--- + +Para comenzar con Desafíos de Angular, siga estos pasos: + +## Crea una cuenta de GitHub + +Si desea enviar una solución, deberá tener su propia cuenta de GitHub. Además, tener una cuenta de GitHub siempre es beneficioso y es gratis. + +## Crea un fork del proyecto de GitHub + +Navegue al [Repositorio de Desafíos de Angular](https://github.com/tomalaforge/angular-challenges) y haga clic en el Fork button in the header. This will create a copy of this repository on your own GitHub page. + +## Clone el repositorio en su máquina local + +Seleccione un directorio en su computadora local y clone este repositorio. + +Abra una terminal, navegue hasta el directorio elegido y escriba el siguiente comando: + +```bash +git clone https://github.com/[YOUR_GITHUB_NAME]/angular-challenges.git +``` + +:::note +Puede encontrar la URL de clonación haciendo clic en el botón <> Code en su propia instancia del repositorio de Desafíos de Angular. + +![Header of GitHub workspace](../../../../assets/header-github.png) + +::: + +## Abra el proyecto en su IDE favorito + +Abra el proyecto en cualquier IDE de su elección. + +## Instale todas las dependencias + +```bash +npm ci +``` + +## Escoja un desafío + +Su proyecto ahora está corriendo. El único paso restante es elegir un desafío 🚀 + +Cada desafío consta de: + +- Nombre: indicando de qué se trata el desafío. +- Número: orden de creación. El número no tiene ningún significado en particular, pero ayuda para hacer referencia en la sección de Pull Request de GitHub. +- Badge: ayuda a visualizar el grado de dificultad. Es totalmente subjetivo 😅 + - 🟢 fácil + - 🟠 medio + - 🔴 difícil diff --git a/docs copy/src/content/docs/es/guides/rebase.md b/docs copy/src/content/docs/es/guides/rebase.md new file mode 100644 index 000000000..8f60580f0 --- /dev/null +++ b/docs copy/src/content/docs/es/guides/rebase.md @@ -0,0 +1,57 @@ +--- +title: Hacer rebase a tu rama +description: Guía para hacer rebase a tu rama +contributors: + - nelsongutidev +sidebar: + order: 6 +--- + +En ocasiones, pueden agregarse cambios al proyecto. Intentaré hacer cambios que no rompan nada, pero a veces es inevitable. + +La mayoría de las veces, no necesitarás hacer rebase a tu solución, pero aquí hay una guía para ayudarte a saber cómo hacerlo en caso de ser necesario. + +:::note[Nota] +Esta guía es aplicable a cualquier Proyecto de Código Abierto. +::: + +## Pasos para hacer rebase a tu rama + +### Sincroniza tu repositorio + +Primero, necesitas sincronizar tu fork para asegurarte de que esté actualizado con el repositorio bifurcado. + +Puedes lograr esto haciendo clic en el botón Sync fork en la página principal de tu fork. + +![Sync project header](../../../../assets/fork-sync.png) + +La imagen de arriba muestra que mi rama está detrás de la rama principal por 8 commits, y necesito sincronizarla para estar actualizada. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Abre una terminal + +Abre cualquier terminal de tu elección, ya sea la de tu IDE favorito o una instancia independiente. + +### Git + +Sigue los siguientes comandos para hacer rebase a tu rama local: + +- git checkout main +- git pull +- git checkout [tu rama] +- git rebase main +- Resuelve los conflictos + +En este paso, el rebase puede detenerse porque tu rama local tiene archivos conflictivos con la rama principal. Corrígelos. Después de esto: + +- git add . +- git rebase --continue + +Si tu rama no tiene conflictos, se mostrará un mensaje de éxito. + +### Envía tu trabajo de vuelta a la rama remota + +Finalmente, envía tu trabajo de vuelta a GitHub: + +- git push -f diff --git a/docs copy/src/content/docs/es/guides/resolve-challenge.md b/docs copy/src/content/docs/es/guides/resolve-challenge.md new file mode 100644 index 000000000..ac8922107 --- /dev/null +++ b/docs copy/src/content/docs/es/guides/resolve-challenge.md @@ -0,0 +1,92 @@ +--- +title: Resolver un Desafío +description: Guía para resolver un desafío +contributors: + - nelsongutidev + - 1fbr +sidebar: + order: 2 +--- + +En esta guía, aprenderás cómo resolver un desafío y enviar una respuesta al repositorio principal de GitHub. + +## Introducción + +Este repositorio ha sido creado utilizando [Nx](https://nx.dev/getting-started/intro). Nx es un monorepositorio que te permite almacenar múltiples aplicaciones dentro del mismo espacio de trabajo. Cada desafío es una aplicación separada. Si abres el directorio `apps`, encontrarás múltiples directorios, cada uno relacionado con un desafío específico. Cada directorio representa una aplicación `Nx` completa e independiente. Para ejecutar e iniciar una, abre tu terminal y ejecuta: + +```bash +npx nx serve +``` + +:::note[Nota] +Si no estás seguro de tu `NOMBRE_DE_LA_APLICACION`, abre el archivo README.md. El comando `serve` está escrito allí, con un enlace a la documentación del desafío. +::: + +:::note[Nota] +Si `nx` está instalado globalmente en tu dispositivo, puedes omitir el uso de `npx`. + +Para instalar `nx` globalmente, ejecuta + +```bash +npm i -g nx +``` + +::: + +## Crear una Rama de Git + +Antes de comenzar a implementar tu solución para resolver un desafío, crea una rama de git para comprometer tu trabajo. + +```bash +git checkout -b +``` + +## Resolver el Desafío + +Sigue las instrucciones para resolver el desafío. + +## Hacer Commit y Enviar tu Trabajo + +El último paso es hacer `commit` a tu trabajo siguiendo las [Directrices Convencionales](https://www.conventionalcommits.org/en/v1.0.0/). + +Finalmente, envía tu trabajo al repositorio remoto con el siguiente comando + +```bash + git push --set-upstream origin +``` + +:::tip[No es necesario que lo memorices] +No tienes que recordar el comando con precisión. Solo necesitas recordar `git push` y si es la primera vez que estás enviando esta rama, `git` te proporcionará el comando completo. +::: + +## Enviar tu Trabajo al Repositorio Principal + +Ahora, todo tu trabajo está ubicado dentro de tu instancia local del repositorio de Desafíos de Angular. + +El siguiente paso es ir a la página principal de [Desafíos de Angular](https://github.com/tomalaforge/angular-challenges) y crear una nueva Pull Request. + +Si no es asi, es posible que hayas hecho incorrectamente uno de los pasos anteriores o puedes ir a la pestaña Pull Request y hacer click en el botón New pull request. + +Una vez hayas escogido las dos ramas a comparar, deberías llegar a la siguiente página: + +![Vista de nuevo pull request](../../../../assets/new-pull-request.png) + +En la sección de título, comienza con Answer: seguido de tu challenge number. Después de eso, eres libre de agregar cualquier cosa que desees. + +:::danger[Importante] +Esto es muy importante. Le permite a otros saber qué desafío estás intentando resolver. +::: + +En la sección de descripción, puedes agregar preguntas, problemas que hayas encontrado o cualquier otra cosa que quieras compartir. Puedes dejarlo vacío si no tienes nada que decir. + +Ahora puedes hacer click en Create pull request. + +Lo leeré y comentaré cuando tenga algo de tiempo libre. + +:::note[Nota] +Todos son bienvenidos a comentar y leer otros PR. +::: + +:::tip[Campeón de OSS] +🔥 Una vez que hayas completado este tutorial, estarás listo para contribuir a cualquier otro repositorio público de GitHub y enviar un PR. Es tan fácil como eso. 🔥 +::: diff --git a/docs copy/src/content/docs/es/index.mdx b/docs copy/src/content/docs/es/index.mdx new file mode 100644 index 000000000..640ca9071 --- /dev/null +++ b/docs copy/src/content/docs/es/index.mdx @@ -0,0 +1,82 @@ +--- +title: Bienvenido a Desafíos de Angular +description: Comienza resolviendo esos desafíos y convirtiéndote en un mejor ingeniero FrontEnd de Angular. +template: splash +noCommentSection: true +hero: + tagline: ¡Comienza ahora y conviértete en un experto en Angular! + image: + file: ../../../assets/angular-challenge.webp + actions: + - text: Inicio + link: /es/guides/getting-started/ + icon: right-arrow + variant: primary + - text: Ir al Desafío más reciente + link: /es/challenges/angular/59-content-projection-defer/ + icon: rocket + - text: Dar una estrella + link: https://github.com/tomalaforge/angular-challenges + icon: github + variant: secondary +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; +import MyIcon from '../../../components/MyIcon.astro'; +import SubscriptionForm from '../../../components/SubscriptionForm.astro'; + + + + Este repositorio contiene 59 Desafíos relacionados con Angular, Nx, RxJS, Ngrx y Typescript. + Estos desafíos se resuelven en torno a problemas de la vida real o características específicas para mejorar tus habilidades. + + + + + + + + Uno de los objetivos de este repositorio es reducir la barrera de + entrada para el Software de Código Abierto (OSS). Al participar en estos + desafíos, aprenderás cómo empezar a contribuir a cualquier otro Proyecto de + Código Abierto. + + + + Aprender y practicar un framework siempre es un desafío. Este conjunto de + desafíos proporciona casos de uso del mundo real para aplicar lo que has + estado aprendiendo. Cualquiera puede comentar u ofrecer asistencia.{' '} + + Aprender solo es genial, pero aprender junto a otros te llevará más lejos. + + + + + ¿Tienes un problema, un error interesante o una idea? No lo dudes;{' '} + crea tus propios desafíos sin perder tiempo. + + + + Completar estos desafíos te preparará para cualquier desafío técnico que + puedas encontrar en un rol de frontend durante las entrevistas. + + + + Este proyecto es gratuito y pretende seguir siéndolo el mayor tiempo posible. Sin embargo, todo se lleva a cabo durante mi tiempo libre, incluyendo la creación de retos y la revisión de pull requests (PRs). El patrocinio puede apoyarme y contribuir al crecimiento del proyecto. + + + +--- + + + + diff --git a/docs copy/src/content/docs/fr/challenges/angular/1-projection.md b/docs copy/src/content/docs/fr/challenges/angular/1-projection.md new file mode 100644 index 000000000..509752c38 --- /dev/null +++ b/docs copy/src/content/docs/fr/challenges/angular/1-projection.md @@ -0,0 +1,47 @@ +--- +title: 🟢 Projection +description: Le challenge 1 consiste à apprendre à projeter des éléments DOM à travers des composants +author: thomas-laforge +contributors: + - alannelucq +challengeNumber: 1 +command: angular-projection +blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5 +videoLinks: + - link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq + alt: Projection video by Arthur Lannelucq + flag: FR + - link: https://www.youtube.com/watch?v=yNrfvu7vTa4 + alt: Projection video by Amos Lucian Isaila + flag: ES +sidebar: + order: 1 +--- + +## Information + +Dans Angular, la projection de contenu est une technique puissante pour créer des composants hautement personnalisables. Utiliser et comprendre les concepts liés aux ng-content et ngTemplateOutlet peut grandement améliorer votre capacité à créer des composants réutilisables. + +Vous pouvez tout apprendre sur ng-content [ici](https://angular.dev/guide/components/content-projection), de la projection de contenu la plus simple jusqu'à des utilisations plus complexes. + +Pour en savoir plus sur ngTemplateOutlet, vous pouvez trouver la documentation de l'API [ici](https://angular.io/api/common/NgTemplateOutlet) avec quelques exemples de base. + +Avec ces deux outils en main, vous êtes maintenant prêt à relever le défi. + +## Énoncé + +Vous commencerez avec une application entièrement fonctionnelle qui comprend un tableau de bord contenant une carte pour les enseignants et une carte pour les élèves. L'objectif est de mettre en place la carte de la ville. + +Bien que l'application fonctionne, l'expérience développeur est loin d'être optimale. Chaque fois que vous devez implémenter une nouvelle carte, vous devez modifier le `card.component.ts`. Dans des projets réels, ce composant pourrait être partagé entre de nombreuses applications. Le but du défi est de créer un `CardComponent` qui peut être personnalisé sans aucune modification. Une fois que vous aurez créé ce composant, vous pourrez commencer à implémenter le `CityCardComponent` et vous assurer de ne pas toucher au `CardComponent`. + +## Contraintes + +- Vous devez refactoriser le `CardComponent` et le `ListItemComponent`. +- La boucle `@for` doit être déclarée et rester à l'intérieur du `CardComponent`. Vous pourriez être tenté de la déplacer dans le `ParentCardComponent` comme `TeacherCardComponent`. +- Le composant `CardComponent` ne doit contenir aucune condition. +- CSS: essayez d'éviter d'utiliser `::ng-deep`. Trouvez un meilleur moyen de gérer le style CSS. + +## Challenges Bonus + +- Utilisez l'API des signals pour gérer l'état de vos composants (documentation [ici](https://angular.dev/guide/signals)) +- Pour référencer le template, utilisez une directive au lieu d'une magic string ([Qu'est-ce qui pose problème avec les magic string ?](https://softwareengineering.stackexchange.com/a/365344)) diff --git a/docs copy/src/content/docs/fr/challenges/angular/21-anchor-navigation.md b/docs copy/src/content/docs/fr/challenges/angular/21-anchor-navigation.md new file mode 100644 index 000000000..e8e7ea947 --- /dev/null +++ b/docs copy/src/content/docs/fr/challenges/angular/21-anchor-navigation.md @@ -0,0 +1,20 @@ +--- +title: 🟢 Naviguer sur une page +description: Le challenge 21 consiste à apprendre à utiliser la navigation intégrée d'Angular +author: thomas-laforge +contributors: + - alannelucq +challengeNumber: 21 +command: angular-anchor-navigation +sidebar: + order: 4 +--- + +## Information + +Vous commencez avec une application qui possède une navigation de base et une navigation par ancre dans le `HomeComponent`. Cependant, l'utilisation de `href` recrée le chemin à chaque fois et rafraîchit la page. + +## Énoncé + +- Votre tâche consiste à refactoriser cette application pour utiliser la navigation intégrée afin de mieux s'intégrer dans le Framework Angular. Vous pouvez explorer le router, mais il est préférable de rester dans le template et d'utiliser la directive `RouterLink`. +- Pour améliorer l'expérience utilisateur, ajoutez un scroll fluide. diff --git a/docs copy/src/content/docs/fr/challenges/angular/22-router-input.md b/docs copy/src/content/docs/fr/challenges/angular/22-router-input.md new file mode 100644 index 000000000..4bb9c8359 --- /dev/null +++ b/docs copy/src/content/docs/fr/challenges/angular/22-router-input.md @@ -0,0 +1,28 @@ +--- +title: 🟢 @RouterInput() +description: Challenge 22 is about using the @Input decorator to retreive router params. +author: thomas-laforge +contributors: + - alannelucq +challengeNumber: 22 +command: angular-router-input +blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617 +sidebar: + order: 5 +--- + +## Information + +Dans cette application, nous récupérons trois informations depuis le routeur dans notre `TestComponent` : + +- `testId` qui est situé dans les paramètres de l'URL. +- `user` qui est situé dans les paramètres de la requête de l'URL. +- `permission` qui est défini dans l'objet `data` de la route. + +Jusqu'à la version 15 d'Angular, nous devions utiliser le `ActivatedRoute` pour obtenir toutes ces informations et les récupérer via des observables pour écouter sur les changements d'URL. + +Depuis la version 16, Angular a introduit un nouvel `Input` qui peut écouter les changements de données d'une route. Vous pouvez en savoir plus [ici](https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617). + +## Énoncé + +L'objectif de cet exercice est de refactoriser le code pour utiliser la nouvelle stratégie `RouterInput`. diff --git a/docs copy/src/content/docs/fr/challenges/angular/31-module-to-standalone.md b/docs copy/src/content/docs/fr/challenges/angular/31-module-to-standalone.md new file mode 100644 index 000000000..bd0356610 --- /dev/null +++ b/docs copy/src/content/docs/fr/challenges/angular/31-module-to-standalone.md @@ -0,0 +1,29 @@ +--- +title: 🟢 Module vers Standalone +description: Le challenge 31 consiste à migrer une application basée sur des modules vers une application standalone. +author: thomas-laforge +contributors: + - alannelucq +challengeNumber: 31 +command: angular-module-to-standalone +sidebar: + order: 6 +--- + +## Information + +Dans la version 14 d'Angular, les composants standalone ont été introduits et sont devenus stables dans la version 15. Si vous ne les avez pas encore essayés, il n'est jamais trop tard. Vous pouvez les essayer dans ce challenge. + +L'objectif est de voir comment **Nx** et les **composants standalone** fonctionnent ensemble, et d'expérimenter le processus de découplage de votre application avec la bibliothèque Nx et les composants standalone. + +Les composants standalone sont très simples à comprendre mais les utilisations de ces composants dans **le routing et via du lazy-loading** peuvent être un peu plus difficiles à appréhender. Ce challenge vous permettra de manipuler des composants à différents niveaux d'imbrication et de travailler avec des routes qui utilisent du lazy loading. + +Après avoir complété ce défi, les composants standalone n'auront plus aucun secret pour vous. + +## Énoncé + +L'objectif de ce challenge est de migrer votre application depuis des composants basés sur des modules vers des composants standalone. + +## Note + +Vous pouvez également tester le [schematic Angular](https://angular.dev/reference/migrations/standalone) pour migrer les NgModule vers des composants standalone. _(Comme nous utilisons Nx, commencez votre commande par nx au lieu de ng)_ diff --git a/docs copy/src/content/docs/fr/challenges/angular/46-simple-animations.md b/docs copy/src/content/docs/fr/challenges/angular/46-simple-animations.md new file mode 100644 index 000000000..d20446040 --- /dev/null +++ b/docs copy/src/content/docs/fr/challenges/angular/46-simple-animations.md @@ -0,0 +1,48 @@ +--- +title: 🟢 Animations Simples +description: Le challenge 46 consiste à apprendre comment utiliser l'API d'animations intégrée dans Angular +author: sven-brodny +contributors: + - alannelucq +challengeNumber: 46 +command: angular-simple-animations +sidebar: + order: 17 +--- + +## Information + +Il s'agit du premier des deux challenges sur les animations. Le but de cette série est de maîtriser les animations en Angular. + +Des animations bien conçues peuvent rendre votre application plus agréable et plus intuitive à utiliser, mais elles ne sont pas seulement cosmétiques. Les animations peuvent améliorer votre application et l'expérience utilisateur de plusieurs façons : + +- Sans animations, les transitions de pages web peuvent sembler abruptes et désagréables. +- Le mouvement améliore grandement l'expérience utilisateur, les animations permettent donc aux utilisateurs de percevoir la réponse de l'application à leurs actions. +- De bonnes animations attirent intuitivement l'attention de l'utilisateur là où elle est nécessaire. + +Je vous recommande de lire la [documentation officielle](https://angular.dev/guide/animations). Vous y apprendrez tout ce qui est nécessaire pour réussir ce challenge. + +Vous pouvez également regarder cet [exemple fonctionnel](https://svenson95.github.io/ng-xmp-animations/) et ce [repertoire git](https://github.com/svenson95/ng-xmp-animations) pour vous inspirer. + +## Énoncé + +L'objectif de ce challenge est d'ajouter des animations qui doivent être déclenchées lorsque l'utilisateur arrive sur la page ou la recharge. + +## Contraintes + +- N'utilisez aucun CSS et utilisez l'API intégrée d'Angular `@angular/animations`. +- Ne déclenchez pas les animations avec un bouton comme dans les exemples, mais lorsque l'utilisateur entre ou recharge la page. + +### Niveau 1 + +Ajoutez une animation de fondu ou de déplacement pour les paragraphes sur le côté gauche. + + + +### Niveau 2 + +Ajoutez une animation en cascade pour la liste sur le côté droit. + + diff --git a/docs copy/src/content/docs/fr/challenges/angular/5-crud-application.md b/docs copy/src/content/docs/fr/challenges/angular/5-crud-application.md new file mode 100644 index 000000000..0ef30ec4d --- /dev/null +++ b/docs copy/src/content/docs/fr/challenges/angular/5-crud-application.md @@ -0,0 +1,52 @@ +--- +title: 🟢 Application CRUD +description: Le challenge 5 consiste à refactoriser une application CRUD +author: thomas-laforge +contributors: + - alannelucq +challengeNumber: 5 +command: angular-crud-application +sidebar: + order: 2 +--- + +## Information + +Communiquer et synchroniser un état global ou local avec votre backend est au cœur de toute application. Vous devrez maîtriser les meilleures pratiques suivantes pour construire des applications Angular solides et fiables. + +## Énoncé + +Dans cet exercice, vous avez une petite application CRUD dans laquelle vous pouvez récupérer, mettre à jour et supprimer des tâches. + +Pour le moment, nous avons un exemple fonctionnel mais qui est rempli de nombreuses mauvaises pratiques. + +### Étape 1 : refactoriser avec les meilleures pratiques + +Ce que vous devrez faire: + +- Évitez d'utiliser **any** comme type. Utiliser des interfaces pour tirer parti du système de typage de Typescript permet d'éviter les erreurs. +- Utilisez un **service séparé** pour tous vos appels HTTP et utilisez un **Signal** pour votre liste de tâches. +- Ne **mutez** pas les données + +```typescript +// À éviter +this.todos[todoUpdated.id - 1] = todoUpdated; + +// Privilégier une approche comme celle-ci, mais qui doit être améliorée car nous voulons toujours conserver le même ordre +this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]; +``` + +### Étape 2 : Améliorer + +- Ajoutez un bouton **Supprimer** : _Documentation de l'API fictive_ +- Gérez correctement les **erreurs**. _(De façon globale)_ +- Ajoutez un **indicateur de chargement** global. _Vous pouvez utilisez le MatProgressSpinnerModule_ + +### Étape 3 : Maintenabilité !! (ajoutez des tests) + +- Ajoutez 2/3 tests + +### Étape 4 : Effet waouw !!! (maîtrisez votre état). + +- Utilisez le **component store de ngrx**, **ngrx/store**, **rxAngular**, **tanstack-query** ou **ngrx/signal-store** pour gérer l'état local de votre composant. +- Ayez un indicateur de chargement/erreur **localisé** , par exemple uniquement sur la tâche en cours de traitement et **désactivez** tous les boutons sur cette tâche. _(Astuce: vous devrez créer un ItemComponent)_ diff --git a/docs copy/src/content/docs/fr/challenges/angular/8-pure-pipe.md b/docs copy/src/content/docs/fr/challenges/angular/8-pure-pipe.md new file mode 100644 index 000000000..0932e7a67 --- /dev/null +++ b/docs copy/src/content/docs/fr/challenges/angular/8-pure-pipe.md @@ -0,0 +1,37 @@ +--- +title: 🟢 Pipe pur +description: Le challenge 8 consiste à créer un pipe pur +author: thomas-laforge +contributors: + - alannelucq +challengeNumber: 8 +command: angular-pure-pipe +blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d +sidebar: + order: 3 +--- + +## Information + +Il s'agit du premier des trois challenges `@Pipe()`. L'objectif de cette série est de maîtriser les **pipes** en Angular. + +Les pipes sont un moyen très puissant de transformer les données dans votre template. La différence entre appeler une fonction et un pipe réside dans le fait que les pipes purs sont mémorisés. Ils ne seront donc pas recalculés à chaque cycle de détection des changements si les données en entrée n'ont pas changées. + +Les pipes sont conçus pour être efficaces et optimisés pour la performance. Ils utilisent des mécanismes de détection des changements pour ne recalculer la valeur que si la donnée en entrée change, ce qui minimise les calculs inutiles et améliore les performances de rendu. + +Par défaut, un pipe est pur. Vous devez être conscient que définir `pure` à false est susceptible d'être inefficace, car cela augmente le nombre de rerenders. + +:::note +Un pipe **pur** est appelé uniquement lorsque la valeur change. +Un pipe **impur** est appelé à chaque cycle de détection des changements. +::: + +Il existe quelques pipes prédéfinis utiles comme DatePipe, UpperCasePipe et CurrencyPipe. Pour en savoir plus sur les pipes dans Angular, consultez la documentation de l'API [ici](https://angular.dev/guide/pipes). + +## Énoncé + +Dans cet exercice, vous devez refactoriser une fonction de transformation à l'intérieur d'un composant qui est appelée dans votre template. L'objectif est de convertir cette fonction en un pipe. + +## Contraintes + +- Doit être fortement typé diff --git a/docs copy/src/content/docs/fr/guides/checkout-answer.md b/docs copy/src/content/docs/fr/guides/checkout-answer.md new file mode 100644 index 000000000..9a16f2a51 --- /dev/null +++ b/docs copy/src/content/docs/fr/guides/checkout-answer.md @@ -0,0 +1,59 @@ +--- +title: Consulter la réponse de quelqu'un d'autre +description: Guide pour consulter la réponse de quelqu'un d'autre. +contributors: + - alannelucq +sidebar: + order: 3 +--- + +Toutes les réponses aux Challenges Angular seront présentées sous la forme d'une pull request (PR). Pour les consulter +et +les suivre, naviguez dans la page Files Changes sur GitHub. Cependant, comprendre et suivre ce processus peut ne pas +être simple si vous n'êtes pas familier avec l'interface. Dans de nombreux cas, vous préférerez peut-être vous mettre +sur la branche et examiner la réponse dans votre IDE préféré. + +## Installer la CLI de GitHub + +Suivez les instructions pour votre système d'exploitation [ici](https://github.com/cli/cli#installation). + +## Consulter la PR de quelqu'un d'autre en local + +### Synchronisez votre dépôt + +Tout d'abord, vous devez synchroniser votre fork pour vous assurer qu'il soit à jour avec le dépôt forké. + +Cela peut être réalisé en cliquant sur le bouton Sync fork sur la page principale de votre fork. + +![Sync project header](../../../../assets/fork-sync.png) + +L'image ci-dessus montre que ma branche a 8 commits de retard par rapport à la branche principale, et je dois la +synchroniser pour qu'elle soit à jour. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Consulter la PR en local + +Recherchez la PR que vous souhaitez consulter en local et récupérez son ID. Vous le trouverez dans le titre de la +PR (comme illustré ci-dessous). + +![PR header](../../../../assets/PR-header.png) + +Ensuite, ouvrez n'importe quel terminal dans le répertoire de votre projet et exécutez la commande suivante : + +```bash +gh pr checkout +``` + +Si vous ne vous souvenez pas de la commande, cliquez sur le bouton Code sur le côté droit de l'en-tête, et vous pourrez +facilement la copier/coller. + +![PR code modal](../../../../assets/PR-code-btn-modal.png) + +:::note +Si la commande ne fonctionne pas ou échoue, l'interface CLI de GitHub vous guidera à travers le processus. +::: + +🔥 Vous pouvez maintenant consulter la réponse en local et la lancer pour la tester. 🔥 + + diff --git a/docs copy/src/content/docs/fr/guides/contribute.md b/docs copy/src/content/docs/fr/guides/contribute.md new file mode 100644 index 000000000..69e8d4a2b --- /dev/null +++ b/docs copy/src/content/docs/fr/guides/contribute.md @@ -0,0 +1,24 @@ +--- +title: Comment contribuer ? +description: Guide pour savoir comment contribuer à ce projet. +contributors: + - alannelucq +sidebar: + order: 4 +--- + +Vous pouvez contribuer à ce projet de plusieurs manières : + +🔥 Créer un nouveau challenge en suivant ces [instructions](/guides/create-challenge). + +🔥 Répondre aux challenges et soumettez les résultats (guide [ici](/guides/resolve-challenge)). + +🔥 Donner des retours bienveillants et constructifs sur les solutions des autres. + +🔥 Corriger les fautes de frappe dans la documentation. + +🔥 Aider à la traduction de la documentation. + +🔥 Créer une issue pour suggérer de nouvelles idées de challenges ou signaler un bug. + +🔥 Sponsoriser le projet [ici](https://github.com/sponsors/tomalaforge). diff --git a/docs copy/src/content/docs/fr/guides/create-challenge.md b/docs copy/src/content/docs/fr/guides/create-challenge.md new file mode 100644 index 000000000..a197db052 --- /dev/null +++ b/docs copy/src/content/docs/fr/guides/create-challenge.md @@ -0,0 +1,68 @@ +--- +title: Créer un challenge +description: Guide sur comment créer un challenge +contributors: + - alannelucq +sidebar: + order: 5 +--- + +Vous avez une idée à partager, un bug intéressant avec lequel vous luttez dans l'un de vos projets privés ou +secondaires, ou une astuce Angular que vous avez découverte ? Toutes ces situations sont un bon point de départ pour +créer un challenge et partager votre solution avec les autres. + +Comment commencer à créer ces challenges ? + +## Configuration de base + +Pour simplifier le processus, j'ai créé un générateur Nx qui configurera tout le code de base pour vous. Le moyen le +plus +simple de l'exécuter est d'utiliser la console Nx : allez dans Nx Console > generate > @angular-challenges/cli - +challenge. + +Vous pouvez également utiliser [l'extension Nx Console](https://nx.dev/getting-started/editor-setup) de votre IDE pour +générer les fichiers. + +### Paramètres + +#### Paramètres obligatoires + +- title: Le titre que vous souhaitez donner à votre challenge. + :::note + Le titre doit comporter un maximum de 25 caractères. + ::: + +- challengeDifficulty: La difficulté estimée de votre challenge. Il y a trois niveaux de difficulté : 🟢 facile / + 🟠 moyen / 🔴 difficile +- name: Le nom de l'application Nx. + :::note + Il doit être écrit en **kebab-case**. + ::: +- docRepository: La catégorie de votre challenge : Nx, Angular, Angular Performance, Rxjs, NgRx, Typescript, ou + Forms. + +#### Paramètres optionnels + +- directory: Si vous souhaitez que votre application soit située dans un dossier spécifique à l'intérieur + de `apps`. +- addTest: Si vous souhaitez ajouter une configuration de test. + +### Qu'est-ce qui est créé ? + +- Le générateur créera tous les fichiers nécessaires pour avoir une nouvelle application fonctionnelle. Tous ces + fichiers seront créés dans apps/${directory}/${name}. +- Un fichier Markdown avec une configuration minimale sera créé dans docs/src/content/docs/challenges/${docRepository}. + +## Création d'un challenge + +La seule chose qu'il vous reste à faire est de créer votre challenge. 🚀 + +:::danger +N'oubliez pas de mettre à jour la documentation pour présenter votre challenge et fournir vos instructions. +::: + +À vous de jouer !!! 💪 + +## Soumission d'une solution + +Après environ une semaine, fournissez une pull request de la solution de votre challenge. diff --git a/docs copy/src/content/docs/fr/guides/faq.md b/docs copy/src/content/docs/fr/guides/faq.md new file mode 100644 index 000000000..abbba29af --- /dev/null +++ b/docs copy/src/content/docs/fr/guides/faq.md @@ -0,0 +1,24 @@ +--- +title: FAQ +description: Foire Aux Questions +contributors: + - alannelucq +sidebar: + order: 7 +--- + +
+ + Pourquoi mon application ne démarre-t-elle pas, ou pourquoi est-ce que je rencontre des erreurs dans mon terminal lorsque je lance `nx serve` ? + + +La plupart du temps, ce problème survient parce que vos node_modules sont obsolètes et que vous devez les mettre à jour +en exécutant `npm ci`. + +Si le processus d'installation échoue, vous pouvez résoudre ce problème en supprimant votre dossier node_modules en +utilisant la commande `rm -rf node_modules` ou `npx npkill`, puis en relançant `npm ci`. + +Si le problème persiste, veuillez signaler le +problème [ici](https://github.com/tomalaforge/angular-challenges/issues/new). + +
diff --git a/docs copy/src/content/docs/fr/guides/getting-started.md b/docs copy/src/content/docs/fr/guides/getting-started.md new file mode 100644 index 000000000..562043b6b --- /dev/null +++ b/docs copy/src/content/docs/fr/guides/getting-started.md @@ -0,0 +1,59 @@ +--- +title: Comment démarrer +contributors: + - tomalaforge +description: Un guide sur la manière de commencer avec sur Angular Challenges. +sidebar: + order: 1 +--- + +Pour commencer avec les Challenges Angular, suivez ces étapes : + +## Créez un compte GitHub + +Si vous souhaitez soumettre une réponse, vous devrez avoir votre propre compte GitHub. De plus, avoir un compte GitHub est toujours bénéfique et c'est gratuit. + +## Forkez le projet GitHub + +Accédez au [répertoire des Challenges Angular](https://github.com/tomalaforge/angular-challenges) et cliquez sur le bouton Fork dans l'en-tête. Cela créera une copie de ce dépôt sur votre propre page GitHub. + +## Clonez le dépôt sur votre machine locale + +Sélectionnez un répertoire sur votre ordinateur local et clonez ce dépôt. + +Ouvrez un terminal, accédez au répertoire choisi et tapez la commande suivante : + +```bash +git clone https://github.com/[VOTRE_NOM_GITHUB]/angular-challenges.git +``` + +:::note +Vous pouvez trouver l'URL de clonage en cliquant sur le bouton <> Code dans votre propre instance du dépôt des Challenges Angular. + +![Header of GitHub workspace](../../../../assets/header-github.png) + +::: + +## Ouvrez le projet dans votre IDE préféré + +Ouvrez le projet dans n'importe quel IDE de votre choix. + +## Installez toutes les dépendances + +```bash +npm ci +``` + +## Choisissez un challenge + +Votre projet est maintenant opérationnel. La seule étape restante est de choisir un challenge 🚀 + +Chaque challenge se compose de : + +- Nom : indiquant de quoi traite le défi. +- Numéro : ordre de création. Le numéro n'a pas de signification particulière mais aide pour la référence dans la section des Demandes de Tirage (Pull Requests) GitHub. +- Badge : aide à visualiser le degré de difficulté. C'est entièrement subjectif 😅 + - 🟢 facile + - 🟠 moyen + - 🔴 difficile diff --git a/docs copy/src/content/docs/fr/guides/rebase.md b/docs copy/src/content/docs/fr/guides/rebase.md new file mode 100644 index 000000000..bf50ebb71 --- /dev/null +++ b/docs copy/src/content/docs/fr/guides/rebase.md @@ -0,0 +1,63 @@ +--- +title: Rebase votre branche +description: Guide pour faire un rebase de sa branche et récupérer les derniers changements. +contributors: + - alannelucq +sidebar: + order: 6 +--- + +Parfois, des modifications peuvent être ajoutées au projet. Je vais essayer de faire des changements qui ne cassent +rien, mais parfois, c'est inévitable. + +La plupart du temps, vous n'aurez pas besoin de rebaser votre solution, mais voici un guide pour vous aider à savoir +comment le faire. + +:::note +Ce guide est applicable à tout projet Open Source. +::: + +## Étapes pour rebaser votre branche + +### Synchronisez votre dépôt + +Tout d'abord, vous devez synchroniser votre fork pour vous assurer qu'il est à jour avec le dépôt forké. + +Vous pouvez le faire en cliquant sur le bouton Sync fork sur la page principale de votre fork. + +![Sync project header](../../../../assets/fork-sync.png) + +L'image ci-dessus montre que ma branche a 8 commits de retard par rapport à la branche principale et que je dois la +synchroniser pour qu'elle soit à jour. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Ouvrez un terminal + +Ouvrez le terminal de votre choix, soit celui de votre IDE préféré, soit une instance autonome. + +### Git + +Exécutez les commandes suivantes pour rebaser votre branche locale : + +- git checkout main +- git pull +- git checkout [votre branche] +- git rebase main +- Résolvez les conflits + +À cette étape, le rebase peut s'arrêter parce que votre branche locale a des fichiers en conflit avec la branche +principale. Corrigez-les. + +Une fois que c'est fait : + +- git add . +- git rebase --continue + +Si votre branche n'a pas de conflit, un message de succès sera affiché. + +### Envoyez votre travail vers la branche distante + +Enfin, envoyez votre travail vers GitHub : + +- git push -f diff --git a/docs copy/src/content/docs/fr/guides/resolve-challenge.md b/docs copy/src/content/docs/fr/guides/resolve-challenge.md new file mode 100644 index 000000000..0031a5981 --- /dev/null +++ b/docs copy/src/content/docs/fr/guides/resolve-challenge.md @@ -0,0 +1,101 @@ +--- +title: Résoudre un Challenge +contributors: + - tomalaforge +description: Guide pour résoudre un challenge +sidebar: + order: 2 +--- + +Dans ce guide, vous apprendrez comment résoudre un challenge et soumettre une réponse sur le répertoire principal de GitHub. + +## Introduction + +Ce répertoire utilise [Nx](https://nx.dev/getting-started/intro). Nx est un monorépo qui vous permet de stocker plusieurs applications à l'intérieur du même espace de travail. Chaque challenge est une application distincte. Si vous ouvrez le répertoire `apps`, vous trouverez plusieurs dossiers, chacun lié à un challenge spécifique. Chaque dossier représente une application autonome complète `Nx`. Pour exécuter et démarrer l'une d'entre elles, ouvrez votre terminal et exécutez : + +```bash +npx nx serve +``` + +:::note +Si vous n'êtes pas sûr de votre `NOM_APPLICATION`, ouvrez le fichier README.md. La commande `serve` y est écrite, avec un lien vers la documentation du challenge. +::: + +:::note +Si vous installez `nx` globalement sur votre ordinateur, vous éviterez de préfixer chaque commande par `npx`. + +Pour installer `nx` globalement, exécutez + +```bash +npm i -g nx +``` + +::: + +## Créer une Branche Git + +Avant de commencer à résoudre un challenge, créez une branche git pour y ajouter vos modifications. + +```bash +git checkout -b +``` + +## Résoudre un Challenge + +Suivez les instructions décrites sur chaque Challenge pour le résoudre. + +## Commitez et Pousser votre Travail + +La dernière étape consiste à valider votre travail en suivant les [Conventional Guidelines](https://www.conventionalcommits.org/en/v1.0.0/). + +Enfin, poussez votre travail vers le répertoire distant avec la commande suivante + +```bash + git push --set-upstream origin +``` + +:::tip[Pas besoin de retenir la commande par coeur] +Vous n'avez pas besoin de mémoriser précisément la commande. Il vous suffit de vous rappeler `git push `et si c'est la première fois que vous poussez cette branche, `git` vous fournira la commande complète. +::: + +## Soumettre votre Travail sur le répertoire Principal + +Maintenant, tout votre travail se trouve dans votre instance locale du dépôt de Angular Challenges. + +La prochaine étape est de vous rendre sur la page principale de Angular Challenges et de créer une nouvelle Pull Request. + +GitHub devrait afficher en en-tête une notification pour vous aider à créer la pull request. + +Si ce n'est pas le cas, vous avez soit mal effectué l'une des étapes précédentes, soit vous pouvez vous rendre sur l'onglet Pull Request et cliquer sur le bouton New pull request. + +Une fois que vous avez choisi les deux branches à comparer, vous devriez arriver sur la page suivante : + +![New pull request screen](../../../../assets/new-pull-request.png) + +Dans la section du titre, commencez par Réponse : suivi de votre numéro de challenge. Ensuite, vous êtes libre d'ajouter tout ce que vous souhaitez. + +:::danger +C'est très important. Cela permet aux autres de savoir quel challenge vous tentez de résoudre. +::: + +Dans la section de description, vous pouvez ajouter des questions, des problèmes rencontrés ou tout autre contenu que vous souhaitez partager. Vous pouvez laisser vide si vous n'avez rien à dire. + +Vous pouvez maintenant cliquer sur Créer pull request. + +## Avoir un Retour + +Pour continuer à donner des retours de qualités, sponsorise le project sur Github: + +
    +
  • $5 pour une review
  • +
  • $25 pour des reviews a vie
  • +
  • Créez un challenge/Contribuez pour des reviews à vie
  • +
+ +:::note +Tout le monde peut commenter ou lire les Pull Requests des autres participants. +::: + +:::tip[Champion OSS] +🔥 Une fois que vous avez terminé ce tutoriel, vous êtes prêt à contribuer à n'importe quel répertoire public GitHub et à soumettre une PR. C'est aussi simple que ça. 🔥 +::: diff --git a/docs copy/src/content/docs/fr/index.mdx b/docs copy/src/content/docs/fr/index.mdx new file mode 100644 index 000000000..25435d041 --- /dev/null +++ b/docs copy/src/content/docs/fr/index.mdx @@ -0,0 +1,81 @@ +--- +title: Bienvenue sur Angular Challenges +description: Commence par résoudre ces défis et deviens un meilleur ingénieur FrontEnd Angular. +template: splash +noCommentSection: true +hero: + tagline: Commence maintenant et deviens un expert Angular ! + image: + file: ../../../assets/angular-challenge.webp + actions: + - text: C'est parti ! + link: /guides/getting-started/ + icon: right-arrow + variant: primary + - text: Aller au dernier Challenge + link: /fr/challenges/angular/59-content-projection-defer/ + icon: rocket + - text: Donne une étoile + link: https://github.com/tomalaforge/angular-challenges + icon: github + variant: secondary +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; +import MyIcon from '../../../components/MyIcon.astro'; +import SubscriptionForm from '../../../components/SubscriptionForm.astro'; + + + + Ce répertoire rassemble 59 Défis liés à Angular, Nx, RxJS, Ngrx et Typescript. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences. + + + + + + + + L'un des objectifs de ce répertoire est de rendre plus accessible les + contributions aux logiciels Open Source (OSS). En résolvant ces défis, vous + apprendrez comment commencer à contribuer à n'importe quel projet Open Source. + + + + Apprendre et démarrer sur un nouveau framework est toujours difficile. Cette + série de défis propose des cas d'utilisation réels pour appliquer ce que vous + avez appris. N'importe qui peut commenter ou aider.{' '} + + Apprendre seul est bien, mais apprendre aux côtés des autres vous fera + progresser davantage et plus rapidement. + + + + + Avez-vous un problème, un bug intéressant ou une idée ? N'hésitez pas ;{' '} + créez vos propres challenges sans perdre de temps. + + + + Résoudre ces challenges vous préparera aux éventuels défis techniques que vous + pourriez rencontrer lors d'un entretien pour un rôle d'ingénieur frontend. + + + + Ce projet est gratuit et vise à le rester le plus longtemps possible. Cependant, tout est réalisé pendant mon temps libre, y compris la création de challenges et la relecture des pull requests. Le sponsoring peut me soutenir et contribuer à la croissance du projet. + + + +--- + + + + diff --git a/docs copy/src/content/docs/guides/checkout-answer.md b/docs copy/src/content/docs/guides/checkout-answer.md new file mode 100644 index 000000000..2e56ce162 --- /dev/null +++ b/docs copy/src/content/docs/guides/checkout-answer.md @@ -0,0 +1,57 @@ +--- +title: Check out Somebody's Answer +description: Guide to checking out someone else's answer. +contributors: + - tomalaforge + - gsgonzalez88 + - 1fbr + - jdegand +sidebar: + order: 3 +--- + +All Angular Challenges answers will be presented in the form of a pull request (PR). To view and follow them, navigate through the **Files Changes** page on GitHub. However, understanding and following this process may not be straightforward if you are not familiar with the interface. In many cases, you may prefer to check out the branch and review the solution in your preferred IDE. + +## Install the GitHub CLI + +Follow the instructions for your operating system [here](https://github.com/cli/cli#installation). + +## Checkout a PR locally from someone else + +### Sync your repository + +First, you need to synchronize your fork to ensure it is up-to-date with the forked repository. + +This can be achieved by clicking the **Sync fork** button on the main page of your fork. + +![Sync project header](../../../assets/fork-sync.png) + +The image above shows that my branch is behind the main branch by 8 commits, and I need to synchronize it to be up to date. + +![Sync project update modal](../../../assets/sync-fork-update.png) + +### Checkout locally + +Navigate to the PR you wish to check out locally and obtain its ID. You will find it in the title of the PR (as shown below). + +![PR header](../../../assets/PR-header.png) + +Next, go to any terminal within your project directory and run the following command: + +```bash +gh pr checkout +``` + +If you don't remember the command, click on the Code button on the right side of the header, and you can easily copy/paste the command. + +![PR code modal](../../../assets/PR-code-btn-modal.png) + +:::note +If the command doesn't work or fails, GitHub CLI will guide you through the process. +::: + +🔥 You can now navigate through the solution locally and serve it to test it. 🔥 + +### Checkout with GitHub Codespaces + +You can checkout any **open** PR with GitHub Codespaces. After clicking the code button, you can navigate to the codespaces tab and click the green button to create a codespace on the PR's branch. After the codespace initializes, you can serve the app. diff --git a/docs copy/src/content/docs/guides/contribute.md b/docs copy/src/content/docs/guides/contribute.md new file mode 100644 index 000000000..45f164a4f --- /dev/null +++ b/docs copy/src/content/docs/guides/contribute.md @@ -0,0 +1,25 @@ +--- +title: Contribute +description: Guide to contribute +contributors: + - tomalaforge + - jdegand +sidebar: + order: 4 +--- + +You can contribute to this repository in many ways: + +🔥 Create a new challenge by following these [instructions](/guides/create-challenge). + +🔥 Answer challenges and submit the results (guide [here](/guides/resolve-challenge)). + +🔥 Give caring, constructive feedback on other people's solutions. + +🔥 Correct typos within the documentation. + +🔥 Assist with the documentation's translation. + +🔥 File an issue to suggest new challenge ideas or report a bug. + +🔥 Sponsor the project [here](https://github.com/sponsors/tomalaforge). diff --git a/docs copy/src/content/docs/guides/create-challenge.md b/docs copy/src/content/docs/guides/create-challenge.md new file mode 100644 index 000000000..4b01d6bb8 --- /dev/null +++ b/docs copy/src/content/docs/guides/create-challenge.md @@ -0,0 +1,66 @@ +--- +title: Create your own challenge +description: Guide to create your own challenge +contributors: + - tomalaforge + - gsgonzalez88 + - jdegand +sidebar: + order: 5 +--- + +You have an idea you want to share, an interesting bug you are struggling with in one of your private or side projects, or an Angular trick you discovered. All of these possibilities are a good starting point to create a challenge and share the solution with others. + +How do you start creating these challenges? + +## Boilerplate Setup + +To streamline the process, I have created an Nx generator that will set up all the boilerplate for you. The easiest way to run it is by using the Nx console: go to the Nx Console > generate > @angular-challenges/cli - challenge. + +Alternatively, you may utilize your IDE's [Nx Console extension](https://nx.dev/getting-started/editor-setup) to generate the files. + +### Parameters + +#### mandatory parameters + +- title: The title you want to give to your challenge. + :::note + The title must be a maximum of 25 characters. + ::: + +- author: Your name + :::note + Your name should be in kebab-case. (e.g. john-doe) + ::: + :::note + Don't forget to update your personal information inside the file at your name. + ::: + +- challengeDifficulty: The difficulty you think your challenge has. There are three difficulty levels : 🟢 easy / 🟠 medium / 🔴 hard + +- docRepository: The category of your Challenge is Nx, Angular, Angular Performance, Rxjs, NgRx, Typescript, Forms or Signals. + +#### optional parameters + +- challengeNumber: You can specify a challenge number if a challenge is being submitted. (If empty, the number will be the next one). +- directory: If you want your application to be located in a specific folder inside `apps`. +- addTest: If you want to add test configuration. + +### What is created? + +- The generator will create all the files needed to have a new working application. All these files will be created inside `apps/${directory}/${name}`. +- A Markdown file with minimal setup will be created inside `docs/src/content/docs/challenges/${docRepository}`. + +## Challenge Creation + +The only thing left to do is create your challenge. 🚀 + +:::danger +Don't forget to update the docs to introduce your challenge and provide your instructions. +::: + +It's your turn to act!!! 💪 + +## Solution Submission + +After one week or so, provide a pull request of your solution to your challenge. diff --git a/docs copy/src/content/docs/guides/faq.md b/docs copy/src/content/docs/guides/faq.md new file mode 100644 index 000000000..93a29c964 --- /dev/null +++ b/docs copy/src/content/docs/guides/faq.md @@ -0,0 +1,20 @@ +--- +title: FAQ +description: Answer to question +contributors: + - tomalaforge + - jdegand +sidebar: + order: 7 +--- + +
+ Why is my application not starting, or why do I encounter errors in my terminal when I run `nx serve`? + + Most of the time, this issue arises because your node_modules are outdated, and you need to update them by running `npm ci`. + +If the installation process fails, you can resolve it by deleting your node_modules folder using the command `rm -rf node_modules` or `npx npkill` and then re-running `npm ci`. + +If the problem persists, please report the issue [here](https://github.com/tomalaforge/angular-challenges/issues/new). + +
diff --git a/docs copy/src/content/docs/guides/getting-started.md b/docs copy/src/content/docs/guides/getting-started.md new file mode 100644 index 000000000..e707fa36c --- /dev/null +++ b/docs copy/src/content/docs/guides/getting-started.md @@ -0,0 +1,82 @@ +--- +title: Getting Started +description: A guide on how to get started with Angular Challenges. +contributors: + - tomalaforge + - 1fbr + - ho-ssain + - jdegand +sidebar: + order: 1 +--- + +To get started with Angular Challenges, follow these steps: + +## Create a GitHub Account + +If you wish to submit an answer, you will need to have your own GitHub account. Additionally, having a GitHub account is always beneficial, and it's free. + +## Fork the GitHub project + +Navigate to the [Angular Challenges Repository](https://github.com/tomalaforge/angular-challenges) and click on the Fork button in the header. This will create a copy of this repository on your own GitHub profile. + +## Clone the repository to your local machine + +Select a directory on your local computer and clone this repository. + +Open a terminal, navigate to the chosen directory, and type the following command: + +```bash +git clone https://github.com/[YOUR_GITHUB_NAME]/angular-challenges.git +``` + +:::note +You can find the clone URL by clicking on the <> Code button in your own instance of the Angular Challenges repository. + +![Header of GitHub workspace](../../../assets/header-github.png) + +::: + +## Open the project in your favourite IDE + +Open the project in any IDE of your choice. + +## Install all dependencies + +```bash +npm ci +``` + +## Choose a challenge + +Your project is now up and running. The only remaining step is to choose a challenge 🚀 + +Each challenge consists of: + +- Name: indicating what the challenge is about. +- Number: order of creation. The number doesn't have any particular meaning but helps for reference in GitHub Pull Request section. +- Badge: helps visualize the degree of difficulty. It's entirely subjective 😅 + - 🟢 easy + - 🟠 medium + - 🔴 difficult + +## (Alternately) Use GitHub Codespaces + +From your own instance of the Angular Challenges repository, click the code button and navigate to the codespaces tab. + +![Codespaces tab](../../../assets/codespaces.png) + +Click the `Create codespace on main` button, and you will navigate to a GitHub codespace. + +If you never used a GitHub codespace before, I would recommend you try this short interactive [GitHub Skills Tutorial](https://github.com/skills/code-with-codespaces). + +When you navigate to the codespace, there will be a prompt to install the recommended `VS Code` plugins. If you plan on creating a challenge, you can use the `Nx plugin` to generate the starter code. Either way, the codespace will install the dependencies, and you can create a new branch, tackle any challenge, and create a pull request. + +When you push to a branch, you do not have to provide a GitHub token. + +Once you are finished, remember to pause or delete your codespace. If you don't, GitHub will automatically pause an idle codespace after 30 minutes. You do have a generous amount of free codespace time per month, but it is still important not to waste your allotment. + +In the GitHub codespace, copy and paste will be blocked until you give permission. + +The GitHub codespace uses port forwarding to serve the projects. Click the prompt after running `npx nx serve [project-name]` to navigate to `localhost:4200`. diff --git a/docs copy/src/content/docs/guides/rebase.md b/docs copy/src/content/docs/guides/rebase.md new file mode 100644 index 000000000..e91badfb6 --- /dev/null +++ b/docs copy/src/content/docs/guides/rebase.md @@ -0,0 +1,57 @@ +--- +title: Rebase your branch +description: Guide to rebase a branch to latest change +contributors: + - tomalaforge +sidebar: + order: 6 +--- + +Sometimes, changes may be added to the project. I'll attempt to make changes that won't break anything, but sometimes it's inevitable. + +Most of the time, you won't need to rebase your solution, but here is a guide to help you know how to do it. + +:::note +This guide is applicable to any Open Source Project. +::: + +## Steps to rebase your branch + +### Sync your repository + +First, you need to synchronize your fork to ensure it's up to date with the forked repository. + +You can achieve this by clicking the Sync fork button on the main page of your fork. + +![Sync project header](../../../assets/fork-sync.png) + +The image above shows that my branch is behind of the main branch by 8 commits, and I need to synchronize it to be up to date. + +![Sync project update modal](../../../assets/sync-fork-update.png) + +### Open a terminal + +Open any terminal of your choice, either the one from your favorite IDE or a standalone instance. + +### Git + +Follow the following commands to rebase your local branch: + +- git checkout main +- git pull +- git checkout [your branch] +- git rebase main +- Resolve Conflicts + +At this step, the rebase may stop because your local branch has conflicting files with the main branch. Correct them. After this is done: + +- git add . +- git rebase --continue + +If your branch doesn't have any conflicts, a success message will be shown. + +### Push your work back to the remote branch + +Finally, push your work back to GitHub: + +- git push -f diff --git a/docs copy/src/content/docs/guides/resolve-challenge.md b/docs copy/src/content/docs/guides/resolve-challenge.md new file mode 100644 index 000000000..0b30556a8 --- /dev/null +++ b/docs copy/src/content/docs/guides/resolve-challenge.md @@ -0,0 +1,105 @@ +--- +title: Resolve a Challenge +description: Guide to resolve a challenge +contributors: + - tomalaforge + - 1fbr + - gsgonzalez88 +sidebar: + order: 2 +--- + +In this guide, you will learn how to resolve a challenge and submit an answer to the main GitHub repository. + +## Introduction + +This repository is powered by [Nx](https://nx.dev/getting-started/intro). Nx is a monorepository that allows you to store multiple applications inside the same workspace. Each challenge is a separate application. If you open the `apps` directory, you will find multiple directories, each related to a specific challenge. Each directory represents a complete standalone `Nx` application. To run and start with one, open your terminal and run: + +```bash +npx nx serve +``` + +:::note +If you are unsure of your `APPLICATION_NAME`, open the README.md file. The `serve` command is written there, with a link to the challenge documentation. +::: + +:::note +If `nx` is installed globally on your device, you can skip using `npx`. + +To install `nx` globally, run + +```bash +npm i -g nx +``` + +::: + +## Create a Git Branch + +Before you start implementing your solution to resolve a challenge, create a git branch to commit your work. + +```bash +git checkout -b +``` + +## Resolve the Challenge + +Follow the instructions to resolve the challenge. + +## Commit and Push your Work + +The last step is to commit your work following the [Conventional Guidelines](https://www.conventionalcommits.org/en/v1.0.0/). + +Finally, push your work to the remote repository with the following command + +```bash + git push --set-upstream origin +``` + +:::tip[Don't remember it] +You don't have to remember the command precisely. You just need to remember `git push` and if it's the first time you are pushing this branch, `git` will provide you with the complete command. +::: + +## Submit your Work to the Main Repository + +Now, all your work is located insite your local instance of the Angular Challenges repository. + +The next step is to go to the main [Angular Challenges page](https://github.com/tomalaforge/angular-challenges) and create a new Pull Request. + +GitHub should display a notification header to help you create the pull request. + +If it's not the case, you either have done one of the previous steps incorrectly or you can go to the Pull Request tab and click the button New pull request. + +Once you have chosen the two branches to compare, you should arrive on the following page: + +![New pull request screen](../../../assets/new-pull-request.png) + +In the title section, start with Answer: followed by your challenge number. After that, you are free to add anything you would like. + +:::danger +This is very important. It lets others know which challenge you are attempting to resolve. +::: + +In the description section, you can add questions, troubles you encountered, or anything else you want to share. You can leave it empty if you don't have anything to say. + +You can now click on Create pull request. + +## Get a review + +To continue providing valuable feedback and reviews, support the project on Github: + +
    +
  • $5 per review
  • +
  • $25 for lifetime reviews
  • +
  • Create a challenge/Contribute for lifetime reviews
  • +
+ +:::note +You should still submit your PR to join the list of answered challenges. And you can still be reviewed by a community member. 🔥 + +Everyone is welcome to comment and read other PRs. 💪 +::: + +:::tip[OSS champion] +🔥 Once you have completed this tutorial, you are ready to contribute to any other public GitHub repository and submit a PR. It is as easy as that. 🔥 +::: diff --git a/docs copy/src/content/docs/index.mdx b/docs copy/src/content/docs/index.mdx new file mode 100644 index 000000000..85b774b73 --- /dev/null +++ b/docs copy/src/content/docs/index.mdx @@ -0,0 +1,85 @@ +--- +title: Welcome to Angular Challenges +description: Get started by resolving these challenges and become a better Angular Front-End engineer. +template: splash +noCommentSection: true +hero: + tagline: Start now and become an Angular Expert! + image: + file: ../../assets/angular-challenge.webp + actions: + - text: Get Started + link: /guides/getting-started/ + icon: right-arrow + variant: primary + - text: Go to the latest Challenge + link: /challenges/angular/59-content-projection-defer/ + icon: rocket + - text: Give a star + link: https://github.com/tomalaforge/angular-challenges + icon: github + variant: secondary +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; +import MyIcon from '../../components/MyIcon.astro'; + +import SubscriptionForm from '../../components/SubscriptionForm.astro'; + + + + This repository gathers 59 Challenges related to Angular, Nx, RxJS, Ngrx and Typescript. + These challenges resolve around real-life issues or specific features to elevate your skills. + + + + + + + + One of the goals of this repository is to lower the barrier to entry + for Open Source Software (OSS). By engaging with these challenges, you will + learn how to start contributing to any other open-source project. + + + + Learning and practicing a new framework is always challenging. This set of   + challenges provide real-world use cases to apply what you've been learning. + Anyone can comment or offer assistance. + + Learning alone is great, but learning alongside others will get you further. + + + + + Do you have an issue, an interesting bug, or an idea? Don't hesitate;{' '} + create your own challenges without wasting any time. + + + + By completing these challenges, you'll be ready for any technical questions + that may come up during a frontend job interview. + + + + This project is free and aims to remain so for as long as possible. However, everything is accomplished during my free time, including creating challenges and reviewing pull requests (PRs). Sponsorship can support me and contribute to the growth of the project. + + + +--- + + + + diff --git a/docs copy/src/content/docs/leaderboard/answers.mdx b/docs copy/src/content/docs/leaderboard/answers.mdx new file mode 100644 index 000000000..03a1f2a69 --- /dev/null +++ b/docs copy/src/content/docs/leaderboard/answers.mdx @@ -0,0 +1,13 @@ +--- +title: Challenges answered +description: leaderboard showing the number of challenges answered. +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardAnswer from '../../../components/leaderboard/LeaderboardAnswer.svelte'; + +Join the list and start your Angular Challenges journey by reading the [Getting Started](/guides/getting-started) guide. + + diff --git a/docs copy/src/content/docs/leaderboard/challenges.mdx b/docs copy/src/content/docs/leaderboard/challenges.mdx new file mode 100644 index 000000000..f5db034ba --- /dev/null +++ b/docs copy/src/content/docs/leaderboard/challenges.mdx @@ -0,0 +1,14 @@ +--- +title: Number of Challenges Created +description: leaderboard showing the number of challenges created. +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardChallenge from '../../../components/leaderboard/LeaderboardChallenge.svelte'; + +A challenge is missing, create your own one and get on the leaderboard! +Read the [Create Challenge](/guides/create-challenge) guide to learn how to create a challenge. + + diff --git a/docs copy/src/content/docs/leaderboard/commit.mdx b/docs copy/src/content/docs/leaderboard/commit.mdx new file mode 100644 index 000000000..1dcbbca6f --- /dev/null +++ b/docs copy/src/content/docs/leaderboard/commit.mdx @@ -0,0 +1,14 @@ +--- +title: Number of contributions +description: leaderboard showing the number of contributions. +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardCommit from '../../../components/leaderboard/LeaderboardCommit.svelte'; + +You want to improve the project, fix a typo, add some documentation to one challenges, or translate a page? This leaderboard shows the number of contributions per user. +This repository is open source and you can contribute to it. Read the [contribution](/guides/contribute) guide to get started. + + diff --git a/docs copy/src/content/docs/pt/challenges/angular/1-projection.md b/docs copy/src/content/docs/pt/challenges/angular/1-projection.md new file mode 100644 index 000000000..2dd44690e --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/1-projection.md @@ -0,0 +1,48 @@ +--- +title: 🟢 Projeção +description: Desafio 1 é sobre aprender a projetar elementos DOM através de componentes +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 1 +command: angular-projection +blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5 +videoLinks: + - link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq + alt: Projection video by Arthur Lannelucq + flag: FR + - link: https://www.youtube.com/watch?v=yNrfvu7vTa4 + alt: Projection video by Amos Lucian Isaila + flag: ES +sidebar: + order: 1 +--- + +## Informação + +Em Angular, projeção de conteúdo é uma técnica robusta para criar componente altamente personalizados. Usar e entender os conceitos do ng-content e ngTemplateOutlet pode melhorar significativamente sua habilidade na criação de componentes compartilháveis. + +Você pode aprender tudo sobre ng-content [aqui](https://angular.dev/guide/components/content-projection), desde projeção simples até casos mais complexos. + +Para aprender sobre ngTemplateOutlet, você pode acessar a documentação [aqui](https://angular.dev/api/common/NgTemplateOutlet) junto a alguns exemplos básicos. + +Com essas duas ferramentas em mãos, você está pronto para realizar o desafio. + +## Declaração + +Você começará com uma aplicação totalmente funcional que inclui um dashboard, que possui um cartão de professor e de estudante. O objetivo é implementar o cartão de cidade. + +Apesar da aplicação funcionar, a experiência do desenvolvedor (DX) está nem um pouco otimizada. Toda vez que você precisar implementar um novo cartão, você terá que modificar o `card.component.ts`. Em projetos reais, esse componente pode ser compartilhado entre várias aplicações. O objetivo do desafio é criar um `CardComponent` que possa ser personalizado sem nenhuma modificação. Uma vez criado o componente, você pode começar a implementar o `CityCardComponent` e assegurar que não mexerá no `CardComponent`. + +## Restrições + +- Você deve refatorar o `CardComponent` e `ListItemComponent`. +- A diretiva `NgFor` deve ser declarada e permanecer dentro do `CardComponent`. Você pode ficar instigado em querer mover ela para o `ParentCardComponent` como `TeacherCardComponent`. +- `CardComponent` não deve conter nenhum `NgIf` ou `NgSwitch`. +- CSS: tente evitar usar `::ng-deep`. Ache uma maneira melhor para lidar com o CSS. + +## Desafios Bônus + +- Tente trabalhar com a nova sintaxe nativa de controle de fluxo para laços e condicionais (documentação [aqui](https://angular.dev/guide/templates/control-flow)) +- Usa a signal API para gerenciar o estado de seus componentes (documentação [aqui](https://angular.dev/guide/signals)) +- Para referenciar o template, use uma diretiva ao invés de strings mágicas diff --git a/docs copy/src/content/docs/pt/challenges/angular/10-utility-wrapper-pipe.md b/docs copy/src/content/docs/pt/challenges/angular/10-utility-wrapper-pipe.md new file mode 100644 index 000000000..6b0135632 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/10-utility-wrapper-pipe.md @@ -0,0 +1,36 @@ +--- +title: 🔴 Pipe Empacotador de Utilidade +description: Desafio 10 é sobre a criação de um pipe para empacotar utilidades +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 10 +command: angular-utility-wrapper-pipe +sidebar: + order: 202 +--- + +## Informação + +Este é o terceiro de três desafios `@Pipe()`, sendo o objetivo dominar **pipes** em Angular. + +Pipes são uma maneira bem poderosa de transformar dados em seu template. A diferença entre chamar uma função e um pipe é que pipes puros são memoizados. Por isso, eles não são recalculados em cada ciclo de detecção de mudanças se suas entradas não mudarem. + +Pipes são eficientes e otimizados para performance. Eles usam mecanismos de detecção de mudanças para apenas recalcular o valor se sua entrada mudar, afim de minimizar cálculos desnecessários e melhorar a performance de renderização. + +Por padrão um pipe é puro, por isso você deve ter cuidado que ao configurar `pipe` como falso deixar mais propenso a ser ineficiente, uma vez que aumenta o número de renderizações. + +:::note[Nota] +Um pipe **puro** é chamado apenas quando o valor muda.\ +Um pipe **impuro** é chamado em cada ciclo da mudança de deteccção. +::: + +Há alguns pipes pré-definidos bem úteis como DatePipe, UpperCasePipe e CurrencyPipe. Para aprender mais sobre pipes em Angular, dê uma olhada na documentação da API [aqui](https://angular.dev/guide/pipes). + +## Declaração + +Neste exercício, você quer acessar algumas funções úteis. Atualmente você não consegue acessá-las diretamente do seu template. O objetivo é criar um pipe específico para o arquivo de úteis, e você precisará passar o nome da função que deseja chamar e os argumentos necessários. + +## Restrições + +- Deve ser fortemente tipado diff --git a/docs copy/src/content/docs/pt/challenges/angular/13-highly-customizable-css.md b/docs copy/src/content/docs/pt/challenges/angular/13-highly-customizable-css.md new file mode 100644 index 000000000..de0b96b45 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/13-highly-customizable-css.md @@ -0,0 +1,21 @@ +--- +title: 🟠 CSS Altamente Personalizável +description: Desafio 13 é sobre criar estilos CSS altamente personalizáveis +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 13 +command: angular-highly-customizable-css +sidebar: + order: 104 +--- + +## Informação + +Estilização é um aspecto importante do trabalho diário de um desenvolvedor frontend, mas é muitas vezes subestimado. Em aplicações Angular, eu frequentemente vejo pessoas usando `@Input()` para personalizar o estilo de seus componentes. No entanto, `@Input()` deve ser usado apenas para lógica. Outras técnicas, como **variáveis CSS** e **host-context** devem ser usadas para estilização. + +Neste desafio, você precisará usar tanto variáveis CSS como `:host-context` para remover todos `@Input()` de seu código. + +## Restrições + +- Na sua submissão final, seu componente não deve conter nenhuma linha de código. Toda a estilização deve ser manipulada dentro do decorador _(ou arquivos css externos se preferir)_ diff --git a/docs copy/src/content/docs/pt/challenges/angular/16-master-dependency-injection.md b/docs copy/src/content/docs/pt/challenges/angular/16-master-dependency-injection.md new file mode 100644 index 000000000..008e8b280 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/16-master-dependency-injection.md @@ -0,0 +1,28 @@ +--- +title: 🔴 Dominando Injeção de Dependência +description: Desafio 16 é sobre dominar como injeção de dependência funciona +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 16 +command: angular-master-dependency-injection +sidebar: + order: 203 +--- + +## Informação + +Para completar este desafio com sucesso, precisaremos ter um bom entendimento de como Injeção de Dependência funciona dentro do Angular. + +O objetivo é providenciar o `CurrencyService` no nível de linha, para que cada linha ilustre a moeda correta. Atualmente, `CurrencyService` é providenciado apenas em nível de tabela, o que resulta em um erro que mostrar a mesma moeda para cada linha, apesar de cada produto ter uma moeda diferente. + +Uma maneira de alcançar isso é adicionando um segundo argumento para o pipe, mas isso não é permitido para este desafio. + +## Declaração + +- Sua tarefa é mostrar a moeda correta para cada linha. + +## Restrições + +- Você não pode modificar o pipe. +- Você não pode envolver a linha dentro de um componente, uma vez que isso quebrará o layout. diff --git a/docs copy/src/content/docs/pt/challenges/angular/21-anchor-navigation.md b/docs copy/src/content/docs/pt/challenges/angular/21-anchor-navigation.md new file mode 100644 index 000000000..8ef34755e --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/21-anchor-navigation.md @@ -0,0 +1,20 @@ +--- +title: 🟢 Navegação por Âncora +description: Desafio 21 é sobre navegação dentro de uma página por âncora +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 21 +command: angular-anchor-navigation +sidebar: + order: 4 +--- + +## Informação + +Você começa com uma aplicação que tem uma navegação básica e navegação por âncora no `HomeComponent`. No entanto, usando `href` recria o caminho toda vez e recarrega a página. + +## Declaração + +- Sua tarefa é refatorar essa aplicação para usar a ferramenta nativa de navegação para melhor ajuste com o framework Angular. Você pode explorar o roteador, mas é melhor permanecer dentro do template e usar a diretiva `RouterLink`. +- Para melhorar a experiência do usuário, adicionar rolagem suave. diff --git a/docs copy/src/content/docs/pt/challenges/angular/22-router-input.md b/docs copy/src/content/docs/pt/challenges/angular/22-router-input.md new file mode 100644 index 000000000..ff24f96e3 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/22-router-input.md @@ -0,0 +1,28 @@ +--- +title: 🟢 @RouterInput() +description: Desafio 22 é sobre o uso do decorador @Input para recuperar parâmetros do roteador. +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 22 +command: angular-router-input +blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617 +sidebar: + order: 5 +--- + +## Informação + +Nesta aplicação, recuperamos 3 pedaços de informação, dentro do nosso `TestComponent`, providenciados pelo roteador: + +- Queremos recuperar `testId` encontrado nos parâmetros da URL. +- Queremos obter `user` localizado nos parâmetros query da URL. +- Queremos acessar `permission` atribuído no objeto `data` da rota. + +Na versão 15 ou mais recente do Angular, usamos `ActivatedRoute` para obter todas as informações e recebê-las através de observables para escutarmos mudanças na URL. + +Na versão 16, Angular introduziu um novo `Input` que pode ouvir os dados da rota. Você pode ler mais sobre [aqui](https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617). + +## Declaração + +O objetivo deste exercício é refatorar o código para usar a nova estratégia `RouterInput`. diff --git a/docs copy/src/content/docs/pt/challenges/angular/3-directive-enhancement.md b/docs copy/src/content/docs/pt/challenges/angular/3-directive-enhancement.md new file mode 100644 index 000000000..97541bc3d --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/3-directive-enhancement.md @@ -0,0 +1,48 @@ +--- +title: 🟠 Aprimoramento de Diretiva +description: Desafio 3 é sobre o aprimoramento de uma diretiva nativa +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 3 +command: angular-directive-enhancement +blogLink: https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c +sidebar: + order: 101 +--- + +:::note[Nota] +Este exercício pode ser obsoleto com o novo controle de fluxo e do bloco de empty state dentro do bloco `@for`. No entanto, **diretivas estruturais** não serão removidas tão cedo, por isso você ainda pode aprender bastante com este exercício. +::: + +## Informação + +Diretiva é uma ferramente poderosa oferecida pelo framework Angular. Você pode usar o princípio DRY compartilhando a lógica dentro de uma diretiva e aplicando ela em qualquer componente que quiser. + +Mas a verdadeira vantagem é que você consegue melhorar uma diretiva pré-existente que não **pertence** a você. + +## Declaração + +Neste exercício, queremos mostrar uma lista de pessoas. Se a lista está vazio, você deve mostrar _" the list is empty !! "_. + +Atualmente, temos: + +```typescript + +
+ {{ person.name }} +
+
+ The list is empty !! +``` + +Queremos nos livrar do `ng-container` escrevendo: + +```typescript +
+ {{ person.name }} +
+ The list is empty !! +``` + +Objetivo é **melhorar a diretiva ngFor**. diff --git a/docs copy/src/content/docs/pt/challenges/angular/31-module-to-standalone.md b/docs copy/src/content/docs/pt/challenges/angular/31-module-to-standalone.md new file mode 100644 index 000000000..e4878fd38 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/31-module-to-standalone.md @@ -0,0 +1,29 @@ +--- +title: 🟢 Módulo para Standalone +description: Desafio 31 é sobre migrar uma aplicação baseada em módulos para uma aplicação baseada em componentes standalone. +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 31 +command: angular-module-to-standalone +sidebar: + order: 6 +--- + +## Informação + +Em v14, componentes standalone foram lançados e foram estabilizados na v15. Se você ainda não brincou com eles, nunca é tarde. Você pode tentar neste desafio. + +Além disso, o objetivo é ver como **Nx** e **componentes standalone** trabalham juntos, e experimentar o processo de desacoplagem de sua aplicação com a biblioteca Nx e componentes standalone. + +Finalmente, componentes standalone são bem simples de entender, mas **componentes de roteameanto/lazy-loaded** podem ser um pouco difíceis de compreender. Este desafio permitirá manipular componentes em diferentes níveis de aninhamento e trabalhar com rotas carregadas preguiçosamente (lazy-loaded). + +Após completar este desafio, componentes standalone não serão mais segredo para você. + +## Declaração + +O objetivo deste desafio é migrar sua aplicação de componentes baseados em módulos para componentes standalone. + +## Nota + +Você também pode testar o [Angular schematic](https://angular.dev/reference/migrations/standalone) para migrar NgModule para componentes Standalone. _(Como estamos usando nx, comece seu comando com nx ao invés de ng)_ diff --git a/docs copy/src/content/docs/pt/challenges/angular/32-change-detection-bug.md b/docs copy/src/content/docs/pt/challenges/angular/32-change-detection-bug.md new file mode 100644 index 000000000..534a250f6 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/32-change-detection-bug.md @@ -0,0 +1,39 @@ +--- +title: 🟠 Bug na Detecção de Mudanças +description: Desafio 32 é sobre debuggar uma aplicação que tem um problema quando a detecção de mudanças é disparada +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 32 +command: angular-change-detection-bug +blogLink: https://medium.com/ngconf/function-calls-inside-template-are-dangerous-15f9822a6629 +sidebar: + order: 105 +--- + +:::note[Nota] +Este desafio é inspirado por um exemplo real que eu simplifiquei para criar um desafio legal. +::: + +## Informação + +Neste pequena aplicação, nós temos um menu de navegação que roteia nossa aplicação ou para `BarComponent` ou para `FooComponent`. No entanto, a aplicação não está carregando e os erros não são mostrado dentro do console. + +## Declaração + +O objetivo do desafio é debuggar a aplicação e fazer ela funcionar. + +## Dicas + +
+ Dica 1 + + Se você comentar `routerLinkActive="isSelected"` dentro de `NavigationComponent`, a aplicação carregará corretamente. +
+ +
+ Dica 2 + +Se você abrir o [código-fonte de `RouterLinkActive`](https://github.com/angular/angular/blob/main/packages/router/src/directives/router_link_active.ts) e ir na **linha 196**, verá que o Angular chama `this.cdr.markForCheck` dentro de uma microTask, na qual dispara um novo ciclo de detecção de mudanças (CD). Se você comentar essa linha, a aplicação carrega novamente, mas o bug não é dentro do framework Angular. 😅😯 + +
diff --git a/docs copy/src/content/docs/pt/challenges/angular/39-injection-token.md b/docs copy/src/content/docs/pt/challenges/angular/39-injection-token.md new file mode 100644 index 000000000..b6f4ae8e1 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/39-injection-token.md @@ -0,0 +1,36 @@ +--- +title: 🟠 InjectionToken +description: Desafio 39 é sobre o poder da injeção de dependência +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 39 +command: angular-injection-token +videoLinks: + - link: https://www.youtube.com/watch?v=ntggdQycFyc + alt: Injection Token by Arthur Lannelucq + flag: FR +sidebar: + order: 118 +--- + +## Informação + +Nesta pequena aplicação, começamos com um `VideoComponent` contendo um temporizador de **1-segundo**. O time de desenvolvimento decidiu usar uma constante global para armazenar o valor do temporizador: `DEFAULT_TIMER`. No entanto, algumas semanas depois, o time de produto quer adicionar uma nova tela para chamadas de celular nomeada `PhoneComponent`, e nós queremos reutilizar o `TimerComponent`. Entretanto, o time de produto quer um temporizador de **2-segundos**. Como conseguiremos isso? + +## Declaração + +Atualmente, o temporizador ainda é de 1 segundo para o `PhoneComponent`. O objetivo deste desafio é mudar o valor do temporizador para 2 segundos para o `PhoneComponent`. + +## Restrições + +O uso de `@Input` é proibido. O exemplo é básico e usar `@Input` pode ser uma boa opção, mas em aplicações mais complexas, o componente que precisamos atualizar pode estar profundamente aninhado, fazendo o uso de `@Input` um design bem ruim. + +## Dicas + +
+ Dica 1 + +Ler esta [postagem de blog](https://itnext.io/stop-being-scared-of-injectiontokens-ab22f72f0fe9) pode ser de grande ajuda. + +
diff --git a/docs copy/src/content/docs/pt/challenges/angular/4-typed-context-outlet.md b/docs copy/src/content/docs/pt/challenges/angular/4-typed-context-outlet.md new file mode 100644 index 000000000..63dff6a16 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/4-typed-context-outlet.md @@ -0,0 +1,45 @@ +--- +title: 🔴 ContextOutlet Tipado +description: Desafio 4 é sobre tipagem forte em diretivas ngContextOutlet +author: thomas-laforge +contributors: + - tomalaforge + - tomer953 + - svenson95 + - jdegand +challengeNumber: 4 +command: angular-typed-context-outlet +blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6 +sidebar: + order: 201 +--- + +## Informação + +Você pode melhorar a verificação de tipo do template para diretivas personalizadas adicionando guardas de propriedades de template na definição de sua diretiva. Angular oferece a função estática [`ngTemplateContextGuard`](https://angular.dev/guide/directives/structural-directives#improving-template-type-checking-for-custom-directives) para tipar fortemente diretivas estruturais. + +No entanto, o contexto do tipo do **NgTemplateOutlet** é **Object**. Mas com a a ajuda do guarda acima, podemos melhorar esse comportamento. + +## Declaração + +Neste exercício, queremos aprender como tipar fortemente nosso `ng-template` no `AppComponent`. + +Este exercício tem dois níveis de complexidade. + +### Nível 1: Interface Conhecida + +Atualmente nós temos o seguinte trecho de código. + +![Unkown Person](../../../../../assets/4/unknown-person.png 'Unkown Person') + +Como podemos ver, `name` é do tipo `any`. Queremos inferir o tipo correto usando a diretiva personalizada `PersonDirective`. + +### Level 2: Interface Genérica + +No momento presente, temos o seguinte trecho de código. + +![Unkown Student](../../../../../assets/4/unknown-student.png 'Unkown Student') + +Como podemos ver, `student` é do tipo `any`. Queremos inferir o tipo correto usando a diretiva personalizada `ListDirective`. + +Mas nesta parte, queremos passar uma lista de **qualquer objeto** para `LPersonistComponent`. E também queremos que o tipo correto seja inferido. diff --git a/docs copy/src/content/docs/pt/challenges/angular/44-view-transition.md b/docs copy/src/content/docs/pt/challenges/angular/44-view-transition.md new file mode 100644 index 000000000..b8b3e9bc5 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/44-view-transition.md @@ -0,0 +1,83 @@ +--- +title: 🔴 Transição de View +description: Desafio 44 você aprenderá a nova API para animação de transição de view +author: thomas-laforge +contributors: + - kabrunko-dev + - svenson95 +challengeNumber: 44 +command: angular-view-transition +sidebar: + order: 208 +--- + +## Informação + +Este é o segundo de três desafios animation, sendo o objetivo dominar animations em Angular. + +A View Transition API é uma nova API que fornece um conjunto de funcionalidades, permitindo desenvolvedores controlarem e manipularem as transições e animações entre views dentro de uma aplicação. +Isso tem um papel importante na melhoria da experiência do usuário (UX), trazendo vida a aplicações com transições atraentes e cativantes afim de guiar usuários por diferentes páginas e seções da aplicação. + +O objetivo deste desafio é aprender a manipular todos os tipos de transições propostas pela API. + +Para usar a API, Angular tem uma função `withViewTransitions()` que deve ser injetada dentro da configurações do roteador. + +Eu recomendaria a leitura da [documentação Chrome](https://developer.chrome.com/docs/web-platform/view-transitions). Você aprenderá tudo o que é necessário para completar o desafio com sucesso. + +Aqui, no entanto, um pequeno resumo: +Primeiramente, cada elemento DOM tem dois estados; um `old` para quando o elemento está deixando a página, e um `new` para quando está entrando na página: + +```css +::view-transition-old(root) { +/ / animação +} + +::view-transition-new(root) { +/ / animação +} +``` + +Para apontar um elemento em específico, você deve adicionar o seletor `view-transition-name` em uma classe CSS no nó DOM, como ilustrado abaixo: + +```css +.specific-element { + view-transition-name: specific-element; +} +``` + +Isso permite criar uma animação para aquele elemento apenas. + +Por último, se um mesmo elemento está presente em ambas as views, você pode automatizar a transição atribuindo o mesmo **nome da transição**. + +:::danger[Importante] +Lembre-se, você pode ter apenas UM ÚNICO `view-transition-name` por página. +::: + +## Declaração + +O objetivo deste desafio é realizar a transição entre os estados mostrados no vídeo abaixo: + + + +Para o estado final mostrado no vídeo seguinte: + + + +Observe os pontos: + +- O cabeçalho desliza para dentro e para fora +- Cada elemento transiciona suavemente para sua nova localização + +### Nível 1 + +Foque apenas no primeiro thumbnail e crie uma transição agradável e transparente + +### Nível 2 + +Crie a mesma transição atraente para todos os thumbnails, mas sem duplicar o `view-transition-name`. Note que a página tem apenas 3 thumbnails; em um cenário real, você pode ter muito mais. + +### Nível 3 + +Mude para a localização Y correta quando navegando para frente e para trás entre as páginas. diff --git a/docs copy/src/content/docs/pt/challenges/angular/45-react-in-angular.md b/docs copy/src/content/docs/pt/challenges/angular/45-react-in-angular.md new file mode 100644 index 000000000..a7fa38654 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/45-react-in-angular.md @@ -0,0 +1,76 @@ +--- +title: 🔴 React em angular +description: Desafio 5 é sobre aprender como se beneficiar das várias bibliotecas em React +author: wandrille-guesdon +contributors: + - tomalaforge 45 +command: angular-react-in-angular +sidebar: + order: 209 +--- + +O objetivo deste desafio é usar um componente React dentro de uma aplicação Angular. + +Muitos componentes estão disponíveis em React, e pode ser interessante usar eles em uma aplicação Angular. O objetivo é criar um componente React e usar em uma aplicação Angular. + +## Informação + +Neste desafio temos uma simples aplicação e um componente React `ReactPost` em `app/react` para ilustrar um componente React de uma biblioteca. + +## Declaração + +- Sua tarefa é mostrar as postagens com o componente React `ReactPost`. +- Quando selecionar uma postagem, a postagem deve ser destacada. + +Para brincar com o componente React, você deve começar instalando as dependências do React. + +```bash +npm i --save react react-dom +npm i --save-dev @types/react @types/react-dom +``` + +## Restrições + +- Não transforme o componente React em um componente Angular. O componente React é bem simples e pode ser escrito facilmente em Angular. No entanto, o **objetivo é usar o componente React**. + +### Dica + +
+ Dica 1 - Configuração + Permita arquivos React no tsconfig.json + +``` +{ +... +"compilerOptions": { + ... + "jsx": "react" +}, +... +} +``` + +
+ +
+ Dica 2 - Initialização + Crie uma raiz react com `createRoot(...)` +
+ +
+ Dica 3 - Visualização + Para renderizar o componente, ele deve parecer com: + ``` + .render( + + ... + + ) + ``` + +
+ +
+ Dica 4 - Design + Não esqueça de permitir o arquivo react no Tailwind. +
diff --git a/docs copy/src/content/docs/pt/challenges/angular/46-simple-animations.md b/docs copy/src/content/docs/pt/challenges/angular/46-simple-animations.md new file mode 100644 index 000000000..2ef7e1760 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/46-simple-animations.md @@ -0,0 +1,56 @@ +--- +title: 🟢 Animações Simples +description: Desafio 46 é sobre aprender a API de animação integrada do Angular +author: sven-brodny +contributors: + - svenson95 +challengeNumber: 46 +command: angular-simple-animations +sidebar: + order: 17 +--- + +## Informação + +Este é o primeiro de dois desafios de animação, o objetivo desta série é dominar animações no Angular. + +Animações bem desenhadas pode fazer sua aplicação mais divertida e direta para usar, mas elas não são apenas comésticas. Animações pode melhorar sua aplicação e a experiência do usuário de várias maneiras: + +- Sem animações, transições de página web podem parecer abruptas e desagradáveis. +- Movimento aumenta bastante a experiência do usuário, uma vez que animações dão a usuários a change de detectar as respostas da aplicação para suas ações. +- Boas animações intuitivamente chama a atenção do usuário para onde é necessário. + +Eu recomendaria você ler a [documentação oficial](https://angular.dev/guide/animations) Você aprenderá tudo o que é necessário para completar o desafio com sucesso. + +Caso contrário, olhe este [exemplo funcional](https://svenson95.github.io/ng-xmp-animations/) e o [repositório git](https://github.com/svenson95/ng-xmp-animations) para se inspirar. + +## Declaração + +O objetivo deste desafio é adicionar animações, elas devem executar quando o usuário acessa a página ou a recarrega. + +## Restrições + +- Não use nenhum CSS e use a API integrada do Angular `@angular/animations`. +- Não dispare as animações com um botão como nos exemplos, mas quando o usuário entrar ou recarregar a página. + +### Nível 1 + +Adicionar uma animação de movimento e fading para os parágrados no lado esquerdo. + + + +### Nível 2 + +Adicionar uma animação cambaleante para a lista no lado direito. + + + + + + + + diff --git a/docs copy/src/content/docs/pt/challenges/angular/5-crud-application.md b/docs copy/src/content/docs/pt/challenges/angular/5-crud-application.md new file mode 100644 index 000000000..3c6a04fda --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/5-crud-application.md @@ -0,0 +1,52 @@ +--- +title: 🟢 Aplicação Crud +description: Desafio 5 é sobre refatorar uma aplicação crud is about refactoring a crud application +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 5 +command: angular-crud-application +sidebar: + order: 2 +--- + +## Informação + +Comunicar e ter um estado global/local em sincronia com seu backend é o coração de qualquer aplicação. Você necessitará dominar as seguintes melhores práticas para construir aplicações Angular fortes e confiáveis. + +## Declaração + +Neste exercício, você tem uma pequena aplicação CRUD, que tem uma lista de TODOS, atualiza e exclui alguns todos. + +Atualmente temos um exemplo funcional, mas cheio de más práticas. + +### Passo 1: refatorar com melhores práticas + +O que você precisará: + +- Evite **any** como um tipo. Use Interface para aproveitar o sistema de tipos do Typescript para evitar erros +- Use um **serviço separado** para todas suas chamadas http e use um **Signal** para sua lista de todos +- Não **mute** em seus dados + +```typescript +// Evite isto +this.todos[todoUpdated.id - 1] = todoUpdated; + +// Prefira algo assim, mas precisa melhorar, porque queremos manter a mesma ordem. +this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]; +``` + +### Passo 2: Melhore + +- Adicione um botão **Deletar**: _Documentação de API falsa_ +- Lide com **erros** corretamente. _(Globalmente)_ +- Adicione um indicador de **carregamento** global. _Você pode usar MatProgressSpinnerModule_ + +### Passo 3: Manutenibilidade!! adicione alguns testes + +- Adicione 2/3 testes + +### Step 4: Incrível!!! domine seu estado. + +- Use o **componente store do ngrx**, **ngrx/store**, **rxAngular**, **tanstack-query** ou **ngrx/signal-store** como estado local de seu componente. +- Tenha um indicador de carregamento/erro **localizado**, e.g. apenas no Todo sendo processado e **desabilite** todos os botões do Todo processado. _(Dica: você precisará criar um ItemComponent)_ diff --git a/docs copy/src/content/docs/pt/challenges/angular/6-structural-directive.md b/docs copy/src/content/docs/pt/challenges/angular/6-structural-directive.md new file mode 100644 index 000000000..f8607b06d --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/6-structural-directive.md @@ -0,0 +1,61 @@ +--- +title: 🟠 Diretiva Estrutural +description: Desafio 6 é sobre criar uma diretiva estrutural para manipular permissões +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 6 +command: angular-structural-directive +blogLink: https://medium.com/@thomas.laforge/create-a-custom-structural-directive-to-manage-permissions-like-a-pro-11a1acad30ad +sidebar: + order: 102 +--- + +## Informação + +Diretiva estrutural é um conceito importante que você necessita dominar para melhorar suas habilidades e conhecimentos angular. Isso será a primeira parte deste desafio. + +Guarda é também muito importante uma vez que você sempre precisará em cada aplicação que construir. + +## Declaração + +Em LoginComponent, você encontrará 6 botões correspondentes para 6 diferentes funções de usuário. + +:::note[Nota] +Deixaram-se os nomes das funções em inglês. +::: + +- Admin (Administrador) +- Manager (Gerente) +- Reader (Leitor) +- Writer (Escritor) +- Reader and Writer (Leitor e Escritor) +- Client (Cliente) +- Everyone (Todos) + +## Passo 1 + +Em `InformationComponent`, precisa mostrar a informação correta para cada função usando uma diretiva estrutural. + +### Restrições + +- sem `ngIf` ou `@if` dentro de `InformationComponent` +- importart a store dentro de `InformationComponent` não é permitido. + +Você deve terminar com algo semelhante com o código abaixo: + +```html +
Info for Role1
+``` + +```html +
Info for Role1 and Role2
+``` + +```html +
Info Only for superadmin
+``` + +## Passo 2 + +Em `Routes.ts`, você deve rotear todos os usuários para o `DashboardComponent` correto usando a guarda `CanMatch`. diff --git a/docs copy/src/content/docs/pt/challenges/angular/8-pure-pipe.md b/docs copy/src/content/docs/pt/challenges/angular/8-pure-pipe.md new file mode 100644 index 000000000..65dea73d8 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/8-pure-pipe.md @@ -0,0 +1,37 @@ +--- +title: 🟢 Pipe Puro +description: Desafio 8 é sobre criar um pipe puro +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 8 +command: angular-pure-pipe +blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d +sidebar: + order: 3 +--- + +## Informação + +Este é o primeiro de três desafios `@Pipe()`, sendo o objetivo dominar **pipes** em Angular. + +Pipes são uma maneira bem poderosa de transformar dados em seu template. A diferença entre chamar uma função e um pipe é que pipes puros são memoizados. Por isso, eles não são recalculados em cada ciclo de detecção de mudanças se suas entradas não mudarem. + +Pipes são eficientes e otimizados para performance. Eles usam mecanismos de detecção de mudanças para apenas recalcular o valor se sua entrada mudar, afim de minimizar cálculos desnecessários e melhorar a performance de renderização. + +Por padrão um pipe é puro, por isso você deve ter cuidado que ao configurar `pipe` como falso deixar mais propenso a ser ineficiente, uma vez que aumenta o número de renderizações. + +:::note[Nota] +Um pipe **puro** é chamado apenas quando o valor muda.\ +Um pipe **impuro** é chamado em cada ciclo da mudança de deteccção. +::: + +Há alguns pipes pré-definidos bem úteis como DatePipe, UpperCasePipe e CurrencyPipe. Para aprender mais sobre pipes em Angular, dê uma olhada na documentação da API [aqui](https://angular.dev/guide/pipes). + +## Declaração + +Neste exercício, você precisa refatorar uma função de transformação dentro de um componente, o qual é chamado dentro de seu template. O objetivo é converter essa função em um pipe. + +## Restrições + +- Deve ser fortemente tipado diff --git a/docs copy/src/content/docs/pt/challenges/angular/9-wrap-function-pipe.md b/docs copy/src/content/docs/pt/challenges/angular/9-wrap-function-pipe.md new file mode 100644 index 000000000..c72b7b463 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/angular/9-wrap-function-pipe.md @@ -0,0 +1,37 @@ +--- +title: 🟠 Pipe Empacotador de Função +description: Challenge 9 is about creating a pipe to wrap component fonctions +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 9 +command: angular-wrap-function-pipe +blogLink: https://medium.com/ngconf/boost-your-apps-performance-by-wrapping-your-functions-inside-a-pipe-7e889a901d1d +sidebar: + order: 103 +--- + +## Informação + +Este é o segundo de três desafios `@Pipe()`, sendo o objetivo dominar **pipes** em Angular. + +Pipes são uma maneira bem poderosa de transformar dados em seu template. A diferença entre chamar uma função e um pipe é que pipes puros são memoizados. Por isso, eles não são recalculados em cada ciclo de detecção de mudanças se suas entradas não mudarem. + +Pipes são eficientes e otimizados para performance. Eles usam mecanismos de detecção de mudanças para apenas recalcular o valor se sua entrada mudar, afim de minimizar cálculos desnecessários e melhorar a performance de renderização. + +Por padrão um pipe é puro, por isso você deve ter cuidado que ao configurar `pipe` como falso deixar mais propenso a ser ineficiente, uma vez que aumenta o número de renderizações. + +:::note[Nota] +Um pipe **puro** é chamado apenas quando o valor muda.\ +Um pipe **impuro** é chamado em cada ciclo da mudança de deteccção. +::: + +Há alguns pipes pré-definidos bem úteis como DatePipe, UpperCasePipe e CurrencyPipe. Para aprender mais sobre pipes em Angular, dê uma olhada na documentação da API [aqui](https://angular.dev/guide/pipes). + +## Declaração + +Neste exercício, você está chamando várias funções dentro de seu template. Você pode criar um pipe específico para cada uma das funções, mas isso dará muito trabalho. O objetivo é criar um pipe `wrapFn` que empacote sua função callback através do pipe. Sua função DEVE permanecer dentro do seu componentes. **`WrapFn` deve ser reutilizável**. + +## Restrições + +- Deve ser fortemente tipado diff --git a/docs copy/src/content/docs/pt/challenges/forms/41-control-value-accessor.md b/docs copy/src/content/docs/pt/challenges/forms/41-control-value-accessor.md new file mode 100644 index 000000000..cad37f205 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/forms/41-control-value-accessor.md @@ -0,0 +1,43 @@ +--- +title: 🟠 Control Value Accessor +description: Desafio 41 é sobre criar um controle personalizado de formulário que implemente a interface Control Value Accessor. +author: stanislav-gavrilov +contributors: + - kabrunko-dev +challengeNumber: 41 +command: forms-control-value-accessor +sidebar: + order: 1 +--- + +## Informação + +Neste desafio, o objetivo é criar um campo personalizado de formulário que use a Form API do Angular `ControlValueAccessor`. Você pode achar a documentação [aqui](https://angular.dev/api/forms/ControlValueAccessor). A interface é crucial para criar controles personalizados de formulário que interaja de forma transparente com a API dos formulários do Angular. + +## Declaração + +O objetivo principal é usar controle no `feedbackForm` para eliminar a necessidade de uso do `@Output` afim de recuperar o valor e injetar ele no `FormGroup`. +Além disso, você é obrigado a integrar validação para o novo controle afim de assegurar que os dados de avaliação existam. (O botão de submissão do formulário deve ser desabilitado se o formulário é inválido). + +Atualmente, a avaliação é programada desta maneira: + +```html + +``` + +```ts +rating: string | null = null; + +onFormSubmit(): void { + this.feedBackSubmit.emit({ + ...this.feedbackForm.value, + rating: this.rating, // fora do FormGroup e sem validação + }); +} +``` + +O objetivo é incluir a avaliação no `FormGroup` + +```html + +``` diff --git a/docs copy/src/content/docs/pt/challenges/rxjs/38-rxjs-catch-error.md b/docs copy/src/content/docs/pt/challenges/rxjs/38-rxjs-catch-error.md new file mode 100644 index 000000000..8d9d6fc4c --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/rxjs/38-rxjs-catch-error.md @@ -0,0 +1,35 @@ +--- +title: 🟢 catchError +description: Desafio 38 é sobre aprender conclusão de observable +author: devesh-chaudhari +command: rxjs-catch-error +contributors: + - kabrunko-dev +challengeNumber: 38 +sidebar: + order: 14 +--- + +## Informação + +### Como usar a aplicação + +Nossa aplicação possui um formulário com um input textual e um botão "Fetch". Ao clicar o botão, dados são requeridos de uma [API gratuita](https://jsonplaceholder.typicode.com/). + +Os valores aceitos para requisições de sucesso estão limitados em: posts, comments, albums, photos, todos, and users. Qualquer outro valor, resultará em erro na requisição. + +### Bug + +Um bug foi identificado na nossa aplicação. Usuários conseguem apenas recuperar dados até uma requisição fracassar. Quando uma requisição retorna com erro, os usuários não conseguem mais enviar outras requisições. + +### Aprendizados + +Esta aplicação providencia uma oportunidade de entender onde colocar o operador [`catchError`](https://rxjs.dev/api/operators/catchError) corretamente. Se colocado de forma incorreta, a inscrição será completada, impedindo usuários de enviar mais requisições. O objetivo é preservar a inscrição através do manuseio dos erro nos observables internos de forma apropriada. + +## Declaração + +O objetivo é usar o operator catchError para lidar com o gerenciamento de erro dentro do seu fluxo de dados Rxjs. + +## Restrições + +Usuários devem ser aptos para logar o valor/erro cada vez que clicam o botão "Fetch". diff --git a/docs copy/src/content/docs/pt/challenges/signal/30-interop-rxjs-signal.md b/docs copy/src/content/docs/pt/challenges/signal/30-interop-rxjs-signal.md new file mode 100644 index 000000000..b70f54d17 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/signal/30-interop-rxjs-signal.md @@ -0,0 +1,21 @@ +--- +title: 🔴 Interoperabilidade Rxjs/Signal +description: Desafio 30 é sobre aprender como misturar signal com Rxjs +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 30 +command: signal-interop-rxjs-signal +sidebar: + order: 204 +--- + +## Informação + +Neste desafio, temos uma pequena aplicação reativa que usa **RxJs** e **NgRx/Component-Store**. + +O objetivo deste desafio é usar a nova **API Signal** introduzida no Angular v16. No entanto, não devemos converter tudo. Certas parte do código são mais adequadas com RxJS do que Signal. É sua decisão determinar o limite e observar como **Signal e RXJS coexistem**, além de como a interoperabilidade é feita no Angular. + +## Nota + +- Você pode usar qualquer biblioteca de terceiros se quiser, como **ngrx/signal-store**, **tanstack-query** ou **rxAngular**. diff --git a/docs copy/src/content/docs/pt/challenges/signal/43-signal-input.md b/docs copy/src/content/docs/pt/challenges/signal/43-signal-input.md new file mode 100644 index 000000000..810175b34 --- /dev/null +++ b/docs copy/src/content/docs/pt/challenges/signal/43-signal-input.md @@ -0,0 +1,53 @@ +--- +title: 🟢 Signal Input +description: Desafio 43 é sobre como usar signal inputs +author: thomas-laforge +contributors: + - kabrunko-dev +challengeNumber: 43 +command: signal-signal-input +sidebar: + order: 16 +--- + +## Informação + +Finalmente, o dia chegou quando o time Angular introduziu um input reativo. Essa funcionalidade bastante requisitada é esperada há anos. A versão 17.1 introduz `SignalInput`. Ao invés de utilizar o velho conhecido decorador `@Input`, agora você tem uma função que retorna um signal. + +```ts +// jeito antigo +@Input() age?: number; + +// novo jeito +age = input() +``` + +Se você quiser inputs obrigatórios + +```ts +// jeito antigo +@Input({required: true}) age!: number; + +// novo jeito +age = input.required() +``` + +Se você queria obter um signal de um input, você tinha que usar um setter para configurar seu signal a partir de um input. + +```ts +// jeito antigo +age = signal(0) +@Input({alias: 'age'}) set _age(age: number){ + this.age.set(age) +}; + +// novo jeito +age = input() +``` + +## Declaração + +Nesta pequena aplicação, o objetivo é refatorar o `UserComponent` para utilizar `SignalInput`. + +- Você tem inputs obrigatórios e opcionais. +- Você pode usar a função `transform` para o input `age` e converter a propriedade diretamente para um número. diff --git a/docs copy/src/content/docs/pt/guides/checkout-answer.md b/docs copy/src/content/docs/pt/guides/checkout-answer.md new file mode 100644 index 000000000..309f413b7 --- /dev/null +++ b/docs copy/src/content/docs/pt/guides/checkout-answer.md @@ -0,0 +1,50 @@ +--- +title: Verifique a resposta dos outros +description: Guia para verificar a resposta de outra pessoa +contributors: + - kabrunko-dev +sidebar: + order: 3 +--- + +Todas as respostas do Desafios Angular são apresentadas na forma de Pull Request (PR). Para ver e seguir elas, navegue pela página **Files Changes** no GitHub. Entretanto, entender e seguir esse processo pode não ser direto se você não estiver familiarizado com a interface. Muitas vezes, você pode preferir verificar a branch e revisar a solução na sua IDE de preferência. + +Este guia foi criado para ajudar você a conseguir isso. + +## Confire PR de outra pessoa localmente + +### Sincronize seu repositório + +Primeiro, você precisa sincronizar seu fork para garantir que ele está atualizado com o repositório bifurcado. + +Isso pode ser feito clicando no botão Sync fork na página principal de seu fork. + +![Sync project header](../../../../assets/fork-sync.png) + +A imagem acima mostra que minha branch está atrás da branch principal por 8 commits, e será necessário sincronizá-la para deixar ela atualizada. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Confira localmente + +Vá até o PR que desejar conferir localmente e pegue seu ID. Você o achará no título do PR (como mostrado abaixo). + +![PR header](../../../../assets/PR-header.png) + +Depois, abra um terminal dentro do diretório de seu projeto e execute o seguinte comando: + +```bash +gh pr checkout +``` + +Se você não lembrar o comando, clique no butão <> Code no lado direito do cabeçalho e você poderá copiar/colar o comando. + +![PR code modal](../../../../assets/PR-code-btn-modal.png) + +:::note[Nota] +Se o comando não funcionar ou fracassar, a CLI do GitHub vai guiar você durante o processo. +::: + +🔥 Agora você pode navegar nas soluções localmente e rodá-las para testar. 🔥 + + diff --git a/docs copy/src/content/docs/pt/guides/contribute.md b/docs copy/src/content/docs/pt/guides/contribute.md new file mode 100644 index 000000000..729f7c5db --- /dev/null +++ b/docs copy/src/content/docs/pt/guides/contribute.md @@ -0,0 +1,22 @@ +--- +title: Contribua +description: Guia para contribuir +contributors: + - kabrunko-dev +sidebar: + order: 4 +--- + +Você pode contribuir para este repositório das seguintes maneiras: + +🔥 Criar um novo desafio seguindo as instruções [aqui](/pt/guides/create-challenge). + +🔥 Responder desafios e submeter sua resposta (guia [aqui](/pt/guides/resolve-challenge)). + +🔥 Comentar as soluções de outras pessoas dando feedback construtivo e solidário. + +🔥 Corrigindo erros de digitação (typos) ou erros de inglês na documentação. + +🔥 Enviar um problema (issue) para sugerir novas ideias de desafios ou reportar um bug. + +🔥 Patrocinar o projeto [aqui](https://github.com/sponsors/tomalaforge). diff --git a/docs copy/src/content/docs/pt/guides/create-challenge.md b/docs copy/src/content/docs/pt/guides/create-challenge.md new file mode 100644 index 000000000..d7c39db66 --- /dev/null +++ b/docs copy/src/content/docs/pt/guides/create-challenge.md @@ -0,0 +1,56 @@ +--- +title: Crie seu próprio desafio +description: Guia para criar seu próprio desafio +contributors: + - kabrunko-dev +sidebar: + order: 5 +--- + +Você tem uma ideia que gostaria de compartilhar, um bug interessante que você está batendo a cabeça em um de seus projetos pessoais ou um truque no Angular que você descobriu. Todas essas possibilidades são um bom ponto de partida para criar um desafio e compartilhar a solução com as outras pessoas. + +Mas como você pode criar esses desafios? + +## Código Boilerplate + +Para simplificar o processo, criei um gerador Nx que configurará todo código boilerplate para você começar mais rápido. A maneira mais fácil de rodar o código, é usando o console Nx: vá para Nx Console > generate > @angular-challenges/cli - challenge + +### Parâmetros + +#### parâmetros obrigatórios + +- title: O título que você deseja dar para seu desafio. + :::note[Nota] + O título deve ter no máximo 25 caracteres. + ::: + +- challengeDifficulty: A dificuldade que você acredita que o desafio tem. Têm três níveis de dificuldade: 🟢 fácil / 🟠 médio / 🔴 difícil +- name: nome da aplicação Nx. + :::note[Nota] + Deve ser escrito em **kebab-case**. + ::: +- docRepository: A categoria do seu desafio: Nx, Angular, Angular Performance, Rxjs, NgRx, Typescript. + +#### parâmetros opcionais + +- directory: Se você quiser que sua aplicação esteja localizada dentro de uma pasta específica de `apps`. +- addTest: Se você quer adicionar configuração de testes. + +### O que é criado + +- O gerador criará todos os arquivos necessários para ter uma nova aplicação funcional. Todos esses arquivos serão criado dentro de `apps/${directory}/${name}` +- Um arquivo Markdown com uma configuração mínima será criado dentro de `docs/src/content/docs/challenges/${docRepository}` + +## Criação do Desafio + +A única coisa que falta é criar seu desafio. 🚀 + +:::danger[Importante] +Não esqueça de atualizar a documentação para introduzir seu desafio e providenciar suas instruções. +::: + +É sua vez de agir!!! 💪 + +## Submissão da Solução + +Depois de uma semana mais ou menos, não esqueça de providenciar sua solução para seu desafio. diff --git a/docs copy/src/content/docs/pt/guides/faq.md b/docs copy/src/content/docs/pt/guides/faq.md new file mode 100644 index 000000000..af4505f40 --- /dev/null +++ b/docs copy/src/content/docs/pt/guides/faq.md @@ -0,0 +1,19 @@ +--- +title: FAQ +description: Respostas para perguntas +contributors: + - kabrunko-dev +sidebar: + order: 7 +--- + +
+ Por que minha aplicação não roda ou por que eu encontro erros no meu terminal quando executo `nx serve`? + + Na maioria das vezes, o problema surge por que seu `node_modules` está desatualizado e você precisa atualizá-lo executando o comando `npm ci`. + +Se a instalação fracassar, você pode resolver deletando o diretório `node_modules` através do comando `rm -rf node_modules` ou `npx npkill`, e depois executar `npm ci` novamente. + +Se o problema persistir, por favor reporte ele [aqui](https://github.com/tomalaforge/angular-challenges/issues/new). + +
diff --git a/docs copy/src/content/docs/pt/guides/getting-started.md b/docs copy/src/content/docs/pt/guides/getting-started.md new file mode 100644 index 000000000..57e501bd6 --- /dev/null +++ b/docs copy/src/content/docs/pt/guides/getting-started.md @@ -0,0 +1,59 @@ +--- +title: Começando +description: Um guia de como começar com Desafios Angular. +contributors: + - kabrunko-dev +sidebar: + order: 1 +--- + +Para começar com Desafios Angular, siga os seguintes passos: + +## Crie uma conta GitHub + +Se você desejar submeter uma resposta, será necessário ter uma conta pessoal no GitHub. Além disso, ter uma conta GitHub é sempre benéfico e é de graça. + +## Crie um fork do projeto GitHub + +Navegue para o [reposítório do Desafios Angular](https://github.com/tomalaforge/angular-challenges) e clique no botão Fork no cabeçalho. Isso criará uma cópia do repositório no seu GitHub pessoal. + +## Clone o repositório para sua máquina local + +Escolha um diretório/pasta no seu computador e clone o repositório. + +Abra um terminal, navegue até a pasta selecionada e digite o comando: + +```bash +git clone https://github.com/[SEU_NOME_GITHUB]/angular-challenges.git +``` + +:::note[Nota] +Você pode achar a URL para clonar clicando no botão <> Code na sua própria instância do repositório do Desafios Angular. + +![Header of GitHub workspace](../../../../assets/header-github.png) + +::: + +## Abra o projeto na sua IDE favorita + +Abra o projeto em uma IDE de sua escolha. + +## Instale todas dependências + +```bash +npm ci +``` + +## Escolha um desafio + +O seu projeto está pronto e funcional. O que falta agora é escolher um desafio 🚀 + +Cada desafio consiste em: + +- Nome: indica sobre o que o desafio é. +- Número: ordem de criação. O número não tem nenhum significado, mas ajuda na referência para a seção de Pull Request no GitHub. +- Indicador: ajuda a visualizar o grau de dificuldade. É totalmente subjetivo 😅 + - 🟢 fácil + - 🟠 médio + - 🔴 difícil diff --git a/docs copy/src/content/docs/pt/guides/rebase.md b/docs copy/src/content/docs/pt/guides/rebase.md new file mode 100644 index 000000000..d4bf356d1 --- /dev/null +++ b/docs copy/src/content/docs/pt/guides/rebase.md @@ -0,0 +1,57 @@ +--- +title: Rebase sua branch +description: Guia para realizar rebase em uma branch e atualizá-la com as mudanças mais recentes +contributors: + - kabrunko-dev +sidebar: + order: 6 +--- + +De tempos em tempos, mudanças podem ser adicionadas no projeto. Eu tentarei fazer mudanças que não quebrem nada, mas algumas vezes é inevitável. + +Na maioria das vezes, você não precisará fazer rebase na sua solução, mas aqui está um guia para ajudar em como fazer isso. + +:::note[Nota] +Este guia é aplicável para qualquer Projeto de Código Aberto. +::: + +## Passos para fazer rebase na sua branch + +### Sincronize seu repositório + +Primeiro, você precisa sincronizar seu fork para garantir que está tudo atualizado com o repositório bifurcado. + +Você pode fazer isso clicando no botão Sync fork na página principal de seu fork. + +![Sync project header](../../../../assets/fork-sync.png) + +A imagem acima mostra que minha branch está atrás da branch principal por 8 commits e eu preciso sincronizar para atualizar ela com as mudanças mais recentes. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Abra um terminal + +Abra um terminal de sua escolha, pode ser tanto na sua IDE favorita ou uma instância independente. + +### Git + +Siga os seguintes comandos para realizar um rebase na sua branch local: + +- git checkout main +- git pull +- git checkout [sua branch] +- git rebase main +- Resolva Conflitos + +Neste passo, o rebase pode parar, porque sua branch local tem arquivos conflitantes com a branch principal. Corrija-os e depois disso feito: + +- git add . +- git rebase --continue + +Se sua branch não tem nenhum conflito, uma mensagem de sucesso será mostrada. + +### Faça um Push do seu trabalho para a branch remota + +Por último, faça um push do seu trabalho de volta para o GitHub: + +- git push -f diff --git a/docs copy/src/content/docs/pt/guides/resolve-challenge.md b/docs copy/src/content/docs/pt/guides/resolve-challenge.md new file mode 100644 index 000000000..a36369183 --- /dev/null +++ b/docs copy/src/content/docs/pt/guides/resolve-challenge.md @@ -0,0 +1,101 @@ +--- +title: Resolva um desafio +description: Guia de como resolver um desafio +contributors: + - kabrunko-dev +sidebar: + order: 2 +--- + +Neste guia, você aprenderá como resolver um desafio e submeter uma resposta para o repositório principal no GitHub. + +## Introdução + +Este repositório é feito com [Nx](https://nx.dev/getting-started/intro). Nx é um monorepositório que permite armazenar múltiplas aplicações dentro de um mesmo espaço de trabalho. Cada desafio é uma aplicação separada. Se você abrir o diretório `apps`, achará várias pastas, sendo cada uma relacionada a um desafio específico. Cada diretório representa um aplicação `Nx` completa e independente. Para executar e começar uma aplicação, abra seu terminal e use: + +```bash +npx nx serve +``` + +:::note[Nota] +Se você não tem certeza quanto ao `NOME_APLICACAO`, abra o arquivo README.md do desafio. O comando `serve` está escrito nele com um link para a documentação do desafio. +::: + +:::note[Nota] +Se `nx` está instalado globalmente no seu dispositivo, você pode pular o uso de `npx`. + +Para instalar `nx` globalmente, execute: + +```bash +npm i -g nx +``` + +::: + +## Crie uma branch Git + +Antes de começar a implementação de sua solução para um desafio, crie uma branch para commitar seu trabalho. + +```bash +git checkout -b +``` + +## Resolva o Desafio + +Siga as instruções para resolver o desafio. + +## Commitar e fazer o _Push_ do seu trabalho + +O último passo é commitar seu trabalho seguindo o [Conventional Guidelines](https://www.conventionalcommits.org/en/v1.0.0/). + +Finalmente, faça um push do trabalho ao repositório remoto com o seguinte comando: + +```bash +git push --set-upstream origin +``` + +:::tip[Não precisa lembrar disso] +Você não precisa lembrar do comando. Você pode simplemente lembrar do `git push` e, se é a primeira vez que você faz um push na branch, `git` fornecerá para você o comando completo. +::: + +## Submeta seu Trabalho no Repositório Principal + +Agora, todo seu trabalho está localizado dentro de sua instância local do repositório do Desafios Angular. + +O próximo passo é ir para a [página principal do Desafios Angular](https://github.com/tomalaforge/angular-challenges) e criar um novo Pull Request. + +GitHub deve mostrar no cabeçalho uma notificação para ajudar a criação do pull request. + +Se não mostrar, você pode ter feito um dos passos anteriores errado ou você pode ir para a aba Pull Request e clicar no botão New pull request. + +Uma vez escolhidas as duas branches para comparar, você deve ser redirecionado para a seguinte página: + +![New pull request screen](../../../../assets/new-pull-request.png) + +Na seção do título, comece com Answer: seguido pelo número do desafio. Depois, você está livre para adicionar o que você desejar. + +:::danger[Importante] +Isso é muito importante. Isso deixará as outras pessoas saberem qual desafio você tentou resolver. +::: + +Na seção de descrição, você pode adicionar perguntas, problemas que encontrou ou qualquer coisa que queira compartilhar. Você pode deixar vazio caso não tenha nada para dizer. + +Agora você pode clicar em Create pull request. + +## Receber um Feedback + +Para continuar brindando comentarios y reseñas valiosas, ahora solo revisaré a aquellos que apoyen el proyecto en GitHub. + +
    +
  • $5 por reseña
  • +
  • $25 por reseñas de por vida
  • +
  • Crea un desafío/Contribuye para revisiones de por vida
  • +
+ +:::note[Nota] +Todo mundo é bem-vindo para comentar e ver outros PRs. +::: + +:::tip[Campeão OSS] +🔥 Ao terminar este tutorial, você está pronto para contribuir em qualquer outro repositório público do GitHub e submeter um PR. Simples assim. 🔥 +::: diff --git a/docs copy/src/content/docs/pt/index.mdx b/docs copy/src/content/docs/pt/index.mdx new file mode 100644 index 000000000..d2670bbc4 --- /dev/null +++ b/docs copy/src/content/docs/pt/index.mdx @@ -0,0 +1,97 @@ +--- +title: Bem-vindos aos Desafios Angular +description: Comece resolvendo esses desafios e se torne um melhor desenvolvedor frontend Angular. +template: splash +noCommentSection: true +hero: + tagline: Comece agora e vire um especialista em Angular! + image: + file: ../../../assets/angular-challenge.webp + actions: + - text: Iniciar + link: /pt/guides/getting-started/ + icon: right-arrow + variant: primary + - text: Ir para o desafio mais recente + link: /pt/challenges/angular/59-content-projection-defer/ + icon: rocket + - text: Dar uma estrela + link: https://github.com/tomalaforge/angular-challenges + icon: github + variant: secondary +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; +import MyIcon from '../../../components/MyIcon.astro'; +import SubscriptionForm from '../../../components/SubscriptionForm.astro'; + + + + Este repositório possui 59 Desafios relacionados a Angular, Nx, RxJS, + Ngrx e Typescript. + Esses desafios são voltados para problemas reais ou funcionalidades específicas afim de + melhorar suas habilidades. + + +{' '} + + + + + +{' '} + + + Um dos objetivos desse repositório é diminuir a barreira de entrada + para o Software de Código Aberto (OSS). Ao realizar esses desafios, você + aprenderá como começar a contruibuir em qualquer outro Projeto de Código + Aberto. + + +{' '} + + + Aprender e praticar um novo framework é sempre desafiador. Este conjunto de + desafios possui casos de uso reais para aplicarmos o que aprendemos. Qualquer + um pode comentar e oferecer assistência. + + Aprender sozinho é legal, mas aprender junto com outras pessoas levará você + mais longe. + + + +{' '} + + + Tem algum problema, um bug interessante ou uma ideia? Não hesite; + crie seus próprios desafios sem perder tempo. + + +{' '} + + + Completar esses desafios vai preparar você para quaisquer desafios técnicos + que encontrar em uma entrevista para uma vaga frontend. + + + + Este projeto é livre e tem o objetivo de permanecer assim o máximo possível. No entanto, + tudo é feito durante meu tempo livre, incluindo a criação de desafios e revisão de pull requests (PRs). + Patrocinar pode me ajudar e contribuir para o crescimento do projeto. + + + +--- + + + + diff --git a/docs copy/src/content/docs/pt/leaderboard/answers.mdx b/docs copy/src/content/docs/pt/leaderboard/answers.mdx new file mode 100644 index 000000000..c2302d3cf --- /dev/null +++ b/docs copy/src/content/docs/pt/leaderboard/answers.mdx @@ -0,0 +1,13 @@ +--- +title: Desafios respondidos +description: tabela de classificação mostrando o número de desafios respondidos. +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardAnswer from '../../../../components/leaderboard/LeaderboardAnswer.svelte'; + +Junte-se a lista e comece sua jornada Desafios Angular lendo o guia [Começando](/pt/guides/getting-started). + + diff --git a/docs copy/src/content/docs/pt/leaderboard/challenges.mdx b/docs copy/src/content/docs/pt/leaderboard/challenges.mdx new file mode 100644 index 000000000..2209af5e0 --- /dev/null +++ b/docs copy/src/content/docs/pt/leaderboard/challenges.mdx @@ -0,0 +1,14 @@ +--- +title: Número de Desafios Criados +description: tabela de classificação mostrando o número de desafios criados. +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardChallenge from '../../../../components/leaderboard/LeaderboardChallenge.svelte'; + +Um desafio está faltando, crie seu próprio e entre para a tabela de classificação. +Leia o guia [Crie seu próprio desafio](/pt/guides/create-challenge) para aprender como criar um desafio. + + diff --git a/docs copy/src/content/docs/pt/leaderboard/commit.mdx b/docs copy/src/content/docs/pt/leaderboard/commit.mdx new file mode 100644 index 000000000..2a7695905 --- /dev/null +++ b/docs copy/src/content/docs/pt/leaderboard/commit.mdx @@ -0,0 +1,14 @@ +--- +title: Número de contribuições +description: tabela de classificação mostrando o número de contribuições. +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardCommit from '../../../../components/leaderboard/LeaderboardCommit.svelte'; + +Quer melhorar o projeto, consertar um erro de digitação, adicionar alguma documentação para um desafio ou traduzir uma página? Esta tabela de classificação mostra o número de contribuição por usuário. +Este repositório é de código aberto e você pode contribuir. Leia o guia [Contribua](/pt/guides/contribute) para começar. + + diff --git a/docs copy/src/content/docs/ru/challenges/angular/1-projection.md b/docs copy/src/content/docs/ru/challenges/angular/1-projection.md new file mode 100644 index 000000000..3ff9c2ea9 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/1-projection.md @@ -0,0 +1,48 @@ +--- +title: 🟢 Проекция контента +description: Challenge 1 заключается в изучении проекции элементов DOM через компоненты +author: thomas-laforge +contributors: + - stillst +challengeNumber: 1 +command: angular-projection +blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5 +videoLinks: + - link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq + alt: Projection video by Arthur Lannelucq + flag: FR + - link: https://www.youtube.com/watch?v=yNrfvu7vTa4 + alt: Projection video by Amos Lucian Isaila + flag: ES +sidebar: + order: 1 +--- + +## Информация + +Проекция контента в Angular - это мощная техника для создания компонентов с гибко настраиваемым внешним видом. Понимание и использование концепций ng-content и ngTemplateOutlet может значительно вам помочь создавать компоненты, предназначенные для повторного использования. + +[Здесь](https://angular.dev/guide/components/content-projection) вы можете изучить все о ng-content, начиная с простых примеров и до более сложных. + +Документацию ngTemplateOutlett, вместе с базовыми примерами, можно найти [тут](https://angular.dev/api/common/NgTemplateOutlet). + +Имея эти два инструмента в своем распоряжении, вы теперь готовы пройти испытание. + +## Пояснение + +Вы начнете с полностью работающего приложения, которое включает панель с карточкой учителя и карточкой студента. Цель состоит в том, чтобы реализовать карточку города. + +Хотя приложение работает, его внутреннее устройство далеко от идеала. Каждый раз, когда вам нужно реализовать новую карточку, вам придется изменять `card.component.ts`. В реальных проектах этот компонент может использоваться во многих приложениях. Цель этого упражнения создать `CardComponent`, внешний вид которого можно настроить без каких-либо изменений. После того как вы создадите этот компонент, вы можете создать `CityCardComponent` без модификации `CardComponent`. + +## Ограничения + +- Вы должны провести рефакторинг `CardComponent` и `ListItemComponent`. +- Директива `NgFor` должна быть определена и должна оставаться внутри `CardComponent`, несмотря на возможное желание перенести её в `ParentCardComponent`,как это сделано в `TeacherCardComponent`. +- `CardComponent` не должен содержать `NgIf` или `NgSwitch`. +- CSS: избегайте использования `::ng-deep`. Ищите альтернативные способы стилизации с помощью CSS. + +## Дополнительные задачи + +- Попробуйте использовать новый синтаксис для циклов и условий (документация [тут](https://angular.dev/guide/templates/control-flow)). +- Используйте signal API для управления состоянием компонентов (документация [тут](https://angular.dev/guide/signals)). +- Для ссылки на шаблон используйте директивы вместо магических строк ([What is wrong with magic strings?](https://softwareengineering.stackexchange.com/a/365344)). diff --git a/docs copy/src/content/docs/ru/challenges/angular/21-anchor-navigation.md b/docs copy/src/content/docs/ru/challenges/angular/21-anchor-navigation.md new file mode 100644 index 000000000..cfcf035c3 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/21-anchor-navigation.md @@ -0,0 +1,20 @@ +--- +title: 🟢Навигация по якорю +description: Испытание 21 про навигацию на странице с помощью якоря +author: thomas-laforge +contributors: + - stillst +challengeNumber: 21 +command: angular-anchor-navigation +sidebar: + order: 4 +--- + +## Информация + +Вы начинаете с приложения, которое имеет базовую навигацию и навигацию с использованием якорей в `HomeComponent`. Однако, использование `href` каждый раз создает новый путь и обновляет страницу. + +## Пояснение + +- Ваша задача - рефакторинг этого приложения для использования встроенного инструмента навигации, для более эффективной работы в рамках фреймворка Angular. Вы можете использовать router, но лучше остаться в шаблоне и использовать `RouterLink` директиву. +- Для улучшения пользовательского опыта, добавьте плавную прокрутку. diff --git a/docs copy/src/content/docs/ru/challenges/angular/22-router-input.md b/docs copy/src/content/docs/ru/challenges/angular/22-router-input.md new file mode 100644 index 000000000..5d1a3e78e --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/22-router-input.md @@ -0,0 +1,28 @@ +--- +title: 🟢 @RouterInput() +description: Задача 22 заключается в использовании декоратора @Input для получения параметров маршрутизатора. +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 22 +command: angular-router-input +blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617 +sidebar: + order: 5 +--- + +## Информация + +В этом приложении мы извлекаем три фрагмента информации внутри нашего `TestComponent`, предоставленного маршрутизатором: + +- Мы хотим получить `testId` найденный внутри параметров URL. +- Мы хотим получить `user` расположенный в параметрах запроса URL. +- Мы хотим получить доступ к `permission`, установленному внутри объекта `data` маршрута. + +В Angular версиях 15 или более ранних мы используем `ActivatedRoute` для получения всей этой информации и получаем их через observables для прослушивания изменений URL. + +В версии 16 Angular представил новый `Input`, который может прослушивать данные маршрута. Вы можете прочитать больше об этом [здесь](https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617). + +## Пояснение + +Целью этого упражнения является рефакторинг кода для использования новой стратегии `RouterInput`. diff --git a/docs copy/src/content/docs/ru/challenges/angular/31-module-to-standalone.md b/docs copy/src/content/docs/ru/challenges/angular/31-module-to-standalone.md new file mode 100644 index 000000000..ae90ba492 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/31-module-to-standalone.md @@ -0,0 +1,29 @@ +--- +title: 🟢 Module к Standalone компоненту +description: Задача 31 заключается в переносе приложения с компонентов основанных на модулях на автономные компоненты (standalone). +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 31 +command: angular-module-to-standalone +sidebar: + order: 6 +--- + +## Информация + +В версии 14 были выпущены автономные компоненты, а в версии 15 они стали стабильными. Если вы еще не игрались с ними, никогда не поздно начать. Вы можете попробовать их в этом испытании. + +Более того, цель состоит в том, чтобы увидеть, как **Nx** и **автономные компоненты(standalone)** работают вместе, и понять процесс разделения вашего приложения с помощью Nx lib и автономных компонентов. + +Наконец, автономные компоненты очень просты для понимания, но **маршрутизация/компоненты с отложенной загрузкой** могут быть немного сложнее для понимания. Эта задача позволит вам манипулировать компонентами на разных уровнях вложенности и работать с маршрутами с отложенной загрузкой. + +После выполнения этого задания автономные компоненты больше не будут хранить для вас никаких секретов. + +## Пояснение + +Цель этой задачи - перенести ваше приложение с компонентов, основанных на модулях, на автономные компоненты. + +## Примечание + +Вы также можете протестировать [Angular schematic](https://angular.dev/reference/migrations/standalone) для переноса NgModule на автономные компоненты. _(Поскольку мы используем nx, начните свою команду с nx вместо ng)_ diff --git a/docs copy/src/content/docs/ru/challenges/angular/4-typed-context-outlet.md b/docs copy/src/content/docs/ru/challenges/angular/4-typed-context-outlet.md new file mode 100644 index 000000000..7ff155e61 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/4-typed-context-outlet.md @@ -0,0 +1,42 @@ +--- +title: 🔴 Типизация ContextOutlet +description: Испытание 4 про строгую типизацию ngContextOutlet директивы +author: thomas-laforge +contributors: + - stillst +challengeNumber: 4 +command: angular-typed-context-outlet +blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6 +sidebar: + order: 201 +--- + +## Информация + +В Angular есть статическая функция [`ngTemplateContextGuard`](https://angular.dev/guide/directives/structural-directives#improving-template-type-checking-for-custom-directives) для строгой типизации структурных директив. + +Однако, контекстом **NgTemplateOutlet** является **Object**. Но с помощью вышеупомянутой гарда, мы можем улучшить это поведение. + +## Пояснение + +В этом испытании, мы хотим научиться строго типизировать ng-template в AppComponent. + +Это упражнение имеет два уровня сложности: + +### Уровень 1: Известный интерфейс + +Сейчас код выглядит следующим образом. + +![Unkown Person](../../../../../assets/4/unknown-person.png 'Unkown Person') + +Как мы видим, у переменной name тип "any". Мы хотим вывести правильный тип. + +### Уровень 2: Обобщённый интерфейс + +Сейчас код выглядит следующим образом. + +![Unkown Student](../../../../../assets/4/unknown-student.png 'Unkown Student') + +Как мы видим, у переменной student тип "any". Мы хотим вывести правильный тип. + +Но на этот раз, мы хотим передавать в `ListComponent` список из любых объектов. И мы все равно хотим, чтобы был выведен правильный тип. diff --git a/docs copy/src/content/docs/ru/challenges/angular/46-simple-animations.md b/docs copy/src/content/docs/ru/challenges/angular/46-simple-animations.md new file mode 100644 index 000000000..04d143c0f --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/46-simple-animations.md @@ -0,0 +1,48 @@ +--- +title: 🟢 Простые Анимации +description: Задача 46 заключается в изучении animation API интегрированного в Angular +author: sven-brodny +contributors: + - webbomj +challengeNumber: 46 +command: angular-simple-animations +sidebar: + order: 17 +--- + +## Информация + +Это первое из двух заданий по анимации, цель этой серии - освоить анимацию в Angular. + +Хорошо продуманная анимация может сделать ваше приложение более увлекательным и простым в использовании. Анимация может улучшить ваше приложение и пользовательский опыт несколькими способами: + +- Без анимации переходы между веб-страницами могут казаться резкими и раздражающими. +- Движение значительно улучшает взаимодействие с пользователем, поэтому анимация дает возможность определить реакцию приложения на действия пользователей. +- Хорошая анимация интуитивно привлекает внимание пользователя к тому месту, где это необходимо. + +Я бы порекомендовал вам ознакомиться с [официальной документацией](https://angular.dev/guide/animations). Вы узнаете все, что необходимо для успешного прохождения испытания. + +В противном случае посмотрите на этот [рабочий пример](https://svenson95.github.io/ng-xmp-animations/) и [git repo](https://github.com/svenson95/ng-xmp-animations), чтобы вдохновиться. + +## Пояснение + +Цель этой задачи - добавить анимацию, она должна запускаться, когда пользователь заходит на страницу или перезагружает страницу. + +## Constraints + +- Не используйте никакой CSS и используйте интегрированный в Angular API `@angular/animations`. +- Не запускайте анимацию кнопкой, как в примерах, запускайте когда пользователь заходит на страницу или перезагружает ее. + +### Уровень 1 + +Добавьте анимацию затухания или перемещения для абзацев с левой стороны. + + + +### Уровень 2 + +Добавьте пошаговую (stagger) анимацию для списка справа. + + diff --git a/docs copy/src/content/docs/ru/challenges/angular/5-crud-application.md b/docs copy/src/content/docs/ru/challenges/angular/5-crud-application.md new file mode 100644 index 000000000..ae25d5c51 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/5-crud-application.md @@ -0,0 +1,52 @@ +--- +title: 🟢 Crud приложение +description: Задача 5 посвящена рефакторингу crud-приложения +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 5 +command: angular-crud-application +sidebar: + order: 2 +--- + +## Информация + +Взаимодействие и синхронизация глобального/локального состояния с вашей серверной частью - это основа любого приложения. Вам необходимо освоить следующие рекомендации для создания надежных приложений на Angular. + +## Обзор + +В этом упражнении у вас есть небольшое CRUD приложение, которое получает список задач (TODOS), обновляет и удаляет некоторые задачи. + +В настоящее время у нас есть работающий пример, но он наполнен множеством плохих практик. + +### Шаг 1: рефакторинг с учетом лучших практик + +Что вам нужно будет сделать: + +- Избегайте **any** в качестве типа. Использование интерфейсов Typescript предотвращает ошибки +- Используйте **отдельную службу** для всех ваших http-запросов и используйте **Signal** для вашего списка задач +- Не **изменяйте** данные (пример ниже) + +```typescript +// Избегайте этого +this.todos[todoUpdated.id - 1] = todoUpdated; + +// Предпочитаю что-то вроде этого кода, но он нуждается в улучшении, потому что мы все еще хотим тот же порядок в списке +this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]; +``` + +### Шаг 2: Улучшаем + +- Добавьте кнопку **Delete**: _Документация к fake API_ +- Обработайте **ошибки** правильно. _(Глобально)_ +- Добавьте глобальный **loading** индикатор загрузки. _Вы можете использовать MatProgressSpinnerModule_ + +### Шаг 3: Удобство в обслуживании!! Добавьте немного тестов + +- Добавьте 2/3 тестов + +### Шаг 4: Благоговение!!! овладейте своим состоянием. + +- Используйте **component store of ngrx**, **ngrx/store**, **rxAngular**, **tanstack-query** или **ngrx/signal-store** как локальное состояние вашего компонента. +- Добавьте **локальный** индикатор Loading/Error, например, только для обрабатываемого Todo и **отключите (disable)** все кнопки обрабатываемого Todo. _(Подсказка: вам нужно будет создать ItemComponent)_ diff --git a/docs copy/src/content/docs/ru/challenges/angular/52-lazy-load-component.md b/docs copy/src/content/docs/ru/challenges/angular/52-lazy-load-component.md new file mode 100644 index 000000000..a0697c784 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/52-lazy-load-component.md @@ -0,0 +1,50 @@ +--- +title: 🟢 Ленивая загрузка компонента +description: Испытание 52 посвящено изучению ленивой загрузки компонентов в Angular. +author: lance-finney +contributors: + - LMFinney + - stillst +challengeNumber: 52 +command: angular-lazy-load-component +sidebar: + order: 21 + badge: Новое +--- + +## Информация + +В Angular уже давно существует механизм для ленивой загрузки модулей на основе маршрутов, но ленивая загрузка отдельных компонентов была намного сложнее. Это испытание посвящено изучению того, как лениво загружать компоненты при помощи новой фичи, которая появилась в Angular 17. + +## Пояснение + +Это простое приложение отображает `TopComponent`, который, по нашим предположениям, замедлил бы работу приложения, если бы был частью начального пакета (хотя на самом деле он содержит лишь немного текста, но мы притворяемся, что он замедляет приложение). + +В текущем решении `PlaceholderComponent` отображается до тех пор, пока пользователь не нажмет кнопку для показа `TopComponent`. Однако, несмотря на то что `TopComponent` не виден до нажатия на кнопку, он все равно загружается вместе с начальным пакетом. + +Используйте новую фичу Angular 17 для ленивой загрузки `TopComponent`, чтобы он загружался и отображался только после нажатия пользователем кнопки. + +Когда вы закончите, вы увидите, что браузер загружает `TopComponent` в отдельном пакете после нажатия на кнопку для его отображения. В Chrome вы можете увидеть это, открыв DevTools, перейдя на вкладку "Network", и нажав кнопку для отображения `TopComponent`. + +## Подсказки + +
+ Подсказка 1 + +Вы должны иметь возможность удалить сигнал `topLoaded`, когда закончите. + +
+ +
+ Подсказка 2 + +Новая фича Angular скроет `TopComponent` из вида, но он все равно будет загружаться в начальном пакете, если вы не измените способ определения `AppComponent`, и `TopComponent` в их декораторах. Эта задача начинается со старой архитектуры на основе `NgModule`, но вам нужно будет изменить ее, чтобы использовать новую фичу. + +
+ +
+ Подсказка 3 + +Новая фича - это [Отложенные представления (Deferrable Views)](https://angular.dev/guide/defer). Фича предлагает несколько триггеров. Один из них идеально подходит для этой задачи. + +
diff --git a/docs copy/src/content/docs/ru/challenges/angular/8-pure-pipe.md b/docs copy/src/content/docs/ru/challenges/angular/8-pure-pipe.md new file mode 100644 index 000000000..182262de6 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/angular/8-pure-pipe.md @@ -0,0 +1,37 @@ +--- +title: 🟢Чистый пайп +description: Испытание 8 про создание чистого пайпа +author: thomas-laforge +contributors: + - stillst +challengeNumber: 8 +command: angular-pure-pipe +blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d +sidebar: + order: 3 +--- + +## Информация + +Это первое испытание про `@Pipe()` из трех, цель этой серии испытаний - освоить работу с **pipes** в Angular. + +Пайпы - удобный способ трансформации данных в вашем шаблоне. Разница между вызовом функции и пайпом заключается в том, что результат, возвращаемый чистыми пайпами, кэшируется. Таким образом, они не будут пересчитываться при каждом цикле обнаружения изменений, если их входные значения не изменились. + +Pipes разработаны так, чтобы быть эффективными и оптимизированными для производительности. Они используют механизмы обнаружения изменений, чтобы пересчитывать значение только в случае изменения входных данных, минимизируя ненужные вычисления и улучшая производительность рендеринга. + +По умолчанию пайпы чистые, но вы должны знать, что установка `pure` в false может привести к неэффективности, поскольку это увеличивает количество перерисовок. + +:::note[Примечание] +**Чистые** пайп вызывается только когда изменяется входное значение.\ +**Нечистый** пайп вызывается на каждый цикл обнаружения изменений. +::: + +Существуют несколько полезных предопределенных пайпов, таких как DatePipe, UpperCasePipe и CurrencyPipe. Чтобы узнать больше о пайпах в Angular, ознакомьтесь с документацией API [здесь](https://angular.dev/guide/pipes). + +## Пояснение + +В этом упражнении необходимо превратить вызов функции в шаблоне в использование пайпа. + +## Ограничение + +- Пайп должен быть типизирован. diff --git a/docs copy/src/content/docs/ru/challenges/forms/41-control-value-accessor.md b/docs copy/src/content/docs/ru/challenges/forms/41-control-value-accessor.md new file mode 100644 index 000000000..00f898f4f --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/forms/41-control-value-accessor.md @@ -0,0 +1,43 @@ +--- +title: 🟠 Control Value Accessor +description: Испытание 41 про создание пользовательское поле формы которое использует интерфейс ControlValueAccessor. +author: stanislav-gavrilov +contributors: + - stillst +challengeNumber: 41 +command: forms-control-value-accessor +sidebar: + order: 1 +--- + +## Информация + +Цель этого испытания создать пользовательское поле формы, которое использует API формы Angular через `ControlValueAccessor`. Документацию можно посмотреть [здесь](https://angular.dev/api/forms/ControlValueAccessor). Этот интерфейс критически важен для создания пользовательских элементов управления формами, которые могут беспрепятственно взаимодействовать с API форм Angular. + +## Пояснение + +Задача - использовать контрол в `feedbackForm` напрямую, чтобы убрать необходимость в использовании `@Output` для получения значения из `app-rating-control` и установки его в `FormGroup`. +Кроме того, вы должны добавить валидацию для нового элемента управления, чтобы гарантировать наличие данных о рейтинге. (Кнопка отправки формы должна быть отключена, если форма недействительна). + +Сейчас компонент рейтинга используется следующим образом: + +```html + +``` + +```ts +rating: string | null = null; + +onFormSubmit(): void { + this.feedBackSubmit.emit({ + ...this.feedbackForm.value, + rating: this.rating, // not inside the FormGroup and no validation + }); +} +``` + +Необходимо, чтобы компонент можно было использовать так: + +```html + +``` diff --git a/docs copy/src/content/docs/ru/challenges/performance/12-optimize-change-detection.md b/docs copy/src/content/docs/ru/challenges/performance/12-optimize-change-detection.md new file mode 100644 index 000000000..e79736be9 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/performance/12-optimize-change-detection.md @@ -0,0 +1,40 @@ +--- +title: 🟠 Оптимизация обнаружения изменений +description: Задание 12 посвящено оптимизации количества циклов обнаружения изменений при прокрутке +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 12 +command: performance-optimize-change-detection +sidebar: + order: 107 +--- + +## Информация + +В Angular есть библиотека под названием Zone.js, которая выполняет множество магии, чтобы упростить жизнь разработчика. Zone.js монкипатчит все события DOM, чтобы перепроверить и перерисовать представление, когда что-то изменилось внутри приложения. Разработчику не нужно вручную запускать обнаружение изменений. + +Однако иногда Zone.js вызывает гораздо больше обнаружения изменений, чем это необходимо. Например, когда вы прослушиваете событие прокрутки, каждое событие прокрутки вызывает новый цикл обнаружения изменений. + +В этом испытании нам нужно обновлять представление только в определенной позиции прокрутки, чтобы показать или скрыть кнопку. Все остальные циклы избыточны. + +Чтобы лучше понять проблему, выполните профилирование вашего приложения с помощью Angular Dev Tools. + +:::note +Если вы не знаете, как это сделать, сначала прочтите [введение в производительность](/challenges/performance/). +::: + +Вы можете узнать больше деталей о загрязнении зон и способах его решения [здесь](https://angular.dev/best-practices/zone-pollution). + +В следующем видео более подробно объясняется проблема этого приложения. + + + +## Утверждение + +Ваша цель в этом испытании - избежать всех избыточных циклов обнаружения изменений и запускать обнаружение изменений только при необходимости. + +## Ограничение: + +Вы не можете глобально отключить Zone.js. Если этот код является частью большого проекта и вы отключите Zone.js, вы без сомнения сломаете ваше приложение. diff --git a/docs copy/src/content/docs/ru/challenges/performance/34-default-vs-onpush.md b/docs copy/src/content/docs/ru/challenges/performance/34-default-vs-onpush.md new file mode 100644 index 000000000..44f3be442 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/performance/34-default-vs-onpush.md @@ -0,0 +1,57 @@ +--- +title: 🟢 Default vs OnPush +description: Задача 34 заключается в изучении разницы между стратегией обнаружения изменений Default и OnPush. +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 34 +command: performance-default-vs-onpush +sidebar: + order: 7 +--- + +## Информация + +В этом задании мы рассмотрим различия и последствия использования `ChangeDetectionStrategy.Default` в сравнении с `ChangeDetectionStrategy.OnPush`. + +Вы можете прочитать [Angular документацию](https://angular.dev/best-practices/skipping-subtrees) чтобы узнать больше о различиях между этими стратегиями. + +В этом задании все компоненты начинаются со стратегии `Default`. Когда вы вводите буквы в поле ввода, вы заметите, что все компоненты выделены оранжевым цветом. + +:::note[Заметка] +Я добавил цветовую подсветку к каждому компоненту и каждой строке, чтобы обеспечить лучшую визуализацию при повторном отображении компонента. +::: + +Как вы можете видеть, каждая буква запускает новый цикл обнаружения изменений, и все компоненты перерисовываются, что вызывает проблемы с производительностью. + +Давайте воспользуемся Angular DevTool для профилирования нашего приложения и поймем, как этот инструмент может помочь нам понять, что происходит внутри нашего приложения. + +:::note[Заметка] +Если вы не знаете, как им пользоваться, прочтите [страницу введения в производительность](/challenges/performance/) сначала и возвращайся. +::: + +Теперь начните профилировать свое приложение и введите несколько букв в поле ввода, чтобы запустить несколько циклов обнаружения изменений. + +Если вы нажмете на одну из полос (обозначенную желтой стрелкой на рисунке ниже), вы можете увидеть, что на `PersonListComponent`, `RandomComponent` и все `MatListItem` влияет цикл обнаружения изменений, даже когда мы взаимодействуем только с полем ввода. + +![profiler record](../../../../../assets/performance/34/profiler-record.png 'Profiler Record') + +## Пояснение + +Цель этой задачи состоит в том, чтобы улучшить кластеризацию обнаружения изменений в приложении, используя стратегию обнаружения изменений "OnPush", но не только... + +## Подсказки: + +
+ Подсказка 1 + +Используйте `ChangeDetectionStrategy.OnPush` но этого будет не достаточно. + +
+ +
+ Подсказка 2 + +Создайте компоненты меньшего размера, чтобы лучше отделить поле ввода от списка. + +
diff --git a/docs copy/src/content/docs/ru/challenges/performance/35-memoization.md b/docs copy/src/content/docs/ru/challenges/performance/35-memoization.md new file mode 100644 index 000000000..5240262d3 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/performance/35-memoization.md @@ -0,0 +1,50 @@ +--- +title: 🟢 Мемоизация +description: Задача 35 заключается в изучении того, как работает чистые pipe +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 35 +command: performance-memoization +sidebar: + order: 8 +--- + +## Информация + +В Angular чистые каналы очень эффективны, потому что значение запоминается, что означает, что если входное значение не изменяется, функция "преобразования" канала не вычисляется повторно, а выводится кэшированное значение. + +Вы можете узнать больше о каналах в [документации Angular](https://angular.dev/guide/pipes) и в этой [статье о глубоком погружении в pipes](https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d). + +В этом задании мы начнем с кнопки для загрузки списка людей. Каждый человек связан с числом, и мы будем использовать вычисление Фибоначчи для создания сложных вычислений, которые замедлят работу приложения. + +Как только список будет загружен, попробуйте ввести несколько букв в поле ввода. Вы заметите, что приложение работает очень медленно, даже несмотря на то, что вы выполняете только самый простой набор текста. + +:::note[Примечание] +В этом задании мы не будем заострять внимание на начальной загрузке списка. +::: + +Давайте воспользуемся Angular DevTool для профилирования нашего приложения и поймем, как этот инструмент может помочь нам понять, что происходит внутри нашего приложения. + +:::note[Примечание] +Если вы не знаете, как им пользоваться, сначала прочтите [страницу введения в производительность](/задачи/производительность/) и вернитесь после. +::: + +Теперь запустите профилирование вашего приложения и введите несколько букв в поле ввода. Вы увидите несколько красных полос, отображающихся внутри панели профиля. + +Если вы нажмете на одну из полос (обозначенную желтой стрелкой на рисунке ниже), вы увидите, что цикл обнаружения изменений в `PersonListComponent` занимает более 3 секунд. + +![profiler record](../../../../../assets/performance/35/memoize-profiler.png 'Profiler Record') + +## Пояснение + +Цель этой задачи - понять, что является причиной такой задержки, и улучшить ее. + +## Подсказка: + +
+ Подсказка 1 + +Используйте `Pipes` для запоминания вычисления Фибоначчи. + +
diff --git a/docs copy/src/content/docs/ru/challenges/performance/36-ngfor-optimization.md b/docs copy/src/content/docs/ru/challenges/performance/36-ngfor-optimization.md new file mode 100644 index 000000000..60949b71e --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/performance/36-ngfor-optimization.md @@ -0,0 +1,33 @@ +--- +title: 🟢 NgFor Оптимизация +description: Задача 36 заключается в изучении того, как работает track by +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 36 +command: performance-ngfor-optimization +sidebar: + order: 13 +--- + +## Information + +В этом приложении у нас есть список лиц, которых мы можем добавлять, удалять или обновлять. Если вы откроете панель разработчика Chrome, нажав **F12**, перейдете на вкладку "Источник" и развернете элемент, чтобы просмотреть список, вы заметите, что каждый раз, когда вы добавляете, удаляете или обновляете элемент списка, все элементы DOM уничтожаются и инициализируется снова. (Смотрите видео ниже). + + + +Мы также можем использовать Angular DevTool для профилирования нашего приложения и понимания того, что происходит внутри нашего приложения. Я покажу вам, как это сделать, в следующем видео. + + + +:::note[Заметка] +Если вы не знаете, как им пользоваться, сначала прочтите [страницу введения в производительность](/задачи/производительность/) и вернитесь после. +::: + +Если вам нужна дополнительная информация о `ngFor`, я приглашаю вас сначала ознакомиться с [документацией](https://angular.dev/api/common/For).36 + +## Пояснение + +Цель этой задачи состоит в том, чтобы понять, что вызывает это обновление DOM, и решить его. diff --git a/docs copy/src/content/docs/ru/challenges/performance/37-optimize-big-list.md b/docs copy/src/content/docs/ru/challenges/performance/37-optimize-big-list.md new file mode 100644 index 000000000..97f41b7f6 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/performance/37-optimize-big-list.md @@ -0,0 +1,37 @@ +--- +title: 🟠 Оптимизация больших списков +description: Задание 37 посвящено изучению того, как виртуализация оптимизирует рендеринг больших списков +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 37 +command: performance-optimize-big-list +sidebar: + order: 117 +--- + +## Информация + +В этом приложении мы будем отображать список из 100 000 человек, нажав на кнопку **loadList**. Если вы откроете панель разработчика Chrome, нажав **F12**, перейдите на вкладку Source и разверните элемент, чтобы увидеть список, вы заметите, что все 100 000 элементов отображаются в DOM, хотя мы можем видеть только около 20 элементов в видимой области. Этот процесс занимает много времени, поэтому приложение очень медленно отображает список. + +Мы можем использовать Angular DevTool, чтобы профилировать наше приложение и понять, что происходит внутри нашего приложения. Я покажу вам, как это сделать в следующем видео. + + + +:::note +Если вы не знаете, как это сделать, сначала прочтите [введение в производительность](/challenges/performance/) и вернитесь после этого. +::: + +## Утверждение + +Цель этого испытания - реализовать лучшую альтернативу для отображения больших списков элементов. + +## Подсказки: + +
+ Подсказка 1 + +Если вы не уверены, с чего начать, я рекомендую прочитать [документацию Angular CDK о виртуализации](https://material.angular.io/cdk/scrolling/overview). + +
diff --git a/docs copy/src/content/docs/ru/challenges/performance/40-web-worker.md b/docs copy/src/content/docs/ru/challenges/performance/40-web-worker.md new file mode 100644 index 000000000..3d595a137 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/performance/40-web-worker.md @@ -0,0 +1,35 @@ +--- +title: 🟠 Веб-воркеры +description: Испытание 40 о том как создать и использовать веб-воркер +author: thomas-laforge +contributors: + - stillst +challengeNumber: 40 +command: performance-web-worker +sidebar: + order: 119 +--- + +## Информация + +Это испытание было создано для [Angular Advent Calendar](https://angularchristmascalendar.com) 2023. + +Это простое приложение, где нужно нажать на кнопку **Discover**, чтобы увидеть сюрприз, скрывающийся за черным экраном. Тем не менее, взаимодействие с приложением оставляет желать лучшего. При нажатии на кнопку происходит зависание страницы, а затем, после краткой задержки, секрет раскрывается мгновенно и без какой-либо плавности в анимации. + +> Пояснение: Для того, чтобы вызвать зависание приложения, загрузчик использует функцию, выполняющую очень сложные вычисления. Хотя возможно было бы использовать обычный таймер, но это не суть данного испытания. + +Так как JavaScript работает в однопоточном режиме, выполнение ресурсоемких задач препятствует обновлению пользовательского интерфейса браузера и реагированию на клики мыши или другие действия. Задача этого испытания - разгрузить основной поток, перенеся сложные вычисления в отдельный поток. Для этой цели мы будем использовать веб-воркеры. Веб-воркеры способны запускать скрипты в фоне, не влияя на основной поток, что позволяет браузеру сохранять высокое качество пользовательского взаимодействия. + +В Angular использование этой технологии не так распространено, но внедрить её довольно легко. Есть схематик, который вы можете найти [здесь](https://angular.dev/ecosystem/web-workers) чтобы начать. + +## Пояснение + +Это испытание направлено на создание плавной анимации за счет перемещения функции, выполняющей сложные вычисления, в веб-воркер. + +Для начала, используя схематик, создайте веб-воркер и перенесите в него функцию, вызывающую проблемы. После этих шагов анимация должна стать плавной, а отображение процента выполнения — обновляться, тем самым значительно улучшив пользовательский опыт. + +:::note[Пояснение] +Поскольку мы находимся в рабочем пространстве Nx, просто замените команду `ng` на `nx` при запуске схематика. + +Если `nx` не установлен глобально на вашем компьютере, добавьте префикс `npx` к вашей команде. +::: diff --git a/docs copy/src/content/docs/ru/challenges/performance/index.mdx b/docs copy/src/content/docs/ru/challenges/performance/index.mdx new file mode 100644 index 000000000..53a7dc73d --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/performance/index.mdx @@ -0,0 +1,51 @@ +--- +title: Производительность Angular-а +prev: false +next: false +contributors: + - Dinozavvvr +description: Узнайте, как использовать расширение Angular DevTools для Chrome. +noCommentSection: true +sidebar: + order: 1 +--- + +import { LinkCard } from '@astrojs/starlight/components'; + +В этой серии испытаний по производительности вы узнаете, как оптимизировать и улучшить производительность вашего приложения Angular. + +Прежде чем приступить к решению какого-либо испытания, я приглашаю вас скачать [расширение Angular DevTools для Chrome](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh), если вы еще этого не сделали. + +Это расширение позволяет профилировать ваше приложение и обнаруживать проблемы производительности, что очень полезно для понимания мест, где могут возникать проблемы с производительностью. + +## Как его использовать + +При запуске приложения Angular вы можете проверить страницу, нажав F12, что откроет Инструменты разработчика Chrome. Затем перейдите на вкладку Angular. Оттуда вы можете выбрать вкладку Profiler, как показано ниже. + +![вкладка профилировщика](../../../../../assets/performance/profiler-tab.png 'Вкладка профилировщика') + +Теперь вы можете профилировать свое приложение, нажав кнопку записи. Вы можете играть с вашим приложением и видеть, когда срабатывает обнаружение изменений и какие компоненты перерисовываются. + +:::tip[Узнайте больше] +Вы можете узнать больше на [странице документации](https://angular.io/guide/devtools). +::: + +Теперь, когда вы знаете, как использовать Angular DevTool, вы можете выбрать испытание и решить его с использованием профилирования. + + + + + + diff --git a/docs copy/src/content/docs/ru/challenges/rxjs/11-high-order-operator-bug.md b/docs copy/src/content/docs/ru/challenges/rxjs/11-high-order-operator-bug.md new file mode 100644 index 000000000..f714016d9 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/rxjs/11-high-order-operator-bug.md @@ -0,0 +1,31 @@ +--- +title: 🟠 Ошибка в операторе высшего порядка RxJS +description: Задача 11 посвящена устранению ошибки в RxJS из-за операторов высшего порядка +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 11 +command: rxjs-high-order-operator-bug +sidebar: + order: 114 +--- + +Давайте погрузимся в удивительный мир RxJs. + +Этот вызов вдохновлен реальным примером. + +## Информация + +### История пользователя + +Нам нужна кнопка для каждой `Статья`. Когда мы нажимаем на нее, мы удаляем все объекты с этой `Статьей` в нашей базе данных _(Фейковая БД в нашем случае)_. Наконец, мы отображаем **Все [статьи] были удалены** в случае успешного удаления или **Ошибка: удаление некоторых [статей] не удалось** если удаление некоторых объектов не удалось. + +### Ограничения: + +Мы можем передавать в нашу БД для удаления только один объект за раз. БД ответит true, если данные были успешно удалены, и false в противном случае. + +### Утверждение + +Команда тестировщиков сообщает об **ошибке**. Интерфейс пользователя всегда показывает **Все [темы] были удалены**, даже если некоторые удаления не удалось. + +👉 Найдите ошибку и исправьте ее. diff --git a/docs copy/src/content/docs/ru/challenges/rxjs/14-race-condition.md b/docs copy/src/content/docs/ru/challenges/rxjs/14-race-condition.md new file mode 100644 index 000000000..e5b0e9032 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/rxjs/14-race-condition.md @@ -0,0 +1,29 @@ +--- +title: 🟢 Состояние гонки +description: Задача 14 посвящена race condition в Rxjs +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 14 +command: rxjs-race-condition +sidebar: + order: 11 +--- + +## Информация + +Цель этого приложения - отображать список тем в модальном режиме при нажатии кнопки. Приложение функционирует корректно. Однако ваш технический руководитель попросил вас добавить тесты, и они завершились неудачей. + +## Пояснение + +Исправьте своё приложение, чтобы пройти тест + +## Ограничения: + +- Я вижу, как ты приближаешься 🤣 => Вы НЕ МОЖЕТЕ изменить тест (тест работает нормально) 😳 +- Вы НЕ МОЖЕТЕ изменить `fakeGetHttpTopic` метод. Добавлена задержка, чтобы имитировать медленную сеть. + +## Запуск тестов + +HEADLESS : `npx nx component-test rxjs-race-condition` +WATCH MODE : `npx nx component-test rxjs-race-condition --watch` diff --git a/docs copy/src/content/docs/ru/challenges/rxjs/38-rxjs-catch-error.md b/docs copy/src/content/docs/ru/challenges/rxjs/38-rxjs-catch-error.md new file mode 100644 index 000000000..9e25662e1 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/rxjs/38-rxjs-catch-error.md @@ -0,0 +1,35 @@ +--- +title: 🟢 catchError +description: Задача 38 посвященя изучению завершения Observable. +author: devesh-chaudhari +command: rxjs-catch-error +contributors: + - Dinozavvvr +challengeNumber: 38 +sidebar: + order: 14 +--- + +## Информация + +### Как использовать приложение + +Наше приложение представляет собой форму с полем ввода текста и кнопкой "Получить". При нажатии на кнопку "Получить" данные извлекаются из [бесплатного API](https://jsonplaceholder.typicode.com/). + +Корректные значения для успешного ответа ограничены следующим: posts, comments, albums, photos, todos и users. Любые другие значения приведут к ошибке. + +### Ошибка + +В нашем приложении обнаружена ошибка. Пользователи могут успешно получать данные только до тех пор, пока не будет отправлен недопустимый запрос. После получения ответа об ошибке пользователи не могут отправлять дополнительные запросы. + +### Изучение + +Это приложение предоставляет возможность понять правильное размещение оператора [`catchError`](https://rxjs.dev/api/operators/catchError). Если он размещен неправильно, вся подписка будет завершена, что предотвратит отправку дополнительных запросов. Цель состоит в том, чтобы сохранить общую подписку, правильно обрабатывая уведомления об ошибках от внутренних Observable. + +## Утверждение + +Цель - использовать оператор catchError для управления ошибками внутри вашего потока Rxjs. + +## Ограничения + +Пользователи должны иметь возможность журналировать значение/ошибку каждый раз при нажатии кнопки "Получить". diff --git a/docs copy/src/content/docs/ru/challenges/signal/43-signal-input.md b/docs copy/src/content/docs/ru/challenges/signal/43-signal-input.md new file mode 100644 index 000000000..b0d88eea2 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/signal/43-signal-input.md @@ -0,0 +1,55 @@ +--- +title: 🟢 Signal Input +description: Испытание 43 про то как использовать signal inputs +author: thomas-laforge +contributors: + - stillst +challengeNumber: 43 +command: signal-signal-input +sidebar: + order: 16 +--- + +## Информация + +Наконец настал тот день, когда разработчики Angular добавили долгожданный реактивный input. +Фича, которую ждали на протяжении многих лет, появилась в версии 17.1 под названием `SignalInput`. +Теперь, вместо привычного декоратора `@Input`, у нас есть функция, которая возвращает сигнал. + +```ts +// старый способ +@Input() age?: number; + +// новый способ +age = input() +``` + +Если нужны обязательные inputs. + +```ts +// старый способ +@Input({required: true}) age!: number; + +// новый способ +age = input.required() +``` + +Если было нужно получить сигнал из input приходилось использовать сеттер. + +```ts +// старый способ +age = signal(0) +@Input({alias: 'age'}) set _age(age: number){ + this.age.set(age) +}; + +// новый способ +age = input() +``` + +## Пояснение + +Задача этого упражнения - переработать `UserComponent`, чтобы в нем был использован `SignalInput`. + +- У вас есть обязательные и не обязательные inputs. +- Вы можете использовать функцию `transform` для ввода `age`, чтобы преобразовать свойство в число. diff --git a/docs copy/src/content/docs/ru/challenges/testing/17-router.md b/docs copy/src/content/docs/ru/challenges/testing/17-router.md new file mode 100644 index 000000000..118d52e29 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/17-router.md @@ -0,0 +1,27 @@ +--- +title: 🟠 Роутер +description: Задача 17 посвящена тестрированию Роутера +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 17 +command: testing-router +sidebar: + order: 108 +--- + +## Информация + +У нас есть функциональное приложение, которое позволяет просматривать доступные книги для выдачи в библиотеке. Если книга, которую вы ищете, доступна, вы будете перенаправлены на соответствующую книгу(и), в противном случае вы попадете на страницу ошибки. + +Файл с именем `app.component.spec.ts` позволит вам тестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-router-outlet`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`. + +Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `app.component.cy.ts` и запускать команду `npx nx component-test testing-router-outlet` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения. + +# Задание + +Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing. + +:::note +Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите. +::: diff --git a/docs copy/src/content/docs/ru/challenges/testing/18-nested-components.md b/docs copy/src/content/docs/ru/challenges/testing/18-nested-components.md new file mode 100644 index 000000000..545837848 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/18-nested-components.md @@ -0,0 +1,31 @@ +--- +title: 🟠 Вложенные компоненты +description: Задание 18 посвящено тестированию вложенных компонентов +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 18 +command: testing-nested-components +sidebar: + order: 109 +--- + +## Информация + +У нас есть небольшое приложение, которое отправляет заголовок, введенный в поле ввода, на фейковый бэкэнд. +Если заголовок введен правильно, вы можете отправить запрос, в противном случае вы получите ошибку, и запрос не будет отправлен. +Приложение создано с использованием вложенных компонентов. `ChildComponent` - это контейнер, который включает в себя четыре компонента: `ResultComponent`, `ButtonComponent`, `InputComponent` и `ErrorComponent`. Однако, поскольку мы тестируем наш компонент как черный ящик, архитектура наших компонентов ничего не меняет. Вы можете создавать свои тесты, изменять структуру компонентов, и ваши тесты должны по-прежнему проходить. Вот цель интеграционных тестов. Никогда не тестируйте внутренние детали реализации!!!. + +Вы можете поиграть с ним, запустив: `npx nx serve testing-nested`. + +Файл с именем `child.component.spec.ts` позволит вам тестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-nested`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`. + +Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `child.component.cy.ts` и запускать команду `npx nx component-test testing-nested` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения. + +# Задание + +Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing. + +:::note +Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите. +::: diff --git a/docs copy/src/content/docs/ru/challenges/testing/19-input-output.md b/docs copy/src/content/docs/ru/challenges/testing/19-input-output.md new file mode 100644 index 000000000..1d713cd0f --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/19-input-output.md @@ -0,0 +1,29 @@ +--- +title: 🟠 Ввод Вывод +description: Задача 19 посвящена тестированию Ввода и Вывода +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 19 +command: testing-input-output +sidebar: + order: 110 +--- + +## Информация + +У нас есть небольшое приложение-счетчик, которое увеличивает или уменьшает число. `CounterComponent` принимает начальное значение в качестве `@Input` и отправляет результат счетчика как `@Output`, когда мы нажимаем на кнопку **Send**. Поскольку мы тестируем наш компонент как черный ящик, у нас есть доступ только к нашим входным данным и мы слушаем выходные значения. Не следует полагаться на внутренние детали реализации!!! + +Вы можете поиграть с ним, запустив: `npx nx serve testing-input-output`. + +Файл с именем `counter.component.spec.ts` позволит вам протестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-input-output`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`. + +Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `child.component.cy.ts` и запускать команду `npx nx component-test testing-input-output` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения. + +# Задание + +Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing. + +:::note +Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите. +::: diff --git a/docs copy/src/content/docs/ru/challenges/testing/20-modal.md b/docs copy/src/content/docs/ru/challenges/testing/20-modal.md new file mode 100644 index 000000000..aedd11362 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/20-modal.md @@ -0,0 +1,33 @@ +--- +title: 🟠 Модальное окно +description: Задача 20 посвящена тестированию Модальных окн +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 20 +command: testing-modal +sidebar: + order: 111 +--- + +## Информация + +В этом небольшом приложении у вас есть поле ввода, в котором вы должны ввести имя, и кнопка **Confirm** для отправки формы. +Если вы вводите имя, появится модальное окно подтверждения; в противном случае будет отображено модальное окно с ошибкой. +В модальном окне подтверждения, если пользователь нажимает кнопку **Confirm**, появится сообщение с подтверждением отправки формы. Если пользователь нажимает **Cancel**, будет отображено сообщение об ошибке. + +Цель этой задачи - протестировать модальные окна внутри вашего приложения. Для этого мы будем тестировать всё приложение, как это делает end-to-end тест. Это означает, что мы будем тестировать `AppComponent` как черный ящик и реагировать на события на странице. Не следует тестировать внутренние детали. Разница между e2e тестом и интеграционным тестом заключается в том, что мы будем подделывать все вызовы API. _(Все http-запросы фальсифицированы внутри этого приложения и отличаются от тех что присутствуют в реальном корпоративном приложении.)_ + +Вы можете поиграть с этим, запустив: `npx nx serve testing-modal`. + +Файл с именем `app.component.spec.ts` позволит вам тестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-modal`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`. + +Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `app.component.cy.ts` и запускать команду `npx nx component-test testing-modal` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения. + +# Задание + +Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing. + +:::note +Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите. +::: diff --git a/docs copy/src/content/docs/ru/challenges/testing/23-harness.md b/docs copy/src/content/docs/ru/challenges/testing/23-harness.md new file mode 100644 index 000000000..185c87cf5 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/23-harness.md @@ -0,0 +1,26 @@ +--- +title: 🟢 Harness +description: Задача 23 посвящена тестированию с использованием harness компонентов +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 23 +command: testing-harness +sidebar: + order: 9 +--- + +## Информация + +Harness это класс, который позволяет тесту взаимодействовать с компонентом через поддерживаемый API. + +Цель этого задания - лучше понять CDK test harness API. В этом первоначальном задании мы будем использовать только встроенные harness Angular Material. + +Документация для harness компонентов CDK находится [здесь](https://material.angular.io/cdk/test-harnesses/overview#api-for-test-authors). +Документация для компонента Angular Material находится [здесь](https://material.angular.io/components/button/overview). + +## Пояснение + +Протестируйте функциональность `child.component.ts`, которая состоит из некоторых inputs & checkboxes, связанных с `mat-slider`. Реализуйте подготовленный набор тестов, но не стесняйтесь также включать дополнительные тесты. + +**Заметка:** Вы можете воспользоваться Testing Library, если хотите. diff --git a/docs copy/src/content/docs/ru/challenges/testing/24-harness-creation.md b/docs copy/src/content/docs/ru/challenges/testing/24-harness-creation.md new file mode 100644 index 000000000..130d57c51 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/24-harness-creation.md @@ -0,0 +1,46 @@ +--- +title: 🟠 Создание harness класса +description: Задача 24 посвящено созданию компонента тестового стенда. +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 24 +command: testing-harness-creation +sidebar: + order: 112 +--- + +## Информация + +Цель этой задачи - реализовать harness класс для `slider.component.ts`. Файл стенда, `slider.harness.ts`, уже создан. + +Необходимо реализовать следующее API: + +```ts + async clickPlus(): Promise ; + + async clickMinus(): Promise; + + async getValue(): Promise ; + + async getMinValue(): Promise; + + async disabled(): Promise; + + async setValue(value: number): Promise; +``` + +Кроме того, вы должны создать `HarnessPredicate` с предикатом по умолчанию и свойством `minValue`. + +```ts + static with( + this: ComponentHarnessConstructor, + options: SliderHarnessFilters = {} + ): HarnessPredicate; +``` + +Наконец, вам нужно создать набор тестов для `app.component`. Некоторые тесты по умолчанию уже написаны, но не стесняйтесь добавлять столько тестов, сколько вам нужно, и создавать столько методов, сколько вам потребуется. + +> Документация Angular Material доступна [здесь](https://material.angular.io/cdk/test-harnesses/overview). + +Удачи !!! 💪 diff --git a/docs copy/src/content/docs/ru/challenges/testing/28-checkbox.md b/docs copy/src/content/docs/ru/challenges/testing/28-checkbox.md new file mode 100644 index 000000000..bf724504c --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/28-checkbox.md @@ -0,0 +1,27 @@ +--- +title: 🟢 Checkbox +description: Задача 28 заключается в тестировании простого checkbox +author: thomas-laforge +contributors: + - webbomj +challengeNumber: 28 +command: testing-checkbox +sidebar: + order: 10 +--- + +## Информация + +Это приложение очень простое. Оно состоит из checkbox, который включает или отключает кнопку. Основная цель этого приложения - ознакомиться с API отладки библиотеки тестирования. Знание того, как отлаживать ваши тесты, является важным инструментом, который должен быть в вашем наборе инструментов. + +Вы можете найти документацию по отладке в Testing Library [здесь](https://testing-library.com/docs/dom-testing-library/api-debugging#screenlogtestingplaygroundurl). + +Основными функциями, которые необходимо запомнить, являются следующие: + +- `logRoles(myDOMElement)`: выводит все роли ARIA в дереве данного элемента DOM. Роли ARIA - это основные селекторы, к которым вам следует обратиться в первую очередь. +- `screen.debug()` или `screen.debug(myDOMElement)`: выводит DOM внутри консоли. +- `screen.logTestingPlaygroundURL()` или `screen.logTestingPlaygroundURL(myDOMElement)`: эта функция очень мощная. Она создаст игровую площадку для отображения всех элементов, и вы сможете взаимодействовать с ней, чтобы увидеть селекторы, которые вы должны выбрать для элемента DOM. + +## Пояснение + +Цель этого задания не в том, чтобы отправить ответ, но вы можете сделать это, если хотите. Это больше об изучении использования API отладки. Эти инструменты окажут большую помощь в предстоящих тестовых задачах. diff --git a/docs copy/src/content/docs/ru/challenges/testing/29-real-life-application.md b/docs copy/src/content/docs/ru/challenges/testing/29-real-life-application.md new file mode 100644 index 000000000..f03c0897a --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/29-real-life-application.md @@ -0,0 +1,35 @@ +--- +title: 🔴 Приложение из реальной жизни +description: Задача 29 посвящена тестированию приложения из реальной жизни +author: thomas-laforge +contributors: + - Dinozavvvr +challengeNumber: 29 +command: testing-real-life-application +sidebar: + order: 205 +--- + +## Информация + +Это приложение представляет собой большой вызов, потому что оно тесно напоминает приложение из реальной жизни, с которым вы можете столкнуться в своей повседневной деятельности в качестве разработчика Angular. Что делает его более сложным, так это необходимость обрабатывать асинхронные задачи и создавать соответствующие заглушки. + +Приложение - это типичное приложение для списка задач. Вы можете фильтровать заявки, создавать новые, назначать каждую заявку, закрывать другие и переходить к деталям каждой заявки. + +В этом вызове вы напишете тесты для `ListComponent`, который представляет глобальный вид, и `RowComponent`, который представляет конкретную заявку. Кроме того, вам нужно будет написать модульные тесты для `TicketStoreService`, используя библиотеку Testing Library. _Эта библиотека позволяет эффективно тестировать сервисы._ + +Особенно сложно будет обрабатывать асинхронные задачи. Важно не вводить явные ожидания(waits) в ваши тесты, так как это приведет к ненужным задержкам. Вместо этого лучше искать элемент, который должен появиться или исчезнуть из DOM. В этом случае тест будет естественным образом ожидать правильного периода времени, так как ожидания уже реализованы в обеих библиотеках. Воспользуйтесь встроенными функциональными возможностями для создания эффективных и надежных тестов. + +Вы можете поиграть с этим, запустив: `npx nx serve testing-todos-list`. + +Чтобы запустить тесты Testing Library, вам нужно выполнить `npx nx test testing-todos-list`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, нажимая на кнопку `Run` над каждым блоком `describe` или `it`. + +Для тестирования с помощью Cypress вы выполните свой тест внутри `child.component.cy.ts` и выполните `npx nx component-test testing-todos-list`, чтобы запустить ваши тестовые наборы. Вы можете добавить флаг `--watch`, чтобы выполнять тесты в режиме наблюдения. + +# Задание + +Цель - протестировать множество поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing и Cypress Component Testing. + +:::note +Я создал несколько блоков `it`, но не стесняйтесь добавлять больше тестов, если хотите. +::: diff --git a/docs copy/src/content/docs/ru/challenges/testing/index.mdx b/docs copy/src/content/docs/ru/challenges/testing/index.mdx new file mode 100644 index 000000000..508c4b558 --- /dev/null +++ b/docs copy/src/content/docs/ru/challenges/testing/index.mdx @@ -0,0 +1,73 @@ +--- +title: Тестирование +prev: false +next: false +contributors: + - Dinozavvvr +description: Введение в задачи по тестированию. +noCommentSection: true +sidebar: + order: 1 +--- + +import { LinkCard } from '@astrojs/starlight/components'; + +Тестирование - это важный этап в создании масштабируемых, поддерживаемых и надежных приложений. +Тестирование никогда не должно быть упущено, даже в случае сжатых сроков или сильного давления со стороны команды продукта. +В наши дни существует множество замечательных инструментов, которые облегчают тестирование вашего кода и обеспечивают отличный опыт разработчика. + +В этой серии упражнений по тестированию мы изучим и освоим [Testing Library](https://testing-library.com/docs/) и [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/angular/overview), которые упрощают манипуляции с DOM для тестирования любого компонента Angular. + +Преимущества использования Testing Library или Cypress Component Testing заключаются в том, что вы тестируете свой компонент как черный ящик. Вы будете взаимодействовать только с тем, что пользователь может делать на интерфейсе. Однако отличие от полноценных тестов заключается в том, что бэкэнд замокан, что делает тесты быстрее и более поддерживаемыми. +Цель состоит в том, чтобы мокать как можно меньше, чтобы тестировать ваш компонент на более высоком уровне, чем при модульном тестировании, что облегчит рефакторинг. +В реальном приложении интеграционные тесты - это тесты, которые вы будете писать больше всего. Изучение того, как их писать, сделает ваше приложение более надежным и поддерживаемым. + +Перед вами серия из 8 задач, которые вы можете решить в любом порядке. + + + + + + + + + + + + + + + + diff --git a/docs copy/src/content/docs/ru/guides/checkout-answer.md b/docs copy/src/content/docs/ru/guides/checkout-answer.md new file mode 100644 index 000000000..e2cb8f46f --- /dev/null +++ b/docs copy/src/content/docs/ru/guides/checkout-answer.md @@ -0,0 +1,51 @@ +--- +title: Изучайте чужие решения +description: Руководство по просмотру чужого ответа. +contributors: + - stillst + - 1fbr +sidebar: + order: 3 +--- + +Все ответы на испытания Angular представлены в виде Pull Request (PR). Чтобы их просмотреть и изучить, нужно перейти на страницу **Files Changes** на GitHub. Однако, если вы не знакомы с интерфейсом, процесс может быть не очевидным. Иногда посмотреть на решение в вашей любимой IDE может быть удобнее. + +Это руководство поможет вам с этим. + +## Проверьте чужой PR локально + +### Синхронизируйте свой репозиторий + +В начале вам нужно синхронизировать вашу копию репозитория, чтобы убедиться, что она находится в актуальном состоянии. + +Это можно сделать, нажав на кнопку **Sync fork** на главной странице репозитория. + +![Sync project header](../../../../assets/fork-sync.png) + +На изображении выше видно, что моя ветка отстает от основной ветки на 8 коммитов, и мне нужно синхронизировать ее, чтобы она была в актуальном состоянии. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Перейдите к PR + +Перейдите к PR, который вы хотите изучить локально, и узнайте его ID. Вы найдете его в заголовке PR (как показано ниже). + +![PR header](../../../../assets/PR-header.png) + +Далее откройте терминал в каталоге проекта и выполните следующую команду: + +```bash +gh pr checkout +``` + +Если вы не помните команду, нажмите на кнопку "Code" в правой части заголовка, и вы сможете легко скопировать/вставить команду. + +![PR code modal](../../../../assets/PR-code-btn-modal.png) + +:::note[Примечание] +Если команда не сработала, GitHub CLI подскажет, что делать. +::: + +🔥Теперь вы можете изучить решение локально и запустить его для тестирования.🔥 + + diff --git a/docs copy/src/content/docs/ru/guides/contribute.md b/docs copy/src/content/docs/ru/guides/contribute.md new file mode 100644 index 000000000..c40075701 --- /dev/null +++ b/docs copy/src/content/docs/ru/guides/contribute.md @@ -0,0 +1,22 @@ +--- +title: Вносите свой вклад +description: Описание как помочь проекту +contributors: + - stillst +sidebar: + order: 4 +--- + +Вы можете помочь проекту многими способами: + +🔥 Создавайте новые испытания, следуя инструкциям [тут](/guides/create-challenge). + +🔥 Проходите испытания и отправляйте свои решения на ревью (руководство [тут](/guides/resolve-challenge)). + +🔥 Проводите ревью чужих решений, оставляя конструктивные и вежливые комментарии. + +🔥 Исправляйте опечатки и ошибки в документации. + +🔥 Оставляйте issues, чтобы предложить идеи новых испытаний или сообщить об ошибках. + +🔥 Поддерживайте проект [тут](https://github.com/sponsors/tomalaforge). diff --git a/docs copy/src/content/docs/ru/guides/create-challenge.md b/docs copy/src/content/docs/ru/guides/create-challenge.md new file mode 100644 index 000000000..a77e4b0c2 --- /dev/null +++ b/docs copy/src/content/docs/ru/guides/create-challenge.md @@ -0,0 +1,56 @@ +--- +title: Создайте свое испытание +description: Руководство по созданию испытания +contributors: + - stillst +sidebar: + order: 5 +--- + +У вас есть идея, которой вы хотите поделиться, интересная ошибка, с которой вы боретесь в одном из своих проектов, или что-то необычное в Angular, что вы обнаружили. Всё это - хорошая отправная точка, чтобы создать испытание и поделиться её решением с другими. + +Но как начать создавать испытания? + +## Шаблон создания испытания + +Чтобы упростить этот процесс, я создал генератор Nx, который настроит все за вас и поможет вам быстрее начать. Проще всего его запустить в консоли Nx: перейдите в раздел Nx Console > generate > @angular-challenges/cli - challenge + +### Параметры + +#### обязательные параметры + +- title: Название, которое вы хотите дать испытанию. + :::note[Примечание] + Название должно быть не больше 25 символов. + ::: + +- challengeDifficulty: Сложность испытания. Есть три уровня сложности : 🟢 простой / 🟠 средний / 🔴 трудный +- name: Имя NX приложения. + :::note[Примечание] + Имя должно быть написано **kebab-case** + ::: +- docRepository: Категория испытания: Nx, Angular, Angular Performance, Rxjs, NgRx, Typescript. + +#### необязательные параметры + +- directory: Если вы не хотите, чтобы приложение находилось в стандартной папке внутри `apps`. +- addTest: Если хотите добавить конфигурацию теста. + +### Что будет создано + +- Генератор создаст все файлы, необходимые для нового рабочего приложения. Все эти файлы будут созданы внутри `apps/${directory}/${name}` +- Файл Markdown с минимальными настройками будет создан внутри `docs/src/content/docs/challenges/${docRepository}` + +## Создание испытания + +Все что осталось - создать испытание. 🚀 + +:::danger[Опасно] +Не забудьте обновить документацию, чтобы описать свою задачу и дать инструкции. +::: + +Дальше действовать будете вы!!! 💪 + +## Отправка решения + +Не забудьте представить своё решение задачи в течение недели. diff --git a/docs copy/src/content/docs/ru/guides/faq.md b/docs copy/src/content/docs/ru/guides/faq.md new file mode 100644 index 000000000..71a5ce660 --- /dev/null +++ b/docs copy/src/content/docs/ru/guides/faq.md @@ -0,0 +1,19 @@ +--- +title: Часто задаваемые вопросы +description: Ответы на вопросы +contributors: + - stillst +sidebar: + order: 7 +--- + +
+ Почему мое приложение не запускается, или почему я вижу ошибки в терминале при запуске `nx serve`? + +Чаще всего эта проблема возникает из-за того, что `node_modules` устарели, и вам нужно обновить их, выполнив команду `npm ci`. + +Если установка завершилась неудачно, вы можете попробовать решить эту проблему, удалив папку `node_modules` с помощью команды `rm -rf node_modules` или `npx npkill`, а затем снова выполнить `npm ci`. + +Если проблема сохранится, пожалуйста, сообщите о ней [тут](https://github.com/tomalaforge/angular-challenges/issues/new). + +
diff --git a/docs copy/src/content/docs/ru/guides/getting-started.md b/docs copy/src/content/docs/ru/guides/getting-started.md new file mode 100644 index 000000000..e269e9bc2 --- /dev/null +++ b/docs copy/src/content/docs/ru/guides/getting-started.md @@ -0,0 +1,61 @@ +--- +title: Первые шаги +description: Руководство о том, как начать работу с испытаниями Angular. +contributors: + - stillst + - 1fbr +sidebar: + order: 1 +--- + +Чтобы начать работу с испытаниями Angular, выполните следующие шаги: + +## Создайте аккаунт на GitHub + +Если вы захотите отправить свое решение для испытания, вам потребуется аккаунт на GitHub. Кроме того, иметь учетную запись на GitHub всегда полезно, тем более это бесплатно. + +## Скопируйте GitHub проект + +Перейдите в [Angular Challenges Repository](https://github.com/tomalaforge/angular-challenges) и нажмите на кнопку Fork в вверху страницы. Это создаст копию репозитория на вашей GitHub странице. + +## Клонируйте репозиторий на свой компьютер + +Выберите папку на своем компьютере и клонируйте репозиторий. + +Откройте терминал, перейдите в выбранный каталог и наберите команду: + +```bash +git clone https://github.com/[YOUR_GITHUB_NAME]/angular-challenges.git +``` + +:::note + +Вы можете найти URL адрес клонированного репозитория, нажав на кнопку <> Code в вашем собственном экземпляре репозитория Angular Challenges. + +![Header of GitHub workspace](../../../../assets/header-github.png) + +::: + +## Откройте проект в вашей любимой среде разработки + +Откройте проект в любой IDE на ваш выбор. + +## Установите все зависимости + +```bash +npm ci +``` + +## Выберите задачу + +Ваш проект сейчас поднят и запущен. Осталось только выбрать испытание 🚀 + +Каждое испытание состоит из: + +- Имя: описывает о чем испытание. +- Номер: порядковый номер создания. Этот номер не несет какого-то смысла, но служит для ссылки в секции GitHub Pull Request. +- Бейдж: показывает уровень сложности. Полностью субъективно 😅 + - 🟢 простое + - 🟠 среднее + - 🔴 сложное diff --git a/docs copy/src/content/docs/ru/guides/rebase.md b/docs copy/src/content/docs/ru/guides/rebase.md new file mode 100644 index 000000000..dad4d2957 --- /dev/null +++ b/docs copy/src/content/docs/ru/guides/rebase.md @@ -0,0 +1,57 @@ +--- +title: Сделайте rebase вашей ветки +description: Руководство по rebase ветки на последние изменения +contributors: + - stillst +sidebar: + order: 6 +--- + +Иногда в проект могут вноситься изменения. Я стараюсь вносить изменения, которые ничего не сломают, но иногда этого не избежать. + +В большинстве случаев вам не придется делать rebase вашего решения, но вот руководство, которое поможет вам понять, как это сделать. + +:::note[Примечание] +Это руководство применимо к любому проекту с открытым исходным кодом. +::: + +## Шаги rebase + +### Синхронизируйте ваш репозиторий + +Во-первых, вам нужно синхронизировать вашу копию, чтобы убедиться, что она содержит последние изменения. + +Вы можете сделать это, нажав на кнопку Sync fork на главной странице вашего репозитория. + +![Sync project header](../../../../assets/fork-sync.png) + +На изображении выше видно, что моя ветка отстает от основной ветки на 8 коммитов, и мне нужно синхронизировать ее, чтобы она была в актуальном состоянии. + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### Откройте терминал + +Откройте любой терминал, будь то терминал в любимой IDE или отдельное приложение. + +### Гит + +Выполните следующие команды, чтобы сделать rebase локальной ветки: + +- git checkout main +- git pull +- git checkout [your branch] +- git rebase main +- Разрешите конфликты + +На этом этапе rebase может остановиться, потому что в вашей локальной ветке есть конфликтующие файлы с основной веткой. Исправьте это. После того как закончите: + +- git add . +- git rebase --continue + +Если в вашей ветке нет конфликтов, будет показано сообщение об успехе. + +### Отправьте свою работу в удаленный репозиторий + +Наконец, отправьте свою работу на GitHub: + +- git push -f diff --git a/docs copy/src/content/docs/ru/guides/resolve-challenge.md b/docs copy/src/content/docs/ru/guides/resolve-challenge.md new file mode 100644 index 000000000..f2e472c62 --- /dev/null +++ b/docs copy/src/content/docs/ru/guides/resolve-challenge.md @@ -0,0 +1,102 @@ +--- +title: Пройдите испытание +description: Инструкция по прохождению испытания +contributors: + - stillst + - 1fbr +sidebar: + order: 2 +--- + +В этом руководстве вы узнаете, как пройти испытание и отправить свое решение. + +## Вступление + +Этот репозиторий работает под управлением [Nx](https://nx.dev/getting-started/intro). Nx - это монорепозиторий, который позволяет вам хранить несколько приложений в одном рабочем пространстве. +Каждое испытание - это отдельное приложение. Если вы откроете каталог `apps`, то обнаружите несколько директорий, каждая из которых относится к определенной задаче. Каждый каталог представляет собой полноценное приложение `Nx`. Чтобы запустить и начать работу с одним из них, откройте терминал и выполните команду: + +```bash +npx nx serve <ИМЯ_ПРИЛОЖЕНИЯ> +``` + +:::note[Примечание] +Если вы не уверены в названии испытания `ИМЯ_ПРИЛОЖЕНИЯ`, откройте файл README.md. Там написана команда `serve` со ссылкой на документацию по испытанию. +::: + +:::note[Примечание] +Если `nx` установлен глобально на вашем компьютере, вы можете опустить команду `npx`. +Чтобы установить `nx` глобально, выполните + +```bash +npm i -g nx +``` + +::: + +## Создайте Git Ветку + +Прежде чем приступить к реализации вашего решения испытания, создайте ветку git для фиксации своей работы. + +```bash +git checkout -b +``` + +## Пройдите испытание + +Изучите инструкции, чтобы пройти испытание. + +## Сделайте коммит и отправьте код в репозиторий + +Последний шаг - это создание коммита, который следовал бы правилам из [Соглашения о коммитах](https://www.conventionalcommits.org/ru/v1.0.0/). + +Наконец, отправьте свою работу в удаленный репозиторий с помощью следующей команды: + +```bash + git push --set-upstream origin +``` + +:::tip[Не запоминай команду] +Вам не нужно запоминать команду в точности. Нужно просто запомнить `git push`, и если вы впервые загружаете эту ветку в репозиторий, `git` подскажет вам полную команду. +::: + +## Отправьте свое решение в основной репозиторий + +Теперь все ваше решение находится в вашем экземпляре репозитория Angular Challenges. + +Следующий шаг - перейдите на главную страницу [Angular Challenges](https://github.com/tomalaforge/angular-challenges) и создайте новый запрос на слитие (Pull Request). + +GitHub должен показать уведомление, чтобы помочь вам создать pull request. + +Если этого не случилось, то вы либо неправильно выполнили один из предыдущих шагов, либо вам нужно перейти на вкладку Pull Request и нажать кнопку New pull request. + +После того как вы выберете две ветки для сравнения, вы попадете на следующую страницу: + +![New pull request screen](../../../../assets/new-pull-request.png) + +В заголовке напишите Answer:, затем номер вашего испытания. После этого можете добавить все, что пожелаете. + +:::danger[Опасно] +Порядковый номер очень важен. Он позволит другим узнать, какое испытание вы пытаетесь решить. +::: + +В разделе описания вы можете добавить вопросы, проблемы, с которыми столкнулись, или все остальное, чем захотите поделиться. Если нечего написать, можете оставить этот раздел пустым. + +Теперь вы можете нажать на кнопку Create pull request. + +## Поддержка + +Чтобы продолжать предоставлять ценные отзывы и рецензии, теперь я буду рецензировать только тех кто поддерживает проект на GitHub. + +
    +
  • $5 за рецензию
  • +
  • $25 за пожизненные рецензии
  • +
  • Создайте вызов/Внесите свой вклад в пожизненные обзоры
  • +
+ +:::note[Примечание] +Все желающие могут оставлять комментарии и читать другие PR. +::: + +:::tip[OSS чемпион] +🔥 После того как вы пройдете это руководство, вы сможете внести свой вклад в любой другой публичный репозиторий на GitHub. Да, это настолько просто.🔥 +::: diff --git a/docs copy/src/content/docs/ru/index.mdx b/docs copy/src/content/docs/ru/index.mdx new file mode 100644 index 000000000..a80dab6a1 --- /dev/null +++ b/docs copy/src/content/docs/ru/index.mdx @@ -0,0 +1,87 @@ +--- +title: Добро пожаловать в испытания Angular +description: Начните с прохождения этих испытаний и прокачайтесь как Angular разработчик. +template: splash +noCommentSection: true +hero: + tagline: Начните сейчас и станьте экспертом Angular! + image: + file: ../../../assets/angular-challenge.webp + actions: + - text: Начать + link: /ru/guides/getting-started/ + icon: right-arrow + variant: primary + - text: Перейти к последней задаче + link: /ru/challenges/angular/59-content-projection-defer/ + icon: rocket + - text: Добавить звезду + link: https://github.com/tomalaforge/angular-challenges + icon: github + variant: secondary +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; +import MyIcon from '../../../components/MyIcon.astro'; +import SubscriptionForm from '../../../components/SubscriptionForm.astro'; + + + + Этот репозиторий содержит 56 испытаний, связанных с Angular, Nx, RxJS, Ngrx и Typescript. + Испытания основаны на реальных задачах или инструментах для того, чтобы прокачать вас. + + + + + + + + Одна из целей этого репозитория снизить барьер для разработки открытого + программного обеспечения (OSS). Решив эти задачи, вы поймете, как начать + вносить свой вклад в любой другой проект с открытым исходным кодом. + + + + Изучение и использование нового фреймворка всегда сопряжено с трудностями. В + этом наборе испытаний содержатся реальные примеры задач, чтобы закрепить на + практике то, чему вы научились. Любой может оставить комментарий или + предложить помощь. + + Учиться одному - здорово, но обучение вместе с другими поможет вам добиться + большего. + + + + + У вас есть идея или интересный баг? Не стесняйтесь;{' '} + Создавайте свои собственные испытания не теряя времени. + + + + Прохождение этих испытаний подготовит вас к техническим задачам, с которыми вы + можете столкнуться во время собеседований на позицию фронтенд-разработчика. + + + + Это бесплатный проект, и он будет оставаться таковым как можно дольше. Однако + вся работа ведется в мое свободное время, включая создание новых испытаний и + ревью их решений(PRs). + Спонсорство может поддержать меня и способствовать развитию проекта. + + + + +--- + + + + diff --git a/docs copy/src/content/docs/subscription/index.mdx b/docs copy/src/content/docs/subscription/index.mdx new file mode 100644 index 000000000..cf987d584 --- /dev/null +++ b/docs copy/src/content/docs/subscription/index.mdx @@ -0,0 +1,10 @@ +--- +title: Subscription +description: Subscribe to email. +noCommentSection: true +--- +import SubscriptionForm from '../../../components/SubscriptionForm.astro' + +
If you want to be informed of new challenges, you can subscribe to the email form.
+ + diff --git a/docs copy/src/content/docs/zh-cn/challenges/angular/1-projection.md b/docs copy/src/content/docs/zh-cn/challenges/angular/1-projection.md new file mode 100644 index 000000000..9a21713fb --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/challenges/angular/1-projection.md @@ -0,0 +1,52 @@ +--- +title: 🟢 投影 +description: 挑战1是学习如何通过组件投影DOM元素 +author: thomas-laforge +contributors: + - tomalaforge + - jdegand + - dmmishchenko + - kabrunko-dev + - svenson95 +challengeNumber: 1 +command: angular-projection +blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5 +videoLinks: + - link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq + alt: Projection video by Arthur Lannelucq + flag: FR + - link: https://www.youtube.com/watch?v=yNrfvu7vTa4 + alt: Projection video by Amos Lucian Isaila + flag: ES +sidebar: + order: 1 +--- + +## 信息 + +在Angular中,内容投影是一种创建高度可定制组件的强大技术。利用和理解ng-contentngTemplateOutlet的概念可以显著增强你创建可共享组件的能力 + +你可以在[这里](https://angular.dev/guide/components/content-projection)了解ng-content 的所有内容,从简单的投影到更复杂的投影。 + +要了解ngTemplateOutlet,你可以在[这里](https://angular.io/api/common/NgTemplateOutlet)找到API文档和一些基本示例。 + +有了这两个工具,您现在就可以接受挑战了。 + +## 说明 + +您将从一个功能齐全的应用程序开始,该应用程序包括一个包含教师卡和学生卡的仪表盘。目标是实现城市卡。 + +虽然应用程序可以工作,但开发人员的体验还远没有达到最佳。每次需要实现新卡时,都必须修改`card.component.ts` 。在实际项目中,该组件可以在许多应用程序之间共享。该挑战的目标是创建一个 `CardComponent` ,它可以在不做任何修改的情况下进行自定义。一旦你创建了这个组件,你就可以开始实现 `CityCardComponent` ,并确保你没有触碰 `CardComponent` 。 + +## 约束 + +- 必须重构 `CardComponent` 和 `ListItemComponent`。 +- `NgFor` 指令必须声明并保持在 `CardComponent` 内。你可能想把它移到 `ParentCardComponent` ,比如 `TeacherCardComponent` 。 +- `CardComponent` 不应包含任何 `NgIf` 或 `NgSwitch` 。 +- CSS:尽量避免使用 `::ng-deep` 。寻找更好的方法来处理CSS样式。 + +## 挑战奖励 + +- 尝试使用新的内置控制流语法for循环和条件语句(文档在[这里](https://angular.dev/guide/templates/control-flow)) +- 使用signal API来管理组件状态(文档在[这里](https://angular.dev/guide/signals)) +- 要引用模板,请使用指令而不是魔术字符串([魔术字符串有什么问题?](https://softwareengineering.stackexchange.com/a/365344)) diff --git a/docs copy/src/content/docs/zh-cn/guides/checkout-answer.md b/docs copy/src/content/docs/zh-cn/guides/checkout-answer.md new file mode 100644 index 000000000..5ac31b98b --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/guides/checkout-answer.md @@ -0,0 +1,57 @@ +--- +title: 查看某人的回答 +description: 查看某人的回答指南 +contributors: + - tomalaforge + - gsgonzalez88 + - 1fbr + - jdegand +sidebar: + order: 3 +--- + +所有Angular Challenges的答案都将以pull request (PR)的形式呈现。要查看和跟踪它们,请浏览GitHub上的**文件更改**页面。但是,如果您不熟悉界面,理解和遵循此过程可能并不简单。在许多情况下,您可能更喜欢签出分支并在您首选的IDE中检查解决方案。 + +## 安装 GitHub CLI + +在[这里](https://github.com/cli/cli#installation)按照操作系统的说明操作。 + +## 查看本地其他人的PR + +### 同步存储库 + +首先,您需要同步您的分支,以确保它与分支存储库是最新的。 + +这可以通过点击你的分支主页上的**Sync fork**按钮来实现。 + +![Sync project header](../../../../assets/fork-sync.png) + +上图显示我的分支落后于主分支 8 个提交,我需要将其同步才能保持最新。 + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### 本地检出查看 + +导航到你想在本地查看的PR并获取其ID。你可以在PR的标题中找到它(如下所示)。 + +![PR header](../../../../assets/PR-header.png) + +接下来,切换到项目目录中的任意终端,并运行以下命令: + +```bash +gh pr checkout +``` + +如果你不记得这个命令,点击标题右侧的Code按钮,你可以轻松地复制/粘贴这个命令。 + +![PR code modal](../../../../assets/PR-code-btn-modal.png) + +:::note[注意] +如果命令不起作用或失败,GitHub CLI会引导你完成整个过程。 +::: + +🔥您现在可以在本地浏览解决方案并提供服务以测试它。🔥 + +### 使用GitHub Codespaces检出查看 + +你可以使用GitHub Codespaces查看任何**打开**的PR。点击code按钮后,你可以导航到codespaces标签,然后点击绿色按钮,在PR的分支上创建一个codesace。codespace初始化后,就可以启动应用了。 diff --git a/docs copy/src/content/docs/zh-cn/guides/contribute.md b/docs copy/src/content/docs/zh-cn/guides/contribute.md new file mode 100644 index 000000000..7fea19df6 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/guides/contribute.md @@ -0,0 +1,25 @@ +--- +title: 贡献 +description: 贡献指南 +contributors: + - tomalaforge + - jdegand +sidebar: + order: 4 +--- + +你可以通过以下多种方式为这个存储库做出贡献: + +🔥 依照以下[指示](/guides/create-challenge)创建一个新的挑战。 + +🔥 接受挑战并提交结果(指南 [在此](/guides/resolve-challenge))。 + +🔥 对他人提出的解决方案给予有建设性的、热情的反馈。 + +🔥 校正文档中的拼写错误。 + +🔥 协助翻译文档。 + +🔥 提交问题建议新的挑战想法或报告错误。 + +🔥 [在此](https://github.com/sponsors/tomalaforge)赞助该项目。 diff --git a/docs copy/src/content/docs/zh-cn/guides/create-challenge.md b/docs copy/src/content/docs/zh-cn/guides/create-challenge.md new file mode 100644 index 000000000..6b13e69cd --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/guides/create-challenge.md @@ -0,0 +1,68 @@ +--- +title: 创建你自己的挑战 +description: 创建你自己的挑战指南 +contributors: + - tomalaforge + - gsgonzalez88 + - jdegand +sidebar: + order: 5 +--- + +你有一个想法想要分享,你正在努力解决某个私人项目或业余项目中的一个有趣的bug,或者你发现的一个Angular技巧。所有这些可能性都是创建挑战并与他人分享解决方案的良好起点。 + +如何开始创造这些挑战? + +## 样板设置 + +为了简化这个过程,我创建了一个Nx生成器,它将为您设置所有样板文件。运行它最简单的方法是使用Nx控制台:转到Nx Console > generate > @angular-challenges/cli - challenge。 + +或者,你也可以利用IDE的 [Nx Console extension](https://nx.dev/getting-started/editor-setup)来生成文件 + +### 参数 + +#### 强制参数 + +- title: 你想给你的挑战的标题。 + :::note[注意] + 标题长度不能超过25个字符。 + ::: + +- author: 你的名字 + + :::note[注意] + 你的名字应该使用烤肉串格式(如: john-doe) + ::: + + :::note[注意] + 别忘了在以你名字命名的文件中更新你的个人信息 + ::: + +- challengeDifficulty:你认为你的挑战有多大的难度。有三个难度级别:🟢简单/🟠中等/🔴困难 + +- docRepository: 你挑战的类别是Nx、Angular、Angular性能、Rxjs、NgRx、Typescript、表单或信号。 + +#### 可选参数 + +- challengeNumber: 当有挑战提交时,可以指定挑战号。(如果为空,该数字将是下一个数字)。 +- directory: 如果您希望您的应用程序位于 `apps` 中的特定文件夹中。 +- addTest: 如果您想添加测试配置。 + +### 创建了什么? + +- 生成器将创建新应用程序运行所需的所有文件。所有这些文件都将创建在 `apps/${directory}/${name}` 中 +- 将在 `docs/src/content/docs/challenges/${docRepository}` 中创建一个带有最小设置的Markdown文件。 + +## 创造挑战 + +剩下唯一要做的就是创造挑战。 🚀 + +:::danger[危险] +不要忘记更新文档以介绍您的挑战并提供说明。 +::: + +轮到你行动了!!💪 + +## 解决方案提交 + +大约一周后,提供一个针对您的挑战的解决方案的pull request。 diff --git a/docs copy/src/content/docs/zh-cn/guides/faq.md b/docs copy/src/content/docs/zh-cn/guides/faq.md new file mode 100644 index 000000000..0a79778b6 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/guides/faq.md @@ -0,0 +1,22 @@ +--- +title: 常见问题解答 +description: 回答问题 +contributors: + - tomalaforge + - jdegand +sidebar: + order: 7 +--- + +
+ + 为什么我的应用程序没有启动,或者为什么我在运行`nx serve`时在终端中遇到错误? + + + 大多数情况下,出现这个问题是因为你的node_modules已经过时了,你需要通过运行 `npm ci` 来更新它们。 + +如果安装失败,可以通过 `rm -rf node_modules` 或 `npx npkill` 删除node_modules文件夹,然后重新运行 `npm ci` 来解决。 + +如果问题仍然存在,请在[这里](https://github.com/tomalaforge/angular-challenges/issues/new)报告问题。 + +
diff --git a/docs copy/src/content/docs/zh-cn/guides/getting-started.md b/docs copy/src/content/docs/zh-cn/guides/getting-started.md new file mode 100644 index 000000000..53033cae6 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/guides/getting-started.md @@ -0,0 +1,83 @@ +--- +title: 开始 +description: 关于如何开始Angular挑战的指南。 +contributors: + - tomalaforge + - 1fbr + - ho-ssain + - jdegand +sidebar: + order: 1 +--- + +要开始使用 Angular Challenges,请按照以下步骤操作: + +## 创建一个GitHub账户 + +如果你想提交答案,你需要拥有自己的GitHub账户。此外,拥有GitHub账户总是有益的,而且是免费的。 + +## Fork GitHub 项目 + +导航至 [Angular Challenges Repository](https://github.com/tomalaforge/angular-challenges) 在页面顶部点击 Fork 按钮。这将在您的 GitHub 个人资料中创建该存储库的副本。 + +## 将存储库克隆到您的本地机器上 + +在您的本地计算机上选择一个目录,然后克隆此存储库。 + +打开终端,导航到选择的目录,并输入以下命令: + +```bash +git clone https://github.com/[YOUR_GITHUB_NAME]/angular-challenges.git +``` + +:::note[注意] + +你可以通过点击Angular Challenges存储库中你自己的实例中的<> Code 按钮来找到克隆URL + +![Header of GitHub workspace](../../../../assets/header-github.png) + +::: + +## 在您最喜欢的IDE中打开该项目 + +使用您选择的任意集成开发环境(IDE)打开该项目。 + +## 安装所有依赖项 + +```bash +npm ci +``` + +## 选择一个挑战 + +您的项目现已启动并正在运行。剩下的唯一步骤是选择一个挑战 🚀 + +每项挑战包括: + +- Name: 表示挑战的内容。 +- Number: 创建顺序。 这个数字没有任何特别的含义,但有助于在 GitHub Pull Request 部分进行参考。 +- Badge: 有助于可视化难度程度。这完全是主观的 😅 + - 🟢 容易 + - 🟠 中等 + - 🔴 困难 + +## (交替) 使用 GitHub Codespaces + +在你自己的 Angular Challenges 存储库实例中,单击代码按钮并导航到 codespaces 选项卡。 + +![Codespaces tab](../../../../assets/codespaces.png) + +单击 `Create codespace on main` 按钮, 您将导航到 GitHub codespace + +如果您以前从未使用过 GitHub codespace,我建议您尝试这个简短的交互式 [GitHub Skills Tutorial](https://github.com/skills/code-with-codespaces). + +当您导航到codespace时,将出现一个提示,要求安装推荐的 `VS Code` 插件。如果您打算创建一个挑战,您可以使用 `Nx plugin` 来生成开始代码。无论哪种方式,codespace都将安装依赖项,你可以创建一个新分支,解决任何挑战,并创建一个pull request。 + +当您推送到分支时,您不必提供 GitHub 令牌。 + +一旦你完成,记得暂停或删除你的codesace。如果不这样做,GitHub将在30分钟后自动暂停空闲的codesace。你每个月确实有大量的免费codespace时间,但重要的是不要浪费你的分配时间 + +在GitHub codesace中,复制和粘贴将被阻止,直到你获得许可 + +GitHub codespace使用端口转发为项目提供服务。单击运行 `npx nx serve [project-name]` 后的提示符,导航到 `localhost:4200` 。 diff --git a/docs copy/src/content/docs/zh-cn/guides/rebase.md b/docs copy/src/content/docs/zh-cn/guides/rebase.md new file mode 100644 index 000000000..a88ec24a6 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/guides/rebase.md @@ -0,0 +1,57 @@ +--- +title: 变基分支 +description: 将分支变基到最新更改的指南 +contributors: + - tomalaforge +sidebar: + order: 6 +--- + +有时,可能会向项目添加更改。我会尝试做出不会破坏任何东西的更改,但有时这是不可避免的。 + +大多数情况下,您不需要变基您的解决方案,但这里有一个指南可以帮助您知道如何操作。 + +:::note[注意] +本指南适用于任何开源项目。 +::: + +## 变基分支的步骤 + +### 同步存储库 + +首先,你需要同步你的分支,以确保它与分支的存储库是最新的。 + +你可以通过点击你的fork主页面上的Sync fork按钮来实现这一点。 + +![Sync project header](../../../../assets/fork-sync.png) + +上图显示我的分支比主分支落后 8 个提交,我需要将其同步才能保持最新。 + +![Sync project update modal](../../../../assets/sync-fork-update.png) + +### 打开终端 + +打开您选择的任何终端,可以是您最喜欢的 IDE 中的终端,也可以是独立实例。 + +### Git + +请按照以下命令重新设置本地分支的基础: + +- git checkout main +- git pull +- git checkout [你的分支] +- git rebase main +- 解决冲突 + +在此步骤中,变基可能会停止,因为您的本地分支与主分支有冲突的文件。纠正它们。完成此操作后: + +- git add . +- git rebase --continue + +如果您的分支没有任何冲突,则会显示成功消息。 + +### 将你的工作推送到远程分支 + +最后,将你的工作推送到GitHub: + +- git push -f diff --git a/docs copy/src/content/docs/zh-cn/guides/resolve-challenge.md b/docs copy/src/content/docs/zh-cn/guides/resolve-challenge.md new file mode 100644 index 000000000..a943fb311 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/guides/resolve-challenge.md @@ -0,0 +1,107 @@ +--- +title: 解决挑战 +description: 解决挑战指南 +contributors: + - tomalaforge + - 1fbr + - gsgonzalez88 +sidebar: + order: 2 +--- + +在本指南中,您将学习如何解决挑战并向主GitHub存储库提交答案。 + +## 介绍 + +此存储库由 [Nx](https://nx.dev/getting-started/intro) 提供支持。Nx是一个 monorepository,允许您将多个应用程序存储在同一个工作区中。每个挑战都是一个单独的应用程序。如果您打开`apps`目录,您将找到多个目录,每个目录都与一个特定的挑战相关。每个目录都代表一个完整的独立的`Nx`应用程序。想要运行并从某个开始,请打开您的终端并运行: + +```bash +npx nx serve +``` + +:::note[注意] +如果您不确定 `APPLICATION_NAME` ,请打开README.md文件。 `serve` 命令写在那里,并有一个到挑战文档的链接。 +::: + +:::note[注意] + +如果您的设备已全局安装 `nx` ,则可以跳过使用 `npx` + +要全局安装 `nx` ,使用 + +```bash +npm i -g nx +``` + +::: + +## 创建 Git 分支 + +在你开始实现解决挑战的解决方案之前,创建一个git分支来提交你的工作。 + +```bash +git checkout -b +``` + +## 完成挑战 + +按照说明来完成挑战。 + +## 提交和推送您的工作 + +最后一步是按照常规的[指导方针](https://www.conventionalcommits.org/en/v1.0.0/)提交工作 + +最后,使用以下命令将工作推送到远程仓库 + +```bash + git push --set-upstream origin +``` + +:::tip[不用去记] +你不必精确地记住这个命令。你只需要记住 `git push` ,如果这是你第一次推送这个分支, `git` 将为你提供完整的命令。 +::: + +## 将您的工作提交到主仓库 + +现在,你所有的工作都位于Angular Challenges仓库的本地实例中。 + +下一步是转到Angular的主要[挑战页面](https://github.com/tomalaforge/angular-challenges),并创建一个新的Pull Request。 + +GitHub应该显示一个通知头来帮助你创建拉取请求。 + +如果不是这样,要么是你错误地执行了前面的某个步骤,要么你可以转到Pull Request选项卡并点击New pull request按钮 + +一旦你选择了要比较的两个分支,就会看到下面的页面: + +![New pull request screen](../../../../assets/new-pull-request.png) + +在标题部分,以Answer:开始,然后是你的挑战号。之后,您可以随意添加任何您想要的内容 + +:::danger[危险] +这非常重要。它让别人知道你试图解决的是什么挑战。 +::: + +在描述部分,您可以添加您遇到的问题、麻烦或任何其他您想要分享的内容。如果你没什么可说的,可以把它空着 + +现在你可以点击 Create pull request. + +## 获取审查 + +为了继续提供有价值的反馈和评论,请在Github上支持这个项目: + +
    +
  • 每次评论5美元
  • +
  • 终身评论25美元
  • +
  • 创建一个挑战/贡献终身评论
  • +
+ +:::note[注意] + +您仍然可以提交您的PR加入已回答的挑战列表。你仍然可以被社区成员审查🔥 + +欢迎大家评论和阅读其他PRs。💪 +::: + +:::tip[开源拥护者] +🔥完成本教程后,您就可以为任何其他公共GitHub存储库做出贡献并提交PR。就这么简单。🔥 +::: diff --git a/docs copy/src/content/docs/zh-cn/index.mdx b/docs copy/src/content/docs/zh-cn/index.mdx new file mode 100644 index 000000000..97abc22a3 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/index.mdx @@ -0,0 +1,79 @@ +--- +title: 欢迎来到 Angular 挑战 +description: 从解决这些挑战开始,成为一名更好的Angular前端工程师. +template: splash +noCommentSection: true +hero: + tagline: 现在就开始成为Angular专家吧! + image: + file: ../../../assets/angular-challenge.webp + actions: + - text: 开始 + link: /zh-cn/guides/getting-started/ + icon: right-arrow + variant: primary + - text: 进入最新的挑战 + link: /zh-cn/challenges/signal/56-forms-and-signal/ + icon: rocket + - text: 给个星星 + link: https://github.com/tomalaforge/angular-challenges + icon: github + variant: secondary +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; +import MyIcon from '../../../components/MyIcon.astro'; + +import SubscriptionForm from '../../../components/SubscriptionForm.astro'; + + + + 该存储库包含与Angular, Nx, RxJS, NgrxTypescript相关的56个挑战。这些挑战围绕现实生活中的问题或特定功能,旨在提升您的技能。 + + + + + + + + 这个存储库的一个目标是降低进入开放源码软件(OSS)的门槛。通过参与这些挑战,您将学习如何开始为其他任何开源项目做出贡献 + + + + 学习和实践一个新的框架总是具有挑战性的。这些挑战提供了实际使用案例,可以让你将所学的知识应用到实际中。 + 任何人都可以发表评论或提供帮助。 + + 独自学习固然很棒,但与他人一起学习会让你走得更远。 + + + + + 你有任何问题、有趣的bug或者想法吗?不要犹豫,{' '}不要浪费任何时间创造属于你自己的挑战。 + + + + 通过完成这些挑战,您将为前端面试中可能出现的任何技术问题做好准备 + + + + 这个项目是免费的,并且希望能够长期保持免费。然而,所有工作都是在我的业余时间完成的,包括创建挑战和审核合并请求(PR)。赞助可以支持我,并有助于项目的成长。 + + + +--- + + + + diff --git a/docs copy/src/content/docs/zh-cn/leaderboard/answers.mdx b/docs copy/src/content/docs/zh-cn/leaderboard/answers.mdx new file mode 100644 index 000000000..812043baf --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/leaderboard/answers.mdx @@ -0,0 +1,12 @@ +--- +title: 挑战的回答 +description: 排行榜显示已回答的挑战数量 +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardAnswer from '../../../../components/leaderboard/LeaderboardAnswer.svelte'; + +加入这个列表,通过阅读入门指南[开始](/zh-cn/guides/getting-started)你的Angular挑战之旅。 + diff --git a/docs copy/src/content/docs/zh-cn/leaderboard/challenges.mdx b/docs copy/src/content/docs/zh-cn/leaderboard/challenges.mdx new file mode 100644 index 000000000..ce97799d1 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/leaderboard/challenges.mdx @@ -0,0 +1,13 @@ +--- +title: 创建的挑战数量 +description: 排行榜显示创建的挑战数量 +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardChallenge from '../../../../components/leaderboard/LeaderboardChallenge.svelte'; + +缺少挑战,创建自己的挑战并登上排行榜!阅读创建挑战指南来学习如何[创建挑战](/zh-cn/guides/create-challenge)。 + + diff --git a/docs copy/src/content/docs/zh-cn/leaderboard/commit.mdx b/docs copy/src/content/docs/zh-cn/leaderboard/commit.mdx new file mode 100644 index 000000000..ea0448c99 --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/leaderboard/commit.mdx @@ -0,0 +1,13 @@ +--- +title: 贡献数量 +description: 显示贡献数量的排行榜 +noCommentSection: true +prev: false +next: false +--- + +import LeaderboardCommit from '../../../../components/leaderboard/LeaderboardCommit.svelte'; + +您想要改进项目,修复一个错别字,为一个挑战添加一些文档,或者翻译一个页面?这个排行榜显示了每个用户的贡献数量。这个存储库是开源的,您可以为它做出贡献。阅读贡献[贡献](/zh-cn/guides/contribute)指南开始。 + + diff --git a/docs copy/src/content/docs/zh-cn/subscription/index.mdx b/docs copy/src/content/docs/zh-cn/subscription/index.mdx new file mode 100644 index 000000000..1dde0610a --- /dev/null +++ b/docs copy/src/content/docs/zh-cn/subscription/index.mdx @@ -0,0 +1,10 @@ +--- +title: 订阅 +description: Email订阅 +noCommentSection: true +--- +import SubscriptionForm from '../../../../components/SubscriptionForm.astro' + +
如果您想了解新的挑战,可以订阅电子邮件
+ + diff --git a/docs copy/src/content/i18n/en.json b/docs copy/src/content/i18n/en.json new file mode 100644 index 000000000..86d43a40c --- /dev/null +++ b/docs copy/src/content/i18n/en.json @@ -0,0 +1,27 @@ +{ + "page.title.challenge": "Challenge", + "author.createdBy": "Created by", + "buttons.email": "Email subscription", + "buttons.star": "Give a star", + "buttons.sponsor": "Sponsor", + "buttons.clipboardCopy": "Copied!", + "challenge.footer.note": "Note", + "challenge.footer.running": "Start the project by executing:", + "challenge.footer.start": "The title of your PR must begin with", + "challenge.footer.reminder": "Reminder", + "challenge.footer.communityAnswers": "Community solutions", + "challenge.footer.authorAnswer": "Author's solution", + "challenge.footer.blogPost": "Article", + "challenge.footer.video": "Video", + "challenge.footer.gettingStarted.title": "To complete this challenge, start by reading: ", + "challenge.footer.gettingStarted.link": "Getting started", + "challenge.footer.upvoteAnswer": "You can upvote an answer with a 👍 if you like it", + "subscription.button": "Subscribe", + "subscription.email": "username@gmail.com", + "subscription.note.title": "Notes", + "subscription.note.description": "This email will only be used for sending new challenges updates", + "contributor.title": "Contributors", + "contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!", + "sponsors.description": "Big thanks to the people supporting this project: ", + "sponsors.joinButton": "Join the list" +} diff --git a/docs copy/src/content/i18n/es.json b/docs copy/src/content/i18n/es.json new file mode 100644 index 000000000..e015e338a --- /dev/null +++ b/docs copy/src/content/i18n/es.json @@ -0,0 +1,67 @@ +{ + "skipLink.label": "Saltar al contenido", + "search.label": "Búsqueda", + "search.shortcutLabel": "(Presiona / para Buscar)", + "search.cancelLabel": "Cancelar", + "search.devWarning": "La búsqueda solo está disponible en compilaciones para producción. \nIntenta hacer una compilación y vista previa del sitio para probarlo localmente.", + "themeSelect.accessibleLabel": "Seleccionar tema", + "themeSelect.dark": "Oscuro", + "themeSelect.light": "Claro", + "themeSelect.auto": "Automático", + "languageSelect.accessibleLabel": "Seleccionar idioma", + "menuButton.accessibleLabel": "Menú", + "sidebarNav.accessibleLabel": "Inicio", + "tableOfContents.onThisPage": "Contenido de la página", + "tableOfContents.overview": "Vista general", + "i18n.untranslatedContent": "El contenido de esta página no cuenta con una traducción en tu idioma.", + "page.editLink": "Editar página", + "page.lastUpdated": "Última actualización:", + "page.previousLink": "Anterior", + "page.nextLink": "Siguiente", + "404.text": "Página no encontrada. Por favor revisa la URL o intenta utilizando la barra de búsqueda.", + "expressiveCode.copyButtonCopied": "Copiado!", + "expressiveCode.copyButtonTooltip": "Copiar al portapapeles", + "expressiveCode.terminalWindowFallbackTitle": "Ventana de terminal", + "pagefind.clear_search": "Borrar", + "pagefind.load_more": "Cargar más resultados", + "pagefind.search_label": "Buscar en este sitio", + "pagefind.filters_label": "Filtros", + "pagefind.zero_results": "Sin resultados para tu búsqueda de [SEARCH_TERM]", + "pagefind.many_results": "[COUNT] resultados para tu búsqueda de [SEARCH_TERM]", + "pagefind.one_result": "[COUNT] resultado para tu búsqueda de [SEARCH_TERM]", + "pagefind.alt_search": "Sin resultados para tu búsqueda de [SEARCH_TERM]. Te estamos mostrando resultados para [DIFFERENT_TERM]", + "pagefind.search_suggestion": "Sin resultados para tu búsqueda de [SEARCH_TERM]. Intenta alguna de las siguientes búsquedas:", + "pagefind.searching": "Buscando [SEARCH_TERM]...", + "page.title.challenge": "Reto", + "author.createdBy": "Creado por", + "buttons.email": "Suscripción por correo", + "buttons.star": "Danos una estrella", + "buttons.sponsor": "Patrocínanos", + "buttons.clipboardCopy": "Copiado!", + "note": "Nota", + "running": "Inicia el proyecto ejecutando el siguiente comando:", + "start": "El título de tu PR debe iniciar con", + "reminder": "¡No lo olvides!", + "communityAnswers": "Respuestas de la comunidad", + "authorAnswer": "Respuesta del autor", + "blogPost": "Artículo", + "challenge.footer.note": "Nota", + "challenge.footer.running": "Inicia el proyecto ejecutando el siguiente comando:", + "challenge.footer.start": "El título de tu PR debe iniciar con", + "challenge.footer.reminder": "¡No lo olvides!", + "challenge.footer.communityAnswers": "Respuestas de la comunidad", + "challenge.footer.authorAnswer": "Respuesta del autor", + "challenge.footer.blogPost": "Artículo", + "challenge.footer.video": "Vídeo", + "challenge.footer.gettingStarted.title": "Para realizar este desafío, comienza por leer: ", + "challenge.footer.gettingStarted.link": "Inicio", + "challenge.footer.upvoteAnswer": "Puedes votar positivo una respuesta con un 👍 si te gusta", + "subscription.button": "Suscríbete", + "subscription.email": "usuario@gmail.com", + "subscription.note.title": "Notas", + "subscription.note.description": "Este correo se utilizará para informar acerca de nuevos retos", + "contributor.title": "Contributors", + "contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!", + "sponsors.description": "Big thanks to the people supporting this project: ", + "sponsors.joinButton": "Join the list" +} diff --git a/docs copy/src/content/i18n/fr.json b/docs copy/src/content/i18n/fr.json new file mode 100644 index 000000000..9be86272c --- /dev/null +++ b/docs copy/src/content/i18n/fr.json @@ -0,0 +1,27 @@ +{ + "page.title.challenge": "Challenge", + "author.createdBy": "Créé par", + "buttons.email": "Souscrire newsletter", + "buttons.star": "Met une étoile", + "buttons.sponsor": "Sponsorise", + "buttons.clipboardCopy": "Copier!", + "challenge.footer.note": "Note", + "challenge.footer.running": "Démarre le projet en exécutant:", + "challenge.footer.start": "Le titre de ta PR doit commencer par", + "challenge.footer.reminder": "Rappel", + "challenge.footer.communityAnswers": "Solution de la communauté", + "challenge.footer.authorAnswer": "Solution de l'auteur", + "challenge.footer.blogPost": "Article", + "challenge.footer.video": "Video", + "challenge.footer.gettingStarted.title": "Pour faire ce challenge, commencer par lire: ", + "challenge.footer.gettingStarted.link": "Comment Démarrer", + "challenge.footer.upvoteAnswer": "Vous pouvez voter pour une réponse avec un 👍 si vous l'aimez", + "subscription.button": "Souscrit", + "subscription.email": "username@gmail.com", + "subscription.note.title": "Notes", + "subscription.note.description": "Cet email ne sera utilisé que pour envoyer les nouveaux challenges", + "contributor.title": "Contributeurs", + "contributor.subtitle": "Merci à tous les contributeurs qui ont aidé à améliorer cette documentation !", + "sponsors.description": "Un grand merci aux personnes supportant le project: ", + "sponsors.joinButton": "Rejoins-les" +} diff --git a/docs copy/src/content/i18n/pt.json b/docs copy/src/content/i18n/pt.json new file mode 100644 index 000000000..65ed7cfbd --- /dev/null +++ b/docs copy/src/content/i18n/pt.json @@ -0,0 +1,28 @@ +{ + "page.title.challenge": "Desafio", + "author.createdBy": "Criado por", + "buttons.email": "Inscrição de Email", + "buttons.star": "Dar uma estrela", + "buttons.sponsor": "Patrocinar", + "buttons.clipboardCopy": "Copiado!", + "404.text": "Página não encontrada. Verifique a URL ou tente usar a barra de busca.", + "challenge.footer.note": "Nota", + "challenge.footer.running": "Rode o projeto executando o comando:", + "challenge.footer.start": "O título do seu PR deve começar com", + "challenge.footer.reminder": "Não esqueça", + "challenge.footer.communityAnswers": "Solução da Comunidade", + "challenge.footer.authorAnswer": "Solução do Autor do Desafio", + "challenge.footer.blogPost": "Artigo", + "challenge.footer.video": "Vídeo", + "challenge.footer.gettingStarted.title": "Para realizar este desafio, comece lendo: ", + "challenge.footer.gettingStarted.link": "Começando", + "challenge.footer.upvoteAnswer": "Você pode curtir uma resposta com 👍 se você gostar dela", + "subscription.button": "Inscrever-se", + "subscription.email": "usuario@gmail.com", + "subscription.note.title": "Notas", + "subscription.note.description": "Este email será apenas usado para enviar atualizações de novos desafios", + "contributor.title": "Contribuidores", + "contributor.subtitle": "Obrigado a todos os contribuidores que ajudaram a melhorar esta documentação!", + "sponsors.description": "Muito obrigado as pessoas que apoiam este projeto: ", + "sponsors.joinButton": "Juntar-se à lista" +} diff --git a/docs copy/src/content/i18n/ru.json b/docs copy/src/content/i18n/ru.json new file mode 100644 index 000000000..6c841cab8 --- /dev/null +++ b/docs copy/src/content/i18n/ru.json @@ -0,0 +1,28 @@ +{ + "page.title.challenge": "Испытание", + "author.createdBy": "Создано", + "buttons.email": "Подписаться на email рассылку", + "buttons.star": "Добавить звезду", + "buttons.sponsor": "Спонсировать", + "buttons.clipboardCopy": "Скопировано!", + "404.text": "Страница не найдена. Проверьте URL-адрес или воспользуйтесь строкой поиска.", + "challenge.footer.note": "Примечание", + "challenge.footer.running": "Запустите проект, выполнив команду:", + "challenge.footer.start": "Название вашего PR должно начинаться со слов", + "challenge.footer.reminder": "Не забудьте", + "challenge.footer.communityAnswers": "Решения сообщества", + "challenge.footer.authorAnswer": "Решение автора", + "challenge.footer.blogPost": "Статья", + "challenge.footer.video": "Видео", + "challenge.footer.gettingStarted.title": "Чтобы пройти это испытание, прочитайте:", + "challenge.footer.gettingStarted.link": "Первые шаги", + "challenge.footer.upvoteAnswer": "Вы можете проголосовать за ответ 👍 если он вам понравился", + "subscription.button": "Подписаться", + "subscription.email": "username@gmail.com", + "subscription.note.title": "Примечание", + "subscription.note.description": "Этот email будет использоваться только для сообщений о новых испытаниях", + "contributor.title": "Контрибьюторы", + "contributor.subtitle": "Спасибо всем контрибьюторам которые помогли сделать эту документацию лучше!", + "sponsors.description": "Big thanks to the people supporting this project: ", + "sponsors.joinButton": "Join the list" +} diff --git a/docs copy/src/content/i18n/zh-CN.json b/docs copy/src/content/i18n/zh-CN.json new file mode 100644 index 000000000..62cb71ec3 --- /dev/null +++ b/docs copy/src/content/i18n/zh-CN.json @@ -0,0 +1,27 @@ +{ + "page.title.challenge": "挑战", + "author.createdBy": "创建者", + "buttons.email": "Email 订阅", + "buttons.star": "给个星星", + "buttons.sponsor": "赞助", + "buttons.clipboardCopy": "已复制!", + "challenge.footer.note": "注意", + "challenge.footer.running": "通过执行启动项目:", + "challenge.footer.start": "您的 PR 标题开头必须是", + "challenge.footer.reminder": "提醒", + "challenge.footer.communityAnswers": "社区解决方案", + "challenge.footer.authorAnswer": "作者的解决方案", + "challenge.footer.blogPost": "文章", + "challenge.footer.video": "视频", + "challenge.footer.gettingStarted.title": "要完成这个挑战,开始阅读: ", + "challenge.footer.gettingStarted.link": "开始", + "challenge.footer.upvoteAnswer": "如果你喜欢,可以使用👍给答案投票", + "subscription.button": "订阅", + "subscription.email": "username@gmail.com", + "subscription.note.title": "注意", + "subscription.note.description": "此电子邮件将仅用于发送新的挑战更新", + "contributor.title": "贡献者", + "contributor.subtitle": "感谢所有帮助本文档变得更好的贡献者!", + "sponsors.description": "非常感谢支持这个项目的人: ", + "sponsors.joinButton": "加入列表" +} diff --git a/docs copy/src/env.d.ts b/docs copy/src/env.d.ts new file mode 100644 index 000000000..acef35f17 --- /dev/null +++ b/docs copy/src/env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/docs copy/src/pages/auth/authorize.js b/docs copy/src/pages/auth/authorize.js new file mode 100644 index 000000000..ec76aedae --- /dev/null +++ b/docs copy/src/pages/auth/authorize.js @@ -0,0 +1,21 @@ +import { toHexString } from '../../utils/encrypt'; + +export const prerender = false; + +const GITHUB_OAUTH_AUTHORIZE_URL = 'https://github.com/login/oauth/authorize'; + +export async function GET({url, redirect}) { + + const myUrl = new URL(url); + const params = new URLSearchParams(myUrl.search); + const redirectUrl = params.get('redirect_uri'); + + const { GITHUB_CLIENT_ID } = import.meta.env; + + + const redirect_uri = `${myUrl.origin}/auth/authorized` + const state = toHexString(redirectUrl); + + const oauthParams = new URLSearchParams({ client_id:GITHUB_CLIENT_ID , redirect_uri, state }); + return redirect(`${GITHUB_OAUTH_AUTHORIZE_URL}?${oauthParams}`, 302) +} diff --git a/docs copy/src/pages/auth/authorized.js b/docs copy/src/pages/auth/authorized.js new file mode 100644 index 000000000..f9a81223f --- /dev/null +++ b/docs copy/src/pages/auth/authorized.js @@ -0,0 +1,58 @@ +import { fromHexString } from '../../utils/encrypt'; + +export const prerender = false; + +const GITHUB_OAUTH_ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token'; + +export async function GET({ url, redirect, cookies}) { + + const myUrl = new URL(url); + const params = new URLSearchParams(myUrl.search); + const code = params.get('code'); + const state = params.get('state'); + const error = params.get('error'); + + const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = import.meta.env; + + const redirectUrl = new URL(fromHexString(state)); + + if (error && error === 'access_denied') { + redirect(redirectUrl.href, 302); + return; + } + + const init = { + method: 'POST', + body: new URLSearchParams({ client_id: GITHUB_CLIENT_ID, client_secret: GITHUB_CLIENT_SECRET , code, state }), + headers: { + Accept: 'application/json' + }, + }; + + let accessToken = ''; + let refreshToken = ''; + try { + const response = await fetch(GITHUB_OAUTH_ACCESS_TOKEN_URL, init); + if (response.ok) { + const data = await response.json(); + accessToken = data.access_token; + refreshToken = data.refresh_token; + } else { + throw new Error(`Access token response had status ${response.status}.`); + } + } catch (err) { + return new Response( + JSON.stringify({ + error: err.message + }), { + status: 503 + } + ) + } + + cookies.set('refresh', refreshToken, { secure: true, httpOnly: true, path: '/' }); + + redirectUrl.searchParams.set('token', accessToken); + + return redirect(redirectUrl.href, 302); +} diff --git a/docs copy/src/pages/auth/refresh.js b/docs copy/src/pages/auth/refresh.js new file mode 100644 index 000000000..c4dd69bbb --- /dev/null +++ b/docs copy/src/pages/auth/refresh.js @@ -0,0 +1,62 @@ +export const prerender = false; + +const GITHUB_OAUTH_REFRESH_TOKEN = 'https://github.com/login/oauth/access_token'; + +export async function GET({cookies}) { + + const refresh_token = cookies.get('refresh').value; + + const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = import.meta.env; + + + const init = { + method: 'POST', + body: new URLSearchParams({ client_id: GITHUB_CLIENT_ID, client_secret: GITHUB_CLIENT_SECRET, grant_type: "refresh_token" , refresh_token }), + headers: { + Accept: 'application/json' + }, + }; + + let accessToken = ''; + let refreshToken = ''; + try { + + const response = await fetch(GITHUB_OAUTH_REFRESH_TOKEN, init); + if (response.ok) { + const data = await response.json(); + if(data.error) { + cookies.delete('refresh'); + return new Response( + JSON.stringify({ + token: 'delete' + }), { + status: 200 + } + ) + } + + accessToken = data.access_token; + refreshToken = data.refresh_token; + } else { + throw new Error(`Access token response had status ${response.status}.`); + } + } catch (err) { + return new Response( + JSON.stringify({ + error: err.message + }), { + status: 503 + } + ) + } + + cookies.set('refresh', refreshToken, { secure: true, httpOnly: true, path: '/' }); + + return new Response( + JSON.stringify({ + token: accessToken + }), { + status: 200 + } + ) +} diff --git a/docs copy/src/styles/custom-css.css b/docs copy/src/styles/custom-css.css new file mode 100644 index 000000000..4083f9309 --- /dev/null +++ b/docs copy/src/styles/custom-css.css @@ -0,0 +1,192 @@ +:root { + --sl-color-black: #1b1b1d; + --sl-color-gray-6: #242526; + --sl-color-accent-high: #f10023; + --sl-icon-color: #fff; + --sl-color-text-invert: #fff; + --primary-color: var(--sl-color-bg-nav) !important; + --cardBgColor: #242526; + + --sl-color-green: #39a549; + --sl-hue-purple: 41; + --sl-color-purple-low: hsl(var(--sl-hue-orange), 39%, 22%); + --sl-color-purple: hsl(var(--sl-hue-orange), 82%, 63%); + --sl-color-purple-high: hsl(var(--sl-hue-orange), 82%, 87%); + + --color-btn: var(--sl-color-white); + --color-chip: rgb(35, 38, 47); + --color-chip-border: rgba(240, 246, 252, 0.1); + + --button-transition: opacity 100ms ease-in-out; + --button-hover-opacity: 0.85; +} + +:root[data-theme='light'], +[data-theme='light'] { + --sl-color-accent: #f10023; + --sl-color-accent-high: #f10023; + --sl-icon-color: rgb(35, 38, 47); + + --color-btn: white; + --color-chip: white; + --color-chip-border: rgb(33, 38, 45); +} + +html { + scroll-behavior: smooth; +} + +.github-success-btn { + border: 2px solid rgba(240, 246, 252, 0.1); + border-radius: 6px; + padding: 2px 8px; + background-color: rgb(35, 134, 54); + color: var(--color-btn); +} + +.github-neutral-btn { + border: 1px solid rgba(240, 246, 252, 0.1); + border-radius: 6px; + padding: 2px 8px; + background-color: rgb(33, 38, 45); + color: rgb(201, 209, 217); + fill: rgb(201, 209, 217); + display: inline-flex; + width: fit-content; + gap: 6px; + margin: 0px 2px; +} + +a.action, +.button-star, +.article-footer > a, +.button-hover > a.action-button { + transition: var(--button-transition); + + &:hover { + cursor: pointer; + opacity: var(--button-hover-opacity); + transition: var(--button-transition); + + &:not(.primary):not(.button-sponsor) { + opacity: 0.66; + } + } +} + +.article-footer { + margin-top: 3rem !important; + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 1.5rem; +} + +.article-footer > a { + border: 1px solid var(--sl-color-accent-high); + border-radius: 999rem; + padding: 1rem; + text-decoration: none; + color: var(--color-btn); + box-shadow: var(--sl-shadow-md); + font-size: var(--sl-text-lg); + line-height: var(--sl-line-height-headings); + display: flex; + gap: 0.5rem; + justify-content: center; + align-items: center; + margin-top: 0; + background-color: var(--sl-color-accent-high); + + &.action { + color: var(--color-btn); + } +} + +.article-footer > a > p { + margin: 0px !important; +} + +a.primary, +a.primary > svg { + color: var(--color-btn) !important; +} + +b { + color: var(--sl-color-accent-high) !important; +} + +.starlight-aside--tip b { + color: var(--sl-color-asides-text-accent); +} + +.main-page-footer { + margin-top: 2rem !important; + font-size: var(--sl-text-sm); + text-align: center; +} + +@media (max-width: 799px) { + .main-page-footer { + margin-top: 2rem !important; + font-size: var(--sl-text-xs); + } +} + +starlight-menu-button svg { + color: #1c1a1d; +} + +.right-sidebar-panel { + height: 100%; +} + +.right-sidebar-panel > div { + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.important-block { + border: solid 1px red; + padding: 16px; + background-color: #f100002e; +} + +.starlight-aside--note, +.starlight-aside--tip { + background-color: transparent; + border: solid 1px gray; + color: var(--sl-color-text); +} + +.starlight-aside--note .starlight-aside__title, +.starlight-aside--tip .starlight-aside__title { + color: var(--sl-color-white); +} + +.starlight-aside--danger { + background-color: #f100002e; + border: solid 1px red; + color: var(--sl-color-text); +} + +.starlight-aside--danger .starlight-aside__title { + color: red; +} + +details { + summary { + cursor: pointer; + } +} + +.body:where(.astro-v5tidmuc) { + height: 100%; +} + + +.astro-kmkmnagf { + align-items: center; +} diff --git a/docs copy/src/utils/encrypt.ts b/docs copy/src/utils/encrypt.ts new file mode 100644 index 000000000..99f5ab03f --- /dev/null +++ b/docs copy/src/utils/encrypt.ts @@ -0,0 +1,15 @@ +export function toHexString(value: string): string { + return value + .split('') + .map((c) => c.charCodeAt(0).toString(16).padStart(2, '0')) + .join(''); +} + +export function fromHexString(hexString: string): string { + return ( + hexString + .match(/.{1,2}/g) + ?.map((byte) => String.fromCharCode(parseInt(byte, 16))) + .join('') ?? '' + ); +} diff --git a/docs copy/svelte.config.js b/docs copy/svelte.config.js new file mode 100644 index 000000000..cbaee33df --- /dev/null +++ b/docs copy/svelte.config.js @@ -0,0 +1,5 @@ +import { vitePreprocess } from '@astrojs/svelte'; + +export default { + preprocess: vitePreprocess(), +}; diff --git a/docs copy/tsconfig.json b/docs copy/tsconfig.json new file mode 100644 index 000000000..b7243b92c --- /dev/null +++ b/docs copy/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "react" + } +} diff --git a/package-lock.json b/package-lock.json index 6c197da64..b8f6a22e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,11 +24,12 @@ "@ngneat/falso": "7.2.0", "@ngrx/component": "19.0.1", "@ngrx/component-store": "19.0.1", - "@ngrx/effects": "19.0.1", + "@ngrx/effects": "^19.0.1", "@ngrx/entity": "19.0.1", "@ngrx/operators": "19.0.1", "@ngrx/router-store": "19.0.1", - "@ngrx/store": "19.0.1", + "@ngrx/store": "^19.0.1", + "@ngrx/store-devtools": "^19.0.1", "@nx/angular": "20.6.4", "@swc/helpers": "0.5.12", "@tanstack/angular-query-experimental": "5.62.3", @@ -188,7 +189,6 @@ "version": "0.1902.5", "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.5.tgz", "integrity": "sha512-GdcTqwCZT0CTagUoTmq799hpnbQeICx53+eHsfs+lyKjkojk1ahC6ZOi4nNLDl/J2DIMFPHIG1ZgHPuhjKItAw==", - "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": "19.2.5", @@ -204,7 +204,6 @@ "version": "19.2.5", "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.2.5.tgz", "integrity": "sha512-PmLAaPuruTzEACsVe7MVyDuShQhyFdj83gWqvPKXVd8p2SIEE8SeVXyNRKNYf84cZdxqJB+IgjyvTPK7R7a+rA==", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", @@ -330,7 +329,6 @@ "version": "10.4.20", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "dev": true, "funding": [ { "type": "opencollective", @@ -368,7 +366,6 @@ "version": "8.5.2", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -397,7 +394,6 @@ "version": "0.1902.5", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1902.5.tgz", "integrity": "sha512-rXvUKRAgjhHTmBVr4HbZs+gS6sQ5EM+sv+Ygzl7oz7xC2+JOKBYiq+9B8Udk4GnW3Es9m6Dq7G4XbBMPzVia3Q==", - "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1902.5", @@ -417,7 +413,6 @@ "version": "19.2.5", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.5.tgz", "integrity": "sha512-s5d6ZQmut5QO7pcxssIoDgeVhVEjoQKxWpBeqsSdYxMYjROMR+QnlNcyiSDLI6Wc7QR9mZINOpx8yoj6Nim1Rw==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "8.17.1", @@ -445,7 +440,6 @@ "version": "19.2.5", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.5.tgz", "integrity": "sha512-gfWnbwDOuKyRZK0biVyiNIhV6kmI1VmHg1LLbJm3QK6jDL0JgXD0NudgL8ILl5Ksd1sJOwQAuzTLM5iPfB3hDA==", - "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": "19.2.5", @@ -551,7 +545,6 @@ "version": "19.2.5", "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.2.5.tgz", "integrity": "sha512-WtgdBHxFVMtbLzEYf1dYJqtld282aXxEbefsRi3RZWnLya8qO33bKMxpcd0V2iLIuIc1v/sUXPIzbWLO10mvTg==", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", @@ -714,7 +707,6 @@ "version": "19.2.4", "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.4.tgz", "integrity": "sha512-zIWWJm0L+OGMGoRJ73WW96+LDSmZsWqNpwYYXBAEzzoMtPMsWg8uiOIxxjF9ZUWQ1Y5ODUSADnBJwt5vtiLbzA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/core": "7.26.9", @@ -743,7 +735,6 @@ "version": "7.26.9", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -774,14 +765,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, "license": "MIT" }, "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -1214,7 +1203,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" @@ -1404,7 +1392,7 @@ "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1417,7 +1405,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1430,7 +1418,7 @@ "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" @@ -1443,7 +1431,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1504,7 +1492,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1517,7 +1505,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1545,7 +1533,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1558,7 +1546,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1571,7 +1559,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1584,7 +1572,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1597,7 +1585,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1610,7 +1598,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1623,7 +1611,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1639,7 +1627,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -2719,7 +2707,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@bufbuild/protobuf": { @@ -3049,7 +3037,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -3062,7 +3050,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -3686,7 +3674,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.17.0" @@ -3727,7 +3714,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3744,7 +3730,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3761,7 +3746,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3778,7 +3762,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3795,7 +3778,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3812,7 +3794,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3829,7 +3810,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3846,7 +3826,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3863,7 +3842,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3880,7 +3858,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3897,7 +3874,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3914,7 +3890,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3931,7 +3906,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3948,7 +3922,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3965,7 +3938,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3982,7 +3954,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3999,7 +3970,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4016,7 +3986,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4033,7 +4002,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4050,7 +4018,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4067,7 +4034,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4084,7 +4050,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4101,7 +4066,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4118,7 +4082,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4135,7 +4098,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4167,7 +4129,6 @@ "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -4177,7 +4138,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -4201,7 +4161,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -4218,7 +4177,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4229,7 +4187,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -4245,7 +4202,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -4258,14 +4214,12 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -4278,7 +4232,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -4291,7 +4244,6 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4322,7 +4274,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "deprecated": "Use @eslint/config-array instead", - "dev": true, "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", @@ -4337,7 +4288,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4348,7 +4298,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -4361,7 +4310,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -4376,7 +4324,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/@inquirer/checkbox": { @@ -4408,7 +4355,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.6.tgz", "integrity": "sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^10.1.7", @@ -4430,7 +4376,6 @@ "version": "10.1.9", "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.9.tgz", "integrity": "sha512-sXhVB8n20NYkUBfDYgizGHlpRVaCRjtuzNZA6xpALIUbkgfd2Hjz+DfEN6+h1BRnuxw0/P4jCIMjMsEOAMwAJw==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/figures": "^1.0.11", @@ -4504,7 +4449,6 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.11.tgz", "integrity": "sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -4683,7 +4627,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.5.tgz", "integrity": "sha512-ZJpeIYYueOz/i/ONzrfof8g89kNdO2hjGuvULROo3O8rlB2CRtSseE5KeirnyE4t/thAn/EwvS/vuQeJCn+NZg==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -4810,7 +4753,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "camelcase": "^5.3.1", @@ -4827,7 +4770,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -4841,7 +4784,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -4854,7 +4797,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -4870,7 +4813,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -4883,7 +4826,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4893,7 +4835,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -4911,7 +4853,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -4959,7 +4901,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -4972,7 +4914,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -4988,7 +4930,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -5003,14 +4945,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@jest/environment": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", @@ -5026,7 +4968,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "expect": "^29.7.0", @@ -5040,7 +4982,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" @@ -5053,7 +4995,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -5071,7 +5013,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -5087,7 +5029,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -5143,7 +5085,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -5158,7 +5100,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -5174,7 +5116,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -5190,7 +5132,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -5217,7 +5159,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@jest/types": { @@ -5401,7 +5343,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5415,7 +5356,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5429,7 +5369,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5443,7 +5382,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5457,7 +5395,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5471,7 +5408,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5479,13 +5415,13 @@ ] }, "node_modules/@modern-js/node-bundle-require": { - "version": "2.65.1", - "resolved": "https://registry.npmjs.org/@modern-js/node-bundle-require/-/node-bundle-require-2.65.1.tgz", - "integrity": "sha512-XpEkciVEfDbkkLUI662ZFlI9tXsUQtLXk4NRJDBGosNnk9uL2XszmC8sKsdCSLK8AYuPW2w6MTVWuJsOR0EU8A==", + "version": "2.67.6", + "resolved": "https://registry.npmjs.org/@modern-js/node-bundle-require/-/node-bundle-require-2.67.6.tgz", + "integrity": "sha512-rRiDQkrm3kgn0E/GNrcvqo4c71PaUs2R8Xmpv6GUKbEr6lz7VNgfZmAhdAQPtNfRfiBe+1sFLzEcwfEdDo/dTA==", "license": "MIT", "dependencies": { - "@modern-js/utils": "2.65.1", - "@swc/helpers": "0.5.13", + "@modern-js/utils": "2.67.6", + "@swc/helpers": "^0.5.17", "esbuild": "0.17.19" } }, @@ -5842,12 +5778,12 @@ } }, "node_modules/@modern-js/node-bundle-require/node_modules/@swc/helpers": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", - "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, "node_modules/@modern-js/node-bundle-require/node_modules/esbuild": { @@ -5888,24 +5824,24 @@ } }, "node_modules/@modern-js/utils": { - "version": "2.65.1", - "resolved": "https://registry.npmjs.org/@modern-js/utils/-/utils-2.65.1.tgz", - "integrity": "sha512-HrChf19F+6nALo5XPra8ycjhXGQfGi23+S7Y2FLfTKe8vaNnky8duT/XvRWpbS4pp3SQj8ryO8m/qWSsJ1Rogw==", + "version": "2.67.6", + "resolved": "https://registry.npmjs.org/@modern-js/utils/-/utils-2.67.6.tgz", + "integrity": "sha512-cxY7HsSH0jIN3rlL6RZ0tgzC1tH0gHW++8X6h7sXCNCylhUdbGZI9yTGbpAS8bU7c97NmPaTKg+/ILt00Kju1Q==", "license": "MIT", "dependencies": { - "@swc/helpers": "0.5.13", + "@swc/helpers": "^0.5.17", "caniuse-lite": "^1.0.30001520", "lodash": "^4.17.21", "rslog": "^1.1.0" } }, "node_modules/@modern-js/utils/node_modules/@swc/helpers": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", - "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, "node_modules/@module-federation/bridge-react-webpack-plugin": { @@ -5932,14 +5868,14 @@ } }, "node_modules/@module-federation/cli": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/cli/-/cli-0.11.2.tgz", - "integrity": "sha512-dIM58VawvWM+UdftVQ/tW8A07LrYRE1260DKJ6feRGbu9NoMV/M35WaNO5HKGHsk1kptXzbZoykkateo7TabrA==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/cli/-/cli-0.16.0.tgz", + "integrity": "sha512-4H9i7vgkRqvVk8VcbGl8LoFZOwLXnXOyefIwQdpxAyG3i99AzuUScTaD2/uGNq/fM+iybo8DGyWy/P6leNHqBQ==", "license": "MIT", "dependencies": { - "@modern-js/node-bundle-require": "2.65.1", - "@module-federation/dts-plugin": "0.11.2", - "@module-federation/sdk": "0.11.2", + "@modern-js/node-bundle-require": "2.67.6", + "@module-federation/dts-plugin": "0.16.0", + "@module-federation/sdk": "0.16.0", "chalk": "3.0.0", "commander": "11.1.0" }, @@ -5951,22 +5887,22 @@ } }, "node_modules/@module-federation/cli/node_modules/@module-federation/dts-plugin": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.11.2.tgz", - "integrity": "sha512-djZZDq8pTpjfDfXoU2knVOAmjoDWvJHcVScbCNI8zjOtwTvvH26EeOfQligiQxdhsCuGf+MQpeP4o6wqWeJW6w==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.16.0.tgz", + "integrity": "sha512-A5ToViydF/JSdnrpxSKx4y38bGAs9CMXdWetrf9mD0Ha15aB3LQDn+1dFzUaiUk4bHblbzRB6BZnKFy7rPzB8g==", "license": "MIT", "dependencies": { - "@module-federation/error-codes": "0.11.2", - "@module-federation/managers": "0.11.2", - "@module-federation/sdk": "0.11.2", - "@module-federation/third-party-dts-extractor": "0.11.2", + "@module-federation/error-codes": "0.16.0", + "@module-federation/managers": "0.16.0", + "@module-federation/sdk": "0.16.0", + "@module-federation/third-party-dts-extractor": "0.16.0", "adm-zip": "^0.5.10", "ansi-colors": "^4.1.3", "axios": "^1.8.2", "chalk": "3.0.0", "fs-extra": "9.1.0", "isomorphic-ws": "5.0.0", - "koa": "2.15.4", + "koa": "2.16.1", "lodash.clonedeepwith": "4.5.0", "log4js": "6.9.1", "node-schedule": "2.1.1", @@ -5984,32 +5920,32 @@ } }, "node_modules/@module-federation/cli/node_modules/@module-federation/error-codes": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.11.2.tgz", - "integrity": "sha512-ik1Qnn0I+WyEdprTck9WGlH41vGsVdUg8cfO+ZM02qOb2cZm5Vu3SlxGAobj6g7uAj0g8yINnd7h7Dci40BxQA==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.16.0.tgz", + "integrity": "sha512-TfmA45b8vvISniGudMg8jjIy1q3tLPon0QN/JdFp5f8AJ8/peICN5b+dkEQnWsAVg2fEusYhk9dO7z3nUeJM8A==", "license": "MIT" }, "node_modules/@module-federation/cli/node_modules/@module-federation/managers": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.11.2.tgz", - "integrity": "sha512-nFi0dRgNWpLy0KB85tWhuqbQztTSsUixcbheu/ZSCjVVWShFN6Va2lZg0XyUlXFX/fy4vKrwMBBE5LXxXNubRw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.16.0.tgz", + "integrity": "sha512-ySWz7j+D9CjKDWgSKkAOTIn7m1Jd8BTNglcsMK66jL3Z76kYFX+oUtogJXu5mV/MiHUkTyp6Pv8AEeaTArdgBw==", "license": "MIT", "dependencies": { - "@module-federation/sdk": "0.11.2", + "@module-federation/sdk": "0.16.0", "find-pkg": "2.0.0", "fs-extra": "9.1.0" } }, "node_modules/@module-federation/cli/node_modules/@module-federation/sdk": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.2.tgz", - "integrity": "sha512-SBFe5xOamluT900J4AGBx+2/kCH/JbfqXoUwPSAC6PRzb8Y7LB0posnOGzmqYsLZXT37vp3d6AmJDsVoajDqxw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.16.0.tgz", + "integrity": "sha512-UXJW1WWuDoDmScX0tpISjl4xIRPzAiN62vg9etuBdAEUM+ja9rz/zwNZaByiUPFS2aqlj2RHenCRvIapE8mYEg==", "license": "MIT" }, "node_modules/@module-federation/cli/node_modules/@module-federation/third-party-dts-extractor": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.11.2.tgz", - "integrity": "sha512-rZuFRH43s68O2KED054Pgd9mV18NWME7Q9ZPuAzN1NGNH/J7Nevyt5MJXrHIaopF/2QpcrYNVjIgdqpRp9FJBg==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.16.0.tgz", + "integrity": "sha512-Q/stS4DshYCHWmsHnd7sbtbBieB4XjQ7cf5EZzWDd9DVpRaghXbt4rDhP+Vwcg2MM6RvmxQFcapiILMBzxMvJQ==", "license": "MIT", "dependencies": { "find-pkg": "2.0.0", @@ -6039,6 +5975,15 @@ "node": ">=16" } }, + "node_modules/@module-federation/cli/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/@module-federation/cli/node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -6054,6 +5999,65 @@ "node": ">=10" } }, + "node_modules/@module-federation/cli/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@module-federation/cli/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@module-federation/cli/node_modules/koa": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.1.tgz", + "integrity": "sha512-umfX9d3iuSxTQP4pnzLOz0HKnPg0FaUUIKcye2lOiz3KPu1Y3M3xlz76dISdFPQs37P9eJz1wUpcTS6KDPn9fA==", + "license": "MIT", + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, "node_modules/@module-federation/cli/node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -6071,6 +6075,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/@module-federation/cli/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/@module-federation/data-prefetch": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-0.9.1.tgz", @@ -6266,15 +6279,14 @@ } }, "node_modules/@module-federation/node": { - "version": "2.6.31", - "resolved": "https://registry.npmjs.org/@module-federation/node/-/node-2.6.31.tgz", - "integrity": "sha512-La+sF0AVW6mAj70WhtNHohMyqevadi9g6X1q42r0N2YaZMx5h/mqRIw/m04/SJOT4D1bSqD7+/VoSBFy9YhnDQ==", + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/@module-federation/node/-/node-2.7.8.tgz", + "integrity": "sha512-z1b8vvzswPmHqwegQCJ7M/doJ1uTJilyEXAzS0STmWzYTV16I4I6IalIgOjHr8JknMzs7GfF2ja1S+2AjiEfrg==", "license": "MIT", "dependencies": { - "@module-federation/enhanced": "0.11.2", - "@module-federation/runtime": "0.11.2", - "@module-federation/sdk": "0.11.2", - "@module-federation/utilities": "3.1.49", + "@module-federation/enhanced": "0.16.0", + "@module-federation/runtime": "0.16.0", + "@module-federation/sdk": "0.16.0", "btoa": "1.2.1", "encoding": "^0.1.13", "node-fetch": "2.7.0" @@ -6297,24 +6309,24 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/bridge-react-webpack-plugin": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.11.2.tgz", - "integrity": "sha512-XDJC01XsByG9IwtpWgoTrZdGecN7fmfOEbs/MFLvPAkn9RhPoMJ6X76MSlpsOkwFxK1T7YLkgpVXwdiZKVVXUg==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.16.0.tgz", + "integrity": "sha512-4HP5keHby66ql5NTe3sXgRaSbWuYCxwIrhO+TI5FsJyBVmVlHuc6ZxhdbV7ssU/u4u2ri0qPL9x1ALwnNie/pw==", "license": "MIT", "dependencies": { - "@module-federation/sdk": "0.11.2", + "@module-federation/sdk": "0.16.0", "@types/semver": "7.5.8", "semver": "7.6.3" } }, "node_modules/@module-federation/node/node_modules/@module-federation/data-prefetch": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-0.11.2.tgz", - "integrity": "sha512-3HiKo/F51MMjy3Os9sELzxfaSiOcpDXT2zTAvedm4h1XT+nGXq04cKcOQ6rhjl91npKP2wOo/2sE3pWYzrnPhw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-0.16.0.tgz", + "integrity": "sha512-+6dxkU5MEORhx5/wrQVMxY/7vW7P23dxn+VCMCtH0FLhocYbyhVtJD+ecEVKI2ZV6WvLRS472u24Fz6C4QJq5A==", "license": "MIT", "dependencies": { - "@module-federation/runtime": "0.11.2", - "@module-federation/sdk": "0.11.2", + "@module-federation/runtime": "0.16.0", + "@module-federation/sdk": "0.16.0", "fs-extra": "9.1.0" }, "peerDependencies": { @@ -6323,22 +6335,22 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/dts-plugin": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.11.2.tgz", - "integrity": "sha512-djZZDq8pTpjfDfXoU2knVOAmjoDWvJHcVScbCNI8zjOtwTvvH26EeOfQligiQxdhsCuGf+MQpeP4o6wqWeJW6w==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.16.0.tgz", + "integrity": "sha512-A5ToViydF/JSdnrpxSKx4y38bGAs9CMXdWetrf9mD0Ha15aB3LQDn+1dFzUaiUk4bHblbzRB6BZnKFy7rPzB8g==", "license": "MIT", "dependencies": { - "@module-federation/error-codes": "0.11.2", - "@module-federation/managers": "0.11.2", - "@module-federation/sdk": "0.11.2", - "@module-federation/third-party-dts-extractor": "0.11.2", + "@module-federation/error-codes": "0.16.0", + "@module-federation/managers": "0.16.0", + "@module-federation/sdk": "0.16.0", + "@module-federation/third-party-dts-extractor": "0.16.0", "adm-zip": "^0.5.10", "ansi-colors": "^4.1.3", "axios": "^1.8.2", "chalk": "3.0.0", "fs-extra": "9.1.0", "isomorphic-ws": "5.0.0", - "koa": "2.15.4", + "koa": "2.16.1", "lodash.clonedeepwith": "4.5.0", "log4js": "6.9.1", "node-schedule": "2.1.1", @@ -6356,23 +6368,24 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/enhanced": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-0.11.2.tgz", - "integrity": "sha512-OlISmj/d0egdGkUOgnVxvyCmoo+eMNBMpiCS3pQj4cnVN4NMs67qxioOD4Q5p04Tzc2jSot2LzRcBM44aTNN2A==", - "license": "MIT", - "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "0.11.2", - "@module-federation/cli": "0.11.2", - "@module-federation/data-prefetch": "0.11.2", - "@module-federation/dts-plugin": "0.11.2", - "@module-federation/error-codes": "0.11.2", - "@module-federation/inject-external-runtime-core-plugin": "0.11.2", - "@module-federation/managers": "0.11.2", - "@module-federation/manifest": "0.11.2", - "@module-federation/rspack": "0.11.2", - "@module-federation/runtime-tools": "0.11.2", - "@module-federation/sdk": "0.11.2", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-0.16.0.tgz", + "integrity": "sha512-ShkQeNXDBLmKMpOF3B+omXU59lVvogsEzRNmNxnnTNz+/zd/MgHxLwOLcNr2bNxdDPk0Ejz/n9GXG4YQKDaJpA==", + "license": "MIT", + "dependencies": { + "@module-federation/bridge-react-webpack-plugin": "0.16.0", + "@module-federation/cli": "0.16.0", + "@module-federation/data-prefetch": "0.16.0", + "@module-federation/dts-plugin": "0.16.0", + "@module-federation/error-codes": "0.16.0", + "@module-federation/inject-external-runtime-core-plugin": "0.16.0", + "@module-federation/managers": "0.16.0", + "@module-federation/manifest": "0.16.0", + "@module-federation/rspack": "0.16.0", + "@module-federation/runtime-tools": "0.16.0", + "@module-federation/sdk": "0.16.0", "btoa": "^1.2.1", + "schema-utils": "^4.3.0", "upath": "2.0.1" }, "bin": { @@ -6396,57 +6409,57 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/error-codes": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.11.2.tgz", - "integrity": "sha512-ik1Qnn0I+WyEdprTck9WGlH41vGsVdUg8cfO+ZM02qOb2cZm5Vu3SlxGAobj6g7uAj0g8yINnd7h7Dci40BxQA==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.16.0.tgz", + "integrity": "sha512-TfmA45b8vvISniGudMg8jjIy1q3tLPon0QN/JdFp5f8AJ8/peICN5b+dkEQnWsAVg2fEusYhk9dO7z3nUeJM8A==", "license": "MIT" }, "node_modules/@module-federation/node/node_modules/@module-federation/inject-external-runtime-core-plugin": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/inject-external-runtime-core-plugin/-/inject-external-runtime-core-plugin-0.11.2.tgz", - "integrity": "sha512-3rUWjos0mb2apXpgebWzGmqXx+8Ky2re4b4QxM8pwsE/9HFn18E/HGURJ/5Ur3Xhw81NjIAVVKxKg3bYSqjVuQ==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/inject-external-runtime-core-plugin/-/inject-external-runtime-core-plugin-0.16.0.tgz", + "integrity": "sha512-kVW5DTxg1K/sqadVvg/r2s5ArZVH4VaVsw+/24dllfUQwn7opVorVMrI491zqz8NpSBjN2MHykWMLPQnSW659g==", "license": "MIT", "peerDependencies": { - "@module-federation/runtime-tools": "0.11.2" + "@module-federation/runtime-tools": "0.16.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/managers": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.11.2.tgz", - "integrity": "sha512-nFi0dRgNWpLy0KB85tWhuqbQztTSsUixcbheu/ZSCjVVWShFN6Va2lZg0XyUlXFX/fy4vKrwMBBE5LXxXNubRw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.16.0.tgz", + "integrity": "sha512-ySWz7j+D9CjKDWgSKkAOTIn7m1Jd8BTNglcsMK66jL3Z76kYFX+oUtogJXu5mV/MiHUkTyp6Pv8AEeaTArdgBw==", "license": "MIT", "dependencies": { - "@module-federation/sdk": "0.11.2", + "@module-federation/sdk": "0.16.0", "find-pkg": "2.0.0", "fs-extra": "9.1.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/manifest": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-0.11.2.tgz", - "integrity": "sha512-5yDbq0MmlmCihRJDhFsuJEIGVjZkylybeHn7hwH0LHTtWAClc7APeXDKh7jPHVgOVmgcQBqaIqyHPeuantVydw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-0.16.0.tgz", + "integrity": "sha512-O9UY4JDlzXmZWzxuvG9dqGForZWcz0Lh5IU9GyPOCDNysVLAejwuwO/Vptohs0D2T3C8U0x/Bd29XqOVu3J/kw==", "license": "MIT", "dependencies": { - "@module-federation/dts-plugin": "0.11.2", - "@module-federation/managers": "0.11.2", - "@module-federation/sdk": "0.11.2", + "@module-federation/dts-plugin": "0.16.0", + "@module-federation/managers": "0.16.0", + "@module-federation/sdk": "0.16.0", "chalk": "3.0.0", "find-pkg": "2.0.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/rspack": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-0.11.2.tgz", - "integrity": "sha512-oEQXufLbAM7MXDVkE5qE+K3ItrWxlSOHL9db8voo20LvaOe3vwr4rILTj3Ou2Rev4QpLY4eMO7HIwPJBTb6ncQ==", - "license": "MIT", - "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "0.11.2", - "@module-federation/dts-plugin": "0.11.2", - "@module-federation/inject-external-runtime-core-plugin": "0.11.2", - "@module-federation/managers": "0.11.2", - "@module-federation/manifest": "0.11.2", - "@module-federation/runtime-tools": "0.11.2", - "@module-federation/sdk": "0.11.2", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-0.16.0.tgz", + "integrity": "sha512-42JiUVqVevosbwxNKV2KxOyrE6BGQXneUjg8AE7+K9pm4p0j180se5xpFerDMQf2blU4gJs4Wjgpj5q1EFQLUw==", + "license": "MIT", + "dependencies": { + "@module-federation/bridge-react-webpack-plugin": "0.16.0", + "@module-federation/dts-plugin": "0.16.0", + "@module-federation/inject-external-runtime-core-plugin": "0.16.0", + "@module-federation/managers": "0.16.0", + "@module-federation/manifest": "0.16.0", + "@module-federation/runtime-tools": "0.16.0", + "@module-federation/sdk": "0.16.0", "btoa": "1.2.1" }, "peerDependencies": { @@ -6464,46 +6477,46 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.11.2.tgz", - "integrity": "sha512-Ya9u/L6z2LvhgpqxuKCB7LcigIIRf1BbaxAZIH7mzbq/A7rZtTP7v+73E433jvgiAlbAfPSZkeoYGele6hfRwA==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.16.0.tgz", + "integrity": "sha512-6o84WI8Qhc9O3HwPLx89kTvOSkyUOHQr73R/zr0I04sYhlMJgw5xTwXeGE7bQAmNgbJclzW9Kh7JTP7+3o3CHg==", "license": "MIT", "dependencies": { - "@module-federation/error-codes": "0.11.2", - "@module-federation/runtime-core": "0.11.2", - "@module-federation/sdk": "0.11.2" + "@module-federation/error-codes": "0.16.0", + "@module-federation/runtime-core": "0.16.0", + "@module-federation/sdk": "0.16.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime-core": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.11.2.tgz", - "integrity": "sha512-dia5kKybi6MFU0s5PgglJwN27k7n9Sf69Cy5xZ4BWaP0qlaXTsxHKO0PECHNt2Pt8jDdyU29sQ4DwAQfxpnXJQ==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.16.0.tgz", + "integrity": "sha512-5SECQowG4hlUVBRk/y6bnYLfxbsl5NcMmqn043WPe7NDOhGQWbTuYibJ3Bk+ZBv5U4uYLEmXipBGDc1FKsHklQ==", "license": "MIT", "dependencies": { - "@module-federation/error-codes": "0.11.2", - "@module-federation/sdk": "0.11.2" + "@module-federation/error-codes": "0.16.0", + "@module-federation/sdk": "0.16.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime-tools": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.11.2.tgz", - "integrity": "sha512-4MJTGAxVq6vxQRkTtTlH7Mm9AVqgn0X9kdu+7RsL7T/qU+jeYsbrntN2CWG3GVVA8r5JddXyTI1iJ0VXQZLV1w==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.16.0.tgz", + "integrity": "sha512-OzmXNluXBQ2E6znzX4m9CJt1MFHVGmbN8c8MSKcYIDcLzLSKBQAiaz9ZUMhkyWx2YrPgD134glyPEqJrc+fY8A==", "license": "MIT", "dependencies": { - "@module-federation/runtime": "0.11.2", - "@module-federation/webpack-bundler-runtime": "0.11.2" + "@module-federation/runtime": "0.16.0", + "@module-federation/webpack-bundler-runtime": "0.16.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/sdk": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.2.tgz", - "integrity": "sha512-SBFe5xOamluT900J4AGBx+2/kCH/JbfqXoUwPSAC6PRzb8Y7LB0posnOGzmqYsLZXT37vp3d6AmJDsVoajDqxw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.16.0.tgz", + "integrity": "sha512-UXJW1WWuDoDmScX0tpISjl4xIRPzAiN62vg9etuBdAEUM+ja9rz/zwNZaByiUPFS2aqlj2RHenCRvIapE8mYEg==", "license": "MIT" }, "node_modules/@module-federation/node/node_modules/@module-federation/third-party-dts-extractor": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.11.2.tgz", - "integrity": "sha512-rZuFRH43s68O2KED054Pgd9mV18NWME7Q9ZPuAzN1NGNH/J7Nevyt5MJXrHIaopF/2QpcrYNVjIgdqpRp9FJBg==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.16.0.tgz", + "integrity": "sha512-Q/stS4DshYCHWmsHnd7sbtbBieB4XjQ7cf5EZzWDd9DVpRaghXbt4rDhP+Vwcg2MM6RvmxQFcapiILMBzxMvJQ==", "license": "MIT", "dependencies": { "find-pkg": "2.0.0", @@ -6512,13 +6525,13 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/webpack-bundler-runtime": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.11.2.tgz", - "integrity": "sha512-WdwIE6QF+MKs/PdVu0cKPETF743JB9PZ62/qf7Uo3gU4fjsUMc37RnbJZ/qB60EaHHfjwp1v6NnhZw1r4eVsnw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.16.0.tgz", + "integrity": "sha512-yqIDQTelJZP0Rxml0OXv4Er8Kbdxy7NFh6PCzPwDFWI1SkiokJ3uXQJBvtlxZ3lOnCDYOzdHstqa8sJG4JP02Q==", "license": "MIT", "dependencies": { - "@module-federation/runtime": "0.11.2", - "@module-federation/sdk": "0.11.2" + "@module-federation/runtime": "0.16.0", + "@module-federation/sdk": "0.16.0" } }, "node_modules/@module-federation/node/node_modules/chalk": { @@ -6534,6 +6547,15 @@ "node": ">=8" } }, + "node_modules/@module-federation/node/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/@module-federation/node/node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -6549,6 +6571,65 @@ "node": ">=10" } }, + "node_modules/@module-federation/node/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@module-federation/node/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@module-federation/node/node_modules/koa": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.1.tgz", + "integrity": "sha512-umfX9d3iuSxTQP4pnzLOz0HKnPg0FaUUIKcye2lOiz3KPu1Y3M3xlz76dISdFPQs37P9eJz1wUpcTS6KDPn9fA==", + "license": "MIT", + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, "node_modules/@module-federation/node/node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -6578,6 +6659,15 @@ "node": ">=10" } }, + "node_modules/@module-federation/node/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/@module-federation/rspack": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-0.9.1.tgz", @@ -6686,37 +6776,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@module-federation/utilities": { - "version": "3.1.49", - "resolved": "https://registry.npmjs.org/@module-federation/utilities/-/utilities-3.1.49.tgz", - "integrity": "sha512-1fhrrQaXe3F1Z7mkgiwtQf3HmFeTRP6lUdGBu1BvKOK66IMIXlncDUoPKijKoU6xvoQsn9SEooQmGzO2MiTVQA==", - "license": "MIT", - "dependencies": { - "@module-federation/sdk": "0.11.2" - }, - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "react-dom": "^16 || ^17 || ^18", - "webpack": "^5.40.0" - }, - "peerDependenciesMeta": { - "next": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@module-federation/utilities/node_modules/@module-federation/sdk": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.2.tgz", - "integrity": "sha512-SBFe5xOamluT900J4AGBx+2/kCH/JbfqXoUwPSAC6PRzb8Y7LB0posnOGzmqYsLZXT37vp3d6AmJDsVoajDqxw==", - "license": "MIT" - }, "node_modules/@module-federation/webpack-bundler-runtime": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.9.1.tgz", @@ -6734,7 +6793,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6748,7 +6806,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6762,7 +6819,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6776,7 +6832,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6790,7 +6845,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6804,7 +6858,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7223,11 +7276,24 @@ "rxjs": "^6.5.3 || ^7.5.0" } }, + "node_modules/@ngrx/store-devtools": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-19.0.1.tgz", + "integrity": "sha512-afvr6NHh12LpYrOH9JKKEEi/z2DHq/wJ45hRn3mrcRDArQTKpTl7V2eu0dYgjGItSRSeJ2drzzKGjccL61PPSg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/core": "^19.0.0", + "@ngrx/store": "19.0.1", + "rxjs": "^6.5.3 || ^7.5.0" + } + }, "node_modules/@ngtools/webpack": { "version": "19.2.5", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.2.5.tgz", "integrity": "sha512-rp9hRFJiUzRrlUBbM3c4BSt/zB93GLM1X9eb+JQOwBsoQhRL92VU9kkffGDpK14hf6uB4goQ00AvQ4lEnxlUag==", - "dev": true, "license": "MIT", "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0", @@ -9185,7 +9251,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.1.0" @@ -9206,7 +9272,7 @@ "version": "5.1.4", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -9232,7 +9298,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9246,7 +9311,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9260,7 +9324,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9274,7 +9337,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9288,7 +9350,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9302,7 +9363,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9316,7 +9376,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9330,7 +9389,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9344,7 +9402,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9358,7 +9415,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9372,7 +9428,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9386,7 +9441,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9400,7 +9454,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9414,7 +9467,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9428,7 +9480,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9442,7 +9493,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9456,7 +9506,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9470,7 +9519,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9484,7 +9532,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -9495,7 +9542,7 @@ "version": "4.37.0", "resolved": "https://registry.npmjs.org/@rollup/wasm-node/-/wasm-node-4.37.0.tgz", "integrity": "sha512-Nzbex+bqQ2wffHfAX5nHUMhcAUwedzE02arkETjt/ybjD0ieWtXwRUgIipB7giMRqKLdopDmkSIWow0mxzWmLg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.6" @@ -9515,7 +9562,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@rspack/binding": { @@ -9725,63 +9772,138 @@ } }, "node_modules/@rspack/dev-server": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rspack/dev-server/-/dev-server-1.1.0.tgz", - "integrity": "sha512-/IMfxE5SWhZ0+6xrlJzsJwJV7a0FpsY51gDBmsjGTCCa+V8ucXNxS2233V4YG/ESAM4URJEKaHzNLAGtwCSW1g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@rspack/dev-server/-/dev-server-1.1.3.tgz", + "integrity": "sha512-jWPeyiZiGpbLYGhwHvwxhaa4rsr8CQvsWkWslqeMLb2uXwmyy3UWjUR1q+AhAPnf0gs3lZoFZ1hjBQVecHKUvg==", + "license": "MIT", + "dependencies": { + "chokidar": "^3.6.0", + "http-proxy-middleware": "^2.0.9", + "p-retry": "^6.2.0", + "webpack-dev-server": "5.2.2", + "ws": "^8.18.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "peerDependencies": { + "@rspack/core": "*" + } + }, + "node_modules/@rspack/dev-server/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@rspack/dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/@rspack/dev-server/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@rspack/dev-server/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@rspack/dev-server/node_modules/webpack-dev-server": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", + "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", "license": "MIT", "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", "chokidar": "^3.6.0", - "express": "^4.19.2", - "http-proxy-middleware": "^2.0.6", - "mime-types": "^2.1.35", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", "webpack-dev-middleware": "^7.4.2", - "webpack-dev-server": "5.2.0", - "ws": "^8.16.0" + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { "node": ">= 18.12.0" }, - "peerDependencies": { - "@rspack/core": "*" - } - }, - "node_modules/@rspack/dev-server/node_modules/http-proxy-middleware": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", - "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "@types/express": "^4.17.13" + "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "@types/express": { + "webpack": { + "optional": true + }, + "webpack-cli": { "optional": true } } }, - "node_modules/@rspack/dev-server/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@rspack/lite-tapable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", @@ -9792,19 +9914,20 @@ } }, "node_modules/@rspack/plugin-react-refresh": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.0.1.tgz", - "integrity": "sha512-KSBc3bsr3mrAPViv7w9MpE9KEWm6q87EyRXyHlRfJ9PpQ56NbX9KZ7AXo7jPeECb0q5sfpM2PSEf+syBiMgLSw==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.4.3.tgz", + "integrity": "sha512-wZx4vWgy5oMEvgyNGd/oUKcdnKaccYWHCRkOqTdAPJC3WcytxhTX+Kady8ERurSBiLyQpoMiU3Iyd+F1Y2Arbw==", "license": "MIT", "dependencies": { "error-stack-parser": "^2.1.4", - "html-entities": "^2.5.2" + "html-entities": "^2.6.0" }, "peerDependencies": { - "react-refresh": ">=0.10.0 <1.0.0" + "react-refresh": ">=0.10.0 <1.0.0", + "webpack-hot-middleware": "2.x" }, "peerDependenciesMeta": { - "react-refresh": { + "webpack-hot-middleware": { "optional": true } } @@ -9813,7 +9936,6 @@ "version": "19.2.5", "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.2.5.tgz", "integrity": "sha512-LXzeWpW7vhW7zk48atwdR860hOp2xEyU+TqDUz4dcLk5sPI14x94fAJuAWch42+9/X6LnkFLB+W2CmyOY9ZD1g==", - "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": "19.2.5", @@ -9936,7 +10058,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -9949,7 +10070,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" @@ -9959,7 +10080,7 @@ "version": "10.3.0", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -9969,7 +10090,7 @@ "version": "1.13.3", "resolved": "https://registry.npmjs.org/@swc-node/core/-/core-1.13.3.tgz", "integrity": "sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 10" @@ -9987,7 +10108,7 @@ "version": "1.9.2", "resolved": "https://registry.npmjs.org/@swc-node/register/-/register-1.9.2.tgz", "integrity": "sha512-BBjg0QNuEEmJSoU/++JOXhrjWdu3PTyYeJWsvchsI0Aqtj8ICkz/DqlwtXbmZVZ5vuDPpTfFlwDBZe81zgShMA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@swc-node/core": "^1.13.1", @@ -10010,7 +10131,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/@swc-node/sourcemap-support/-/sourcemap-support-0.5.1.tgz", "integrity": "sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "source-map-support": "^0.5.21", @@ -10056,7 +10177,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.0.tgz", "integrity": "sha512-+CuuTCmQFfzaNGg1JmcZvdUVITQXJk9sMnl1C2TiDLzOSVOJRwVD4dNo5dljX/qxpMAN+2BIYlwjlSkoGi6grg==", - "dev": true, + "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -10265,7 +10386,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0" }, "node_modules/@swc/helpers": { @@ -10281,7 +10402,7 @@ "version": "0.1.20", "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.20.tgz", "integrity": "sha512-/rlIpxwKrhz4BIplXf6nsEHtqlhzuNN34/k3kMAXH4/lvVoA3cdq+60aqVNnyvw2uITEaCi0WV3pxBe4dQqoXQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" @@ -10477,6 +10598,72 @@ "dequal": "^2.0.3" } }, + "node_modules/@testing-library/dom": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/dom/node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/@testing-library/jest-dom": { "version": "6.4.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.5.tgz", @@ -10569,7 +10756,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 10" @@ -10588,28 +10775,28 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tufjs/canonical-json": { @@ -10672,7 +10859,7 @@ "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -10686,7 +10873,7 @@ "version": "7.6.8", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -10696,7 +10883,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -10707,7 +10894,7 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" @@ -10817,7 +11004,7 @@ "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -10827,7 +11014,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/http-cache-semantics": { @@ -10926,7 +11113,7 @@ "version": "20.0.1", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -11069,7 +11256,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/tapable": { @@ -11083,7 +11270,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/uglify-js": { @@ -11723,14 +11910,12 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, "license": "ISC" }, "node_modules/@vitejs/plugin-basic-ssl": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz", "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.21.3" @@ -12091,7 +12276,7 @@ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause" }, "node_modules/abbrev": { @@ -12133,7 +12318,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.1.0", @@ -12144,7 +12329,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -12154,7 +12338,7 @@ "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -12176,7 +12360,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dev": true, "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -12190,7 +12373,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, "license": "MIT", "dependencies": { "big.js": "^5.2.2", @@ -12214,7 +12396,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 14" @@ -12254,7 +12435,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -12450,7 +12630,6 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -12508,7 +12687,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -12522,7 +12701,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -12832,7 +13011,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", @@ -12885,7 +13064,7 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -12902,7 +13081,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", @@ -12919,7 +13098,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12929,7 +13108,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", @@ -13042,7 +13221,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -13069,7 +13248,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", @@ -13154,7 +13333,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.2.0.tgz", "integrity": "sha512-Ljqskqx/tbZagIglYoJIMzH5zgssyp+in9+9sAyh15N22AornBeIDnb8EZ6Rk+6ShfMxd92uO3gfpT0NtZbpow==", - "dev": true, "license": "Apache-2.0", "dependencies": { "css-select": "^5.1.0", @@ -13397,7 +13575,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" @@ -13720,7 +13898,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", @@ -13731,7 +13909,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -13833,7 +14011,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -13910,14 +14088,14 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "source-map": "~0.6.0" @@ -13930,7 +14108,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -13990,7 +14168,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", - "dev": true, "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", @@ -14007,7 +14184,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -14020,14 +14196,12 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", - "dev": true, "license": "MIT" }, "node_modules/cli-truncate/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", @@ -14045,7 +14219,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -14061,7 +14234,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, "license": "ISC", "engines": { "node": ">= 12" @@ -14147,7 +14319,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/color-convert": { @@ -14215,7 +14387,7 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 12" @@ -14241,7 +14413,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/compare-func": { @@ -14401,7 +14573,6 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true, "license": "MIT" }, "node_modules/cookie": { @@ -14448,7 +14619,6 @@ "version": "12.0.2", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", - "dev": true, "license": "MIT", "dependencies": { "fast-glob": "^3.3.2", @@ -14473,7 +14643,6 @@ "version": "14.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", - "dev": true, "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", @@ -14494,7 +14663,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -14504,7 +14672,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -14517,7 +14684,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.16" @@ -14614,7 +14780,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -14636,7 +14802,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cron-parser": { @@ -14719,7 +14885,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", - "dev": true, "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", @@ -14995,14 +15160,14 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cssstyle": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "cssom": "~0.3.6" @@ -15015,7 +15180,7 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cuint": { @@ -15390,7 +15555,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "abab": "^2.0.6", @@ -15529,7 +15694,7 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/decompress-response": { @@ -15565,7 +15730,7 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -15586,7 +15751,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, "license": "MIT" }, "node_modules/deepmerge": { @@ -15738,7 +15902,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=4" @@ -15774,7 +15938,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, "license": "Apache-2.0", "optional": true, "engines": { @@ -15785,7 +15948,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -15824,7 +15987,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -15873,7 +16036,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -15893,7 +16055,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "utila": "~0.4" @@ -15930,7 +16092,7 @@ "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", "deprecated": "Use your platform's native DOMException instead", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "webidl-conversions": "^7.0.0" @@ -15972,7 +16134,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -16095,7 +16257,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=12" @@ -16196,7 +16358,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -16334,6 +16495,28 @@ "node": ">= 0.4" } }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-module-lexer": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", @@ -16389,7 +16572,6 @@ "version": "0.25.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", - "dev": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -16430,7 +16612,6 @@ "version": "0.25.1", "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.1.tgz", "integrity": "sha512-dZxPeDHcDIQ6ilml/NzYxnPbNkoVsHSFH3JGLSobttc5qYYgExMo8lh2XcB+w+AfiqykVDGK5PWanGB0gWaAWw==", - "dev": true, "license": "MIT", "bin": { "esbuild": "bin/esbuild" @@ -16458,7 +16639,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -16471,7 +16651,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", @@ -16505,7 +16685,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", @@ -16645,7 +16824,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -16662,7 +16840,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -16673,7 +16850,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -16690,7 +16866,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -16706,7 +16881,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -16719,14 +16893,12 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, "license": "MIT" }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -16739,7 +16911,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -16752,7 +16923,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", @@ -16816,7 +16986,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/esutils": { @@ -16863,7 +17033,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -16887,7 +17057,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/executable": { @@ -16917,7 +17087,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 0.8.0" } @@ -16938,7 +17108,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", @@ -17218,7 +17388,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, "license": "MIT" }, "node_modules/fast-uri": { @@ -17262,7 +17431,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" @@ -17320,7 +17489,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" @@ -17517,7 +17685,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -17559,7 +17726,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -17891,14 +18057,12 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -17971,7 +18135,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -18008,7 +18171,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -18031,7 +18194,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -18103,7 +18266,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -18142,7 +18304,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -18153,7 +18314,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -18331,7 +18491,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, "license": "MIT" }, "node_modules/gzip-size": { @@ -18578,9 +18737,9 @@ } }, "node_modules/html-entities": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.3.tgz", - "integrity": "sha512-D3AfvN7SjhTgBSA8L1BN4FpPzuEd06uy4lHwSoRWr0lndi9BKaNzPLKGOWZ2ocSGguozr08TTb2jhCLHaemruw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", "funding": [ { "type": "github", @@ -18597,14 +18756,14 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "camel-case": "^4.1.2", @@ -18626,7 +18785,7 @@ "version": "5.6.3", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -18984,7 +19143,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -19100,7 +19258,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@tootallnate/once": "2", @@ -19115,7 +19273,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "debug": "4" @@ -19201,7 +19359,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -19215,7 +19372,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -19373,7 +19530,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -19393,7 +19550,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -19407,7 +19564,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -19420,7 +19577,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -19436,7 +19593,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -19449,7 +19606,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -19462,7 +19619,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -19483,7 +19639,6 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -19510,7 +19665,7 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/injection-js/-/injection-js-2.4.0.tgz", "integrity": "sha512-6jiJt0tCAo9zjHbcwLiPL+IuNe9SQ6a9g0PEzafThW3fOQi0mrmiJGBJvDD6tmhPh8cQHIQtCOrJuBfQME4kPA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -19626,6 +19781,24 @@ "node": ">= 0.10" } }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -19810,7 +19983,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -19823,7 +19995,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -19968,7 +20140,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -19997,7 +20168,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/is-regex": { @@ -20051,7 +20222,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -20270,7 +20441,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" @@ -20280,7 +20450,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", @@ -20297,7 +20466,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -20312,7 +20481,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", @@ -20327,7 +20496,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -20337,7 +20506,7 @@ "version": "3.1.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -20406,7 +20575,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -20433,7 +20602,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "execa": "^5.0.0", @@ -20448,7 +20617,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -20480,7 +20649,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -20493,7 +20662,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -20508,14 +20677,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-cli": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -20549,7 +20718,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -20595,7 +20764,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -20608,7 +20777,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -20624,7 +20793,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -20639,7 +20808,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-diff": { @@ -20693,7 +20862,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" @@ -20706,7 +20875,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -20723,7 +20892,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -20736,7 +20905,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -20751,14 +20920,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-environment-jsdom": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -20786,7 +20955,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -20813,7 +20982,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -20839,7 +21008,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", @@ -20853,7 +21022,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -20866,7 +21035,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -20881,14 +21050,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-matcher-utils": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -20904,7 +21073,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -20917,7 +21086,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -20932,14 +21101,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-message-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", @@ -20960,7 +21129,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -20973,7 +21142,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -20988,14 +21157,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-mock": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -21010,7 +21179,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -21091,7 +21260,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -21101,7 +21270,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -21122,7 +21291,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", @@ -21136,7 +21305,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -21169,7 +21338,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -21179,7 +21348,7 @@ "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -21190,7 +21359,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -21224,7 +21393,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -21256,7 +21425,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -21269,7 +21438,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -21284,7 +21453,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-util": { @@ -21335,7 +21504,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -21353,7 +21522,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -21366,7 +21535,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -21379,7 +21548,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -21394,14 +21563,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-watcher": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -21501,7 +21670,7 @@ "version": "20.0.3", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "abab": "^2.0.6", @@ -21547,7 +21716,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "debug": "4" @@ -21560,7 +21729,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "agent-base": "6", @@ -21574,7 +21743,7 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", @@ -21590,7 +21759,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -21612,7 +21781,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, "license": "MIT" }, "node_modules/json-fixer": { @@ -21657,7 +21825,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, "license": "MIT" }, "node_modules/json-stringify-safe": { @@ -21702,7 +21869,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, "license": "MIT" }, "node_modules/jsonfile": { @@ -21764,7 +21930,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", - "dev": true, "license": "MIT", "dependencies": { "source-map-support": "^0.5.5" @@ -21786,7 +21951,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -21805,7 +21969,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -21940,7 +22104,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/less/-/less-4.2.2.tgz", "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "copy-anything": "^2.0.1", @@ -21967,7 +22130,6 @@ "version": "12.2.0", "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 18.12.0" @@ -21994,7 +22156,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -22009,7 +22170,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -22020,7 +22180,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, "license": "ISC", "optional": true, "bin": { @@ -22031,7 +22190,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "license": "BSD-3-Clause", "optional": true, "engines": { @@ -22042,7 +22200,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -22052,7 +22210,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -22595,7 +22752,6 @@ "version": "8.2.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", - "dev": true, "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", @@ -22613,7 +22769,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -22626,7 +22781,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -22639,21 +22793,18 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", - "dev": true, "license": "MIT" }, "node_modules/listr2/node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true, "license": "MIT" }, "node_modules/listr2/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", @@ -22671,7 +22822,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -22687,7 +22837,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", @@ -22705,7 +22854,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.2.6.tgz", "integrity": "sha512-SuHqzPl7mYStna8WRotY8XX/EUZBjjv3QyKIByeCLFfC9uXT/OIHByEcA07PzbMfQAM0KYJtLgtpMRlIe5dErQ==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -22741,7 +22889,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 12.13.0" @@ -22764,7 +22911,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -22832,7 +22978,6 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, "license": "MIT" }, "node_modules/lodash.mergewith": { @@ -22896,7 +23041,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", - "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^7.0.0", @@ -22916,7 +23060,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", - "dev": true, "license": "MIT", "dependencies": { "environment": "^1.0.0" @@ -22932,7 +23075,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -22945,7 +23087,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -22958,7 +23099,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^5.0.0" @@ -22974,14 +23114,12 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", - "dev": true, "license": "MIT" }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", - "dev": true, "license": "MIT", "dependencies": { "get-east-asian-width": "^1.0.0" @@ -22997,7 +23135,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" @@ -23013,7 +23150,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, "license": "MIT", "dependencies": { "onetime": "^7.0.0", @@ -23030,7 +23166,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", @@ -23047,7 +23182,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", @@ -23065,7 +23199,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -23081,7 +23214,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", @@ -23121,7 +23253,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -23181,7 +23313,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" @@ -23197,7 +23329,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/make-fetch-happen": { @@ -23237,7 +23369,7 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" @@ -23454,7 +23586,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -23490,7 +23621,6 @@ "version": "2.9.2", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", - "dev": true, "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -23785,7 +23915,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -23801,7 +23930,6 @@ "version": "1.11.2", "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", - "dev": true, "license": "MIT", "optional": true, "optionalDependencies": { @@ -23812,7 +23940,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -23848,7 +23975,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", - "dev": true, "license": "ISC", "engines": { "node": "^18.17.0 || >=20.5.0" @@ -23887,7 +24013,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, "license": "MIT" }, "node_modules/needle": { @@ -23926,7 +24051,7 @@ "version": "19.2.0", "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-19.2.0.tgz", "integrity": "sha512-bDyB9tmXMCL/4IhKcX84zGQlQrZhPhdCaomdJocz6EN57cZWdTP7SGhrswzpdGJY+y89855detet27oJLgR3IQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@rollup/plugin-json": "^6.1.0", @@ -23975,7 +24100,7 @@ "version": "13.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=18" @@ -23985,14 +24110,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/ng-packagr/node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "commondir": "^1.0.1", @@ -24010,7 +24135,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -24024,7 +24149,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -24037,7 +24162,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "semver": "^6.0.0" @@ -24053,7 +24178,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -24069,7 +24194,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -24082,7 +24207,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -24095,7 +24220,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -24105,7 +24230,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "lower-case": "^2.0.2", @@ -24122,7 +24247,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", - "dev": true, "license": "MIT", "optional": true }, @@ -24206,7 +24330,6 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -24339,7 +24462,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/node-machine-id": { @@ -24580,7 +24703,7 @@ "version": "2.2.19", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.19.tgz", "integrity": "sha512-94bcyI3RsqiZufXjkr3ltkI86iEl+I7uiHVDtcq9wJUTwYQJ5odHDeSzkkrRzi80jJ8MaeZgqKjH1bAWAFw9bA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/nx": { @@ -24781,6 +24904,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -24921,7 +25062,6 @@ "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, "license": "MIT", "dependencies": { "deep-is": "^0.1.3", @@ -24939,7 +25079,6 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, "license": "MIT", "dependencies": { "bl": "^4.1.0", @@ -24963,7 +25102,6 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", - "dev": true, "license": "MIT", "optional": true }, @@ -25016,7 +25154,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -25032,7 +25169,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -25078,7 +25214,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -25126,7 +25262,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -25209,7 +25345,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", - "dev": true, "license": "MIT", "dependencies": { "entities": "^4.3.0", @@ -25224,7 +25359,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", - "dev": true, "license": "MIT", "dependencies": { "parse5": "^7.0.0" @@ -25246,7 +25380,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -25257,7 +25391,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -25267,7 +25400,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -26167,7 +26299,6 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true, "license": "MIT" }, "node_modules/postcss-merge-longhand": { @@ -26895,7 +27026,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8.0" @@ -27030,7 +27160,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "lodash": "^4.17.20", @@ -27119,7 +27249,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -27159,7 +27289,7 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "punycode": "^2.3.1" @@ -27192,7 +27322,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "individual", @@ -27224,7 +27354,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/queue-microtask": { @@ -27311,6 +27441,29 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -27318,6 +27471,16 @@ "dev": true, "license": "MIT" }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -27521,7 +27684,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", - "dev": true, "license": "Apache-2.0" }, "node_modules/reflect.getprototypeof": { @@ -27584,7 +27746,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", - "dev": true, "license": "MIT" }, "node_modules/regexp.prototype.flags": { @@ -27659,7 +27820,7 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -27669,7 +27830,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "css-select": "^4.1.3", @@ -27683,7 +27844,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -27700,7 +27861,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", @@ -27715,7 +27876,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" @@ -27731,7 +27892,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", @@ -27746,7 +27907,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" @@ -27756,7 +27917,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, + "devOptional": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -27844,7 +28005,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" @@ -27870,7 +28031,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -27913,7 +28074,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", - "dev": true, "license": "MIT", "dependencies": { "adjust-sourcemap-loader": "^4.0.0", @@ -27930,7 +28090,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, "license": "MIT", "dependencies": { "big.js": "^5.2.2", @@ -27945,7 +28104,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -28025,7 +28183,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -28041,7 +28198,6 @@ "version": "4.34.8", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", - "dev": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.6" @@ -28080,16 +28236,13 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, "license": "MIT" }, "node_modules/rslog": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/rslog/-/rslog-1.2.3.tgz", - "integrity": "sha512-antALPJaKBRPBU1X2q9t085K4htWDOOv/K1qhTUk7h0l1ePU/KbDqKJn19eKP0dk7PqMioeA0+fu3gyPXCsXxQ==", - "engines": { - "node": ">=14.17.6" - } + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/rslog/-/rslog-1.2.9.tgz", + "integrity": "sha512-KSjM8jJKYYaKgI4jUGZZ4kdTBTM/EIGH1JnoB0ptMkzcyWaHeXW9w6JVLCYs37gh8sFZkLLqAyBb2sT02bqpcQ==", + "license": "MIT" }, "node_modules/run-applescript": { "version": "7.0.0", @@ -28674,7 +28827,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" @@ -28683,6 +28836,13 @@ "node": ">=v12.22.7" } }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT", + "peer": true + }, "node_modules/schema-utils": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", @@ -29178,14 +29338,14 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -29195,7 +29355,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", @@ -29212,7 +29371,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -29644,7 +29802,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" @@ -29657,7 +29815,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -29678,6 +29836,21 @@ "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/streamroller": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", @@ -29761,7 +29934,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -29906,7 +30079,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -29927,7 +30100,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -29950,7 +30123,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -30237,7 +30409,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/sync-child-process": { @@ -30565,7 +30737,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", @@ -30580,7 +30752,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -30591,7 +30763,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -30637,7 +30809,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, "license": "MIT" }, "node_modules/thenify": { @@ -30755,7 +30926,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { @@ -30814,7 +30985,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "punycode": "^2.1.1" @@ -30843,7 +31014,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, "license": "MIT", "bin": { "tree-kill": "cli.js" @@ -30873,14 +31043,15 @@ } }, "node_modules/ts-checker-rspack-plugin": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ts-checker-rspack-plugin/-/ts-checker-rspack-plugin-1.1.1.tgz", - "integrity": "sha512-BlpPqnfAmV0TcDg58H+1qV8Zb57ilv0x+ajjnxrVQ6BWgC8HzAdc+TycqDOJ4sZZYIV+hywQGozZFGklzbCR6A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/ts-checker-rspack-plugin/-/ts-checker-rspack-plugin-1.1.4.tgz", + "integrity": "sha512-lDpKuAubxUlsonUE1LpZS5fw7tfjutNb0lwjAo0k8OcxpWv/q18ytaD6eZXdjrFdTEFNIHtKp9dNkUKGky8SgA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.7", "@rspack/lite-tapable": "^1.0.0", "chokidar": "^3.5.3", + "is-glob": "^4.0.3", "memfs": "^4.14.0", "minimatch": "^9.0.5", "picocolors": "^1.1.1" @@ -30899,9 +31070,9 @@ } }, "node_modules/ts-checker-rspack-plugin/node_modules/memfs": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.0.tgz", - "integrity": "sha512-4eirfZ7thblFmqFjywlTmuWVSvccHAJbn1r8qQLzmTO11qcqpohOjmY2mFce6x7x7WtskzRqApPD0hv+Oa74jg==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", + "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", @@ -31006,7 +31177,7 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -31050,7 +31221,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/tsconfig-paths": { @@ -31153,7 +31324,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -31166,7 +31336,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=4" @@ -31176,7 +31346,6 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -31394,7 +31563,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -31533,7 +31701,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "querystringify": "^2.1.1", @@ -31561,7 +31729,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/utils-merge": { @@ -31586,14 +31754,14 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -31608,7 +31776,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/validate-npm-package-license": { @@ -31666,7 +31834,6 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz", "integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", @@ -31738,7 +31905,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "xml-name-validator": "^4.0.0" @@ -31751,7 +31918,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" @@ -31804,7 +31971,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "dev": true, "license": "MIT", "optional": true }, @@ -31812,7 +31978,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -32017,7 +32183,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "dev": true, "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", @@ -32134,7 +32299,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=12" @@ -32144,7 +32309,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "tr46": "^3.0.0", @@ -32275,7 +32440,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -32285,7 +32449,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -32324,7 +32487,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -32338,7 +32501,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/ws": { @@ -32366,7 +32529,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=12" @@ -32376,7 +32539,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/xxhashjs": { @@ -32470,7 +32633,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -32480,7 +32643,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -32493,7 +32655,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" diff --git a/package.json b/package.json index 42656f24c..e82086d91 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,12 @@ "@ngneat/falso": "7.2.0", "@ngrx/component": "19.0.1", "@ngrx/component-store": "19.0.1", - "@ngrx/effects": "19.0.1", + "@ngrx/effects": "^19.0.1", "@ngrx/entity": "19.0.1", "@ngrx/operators": "19.0.1", "@ngrx/router-store": "19.0.1", - "@ngrx/store": "19.0.1", + "@ngrx/store": "^19.0.1", + "@ngrx/store-devtools": "^19.0.1", "@nx/angular": "20.6.4", "@swc/helpers": "0.5.12", "@tanstack/angular-query-experimental": "5.62.3",