UNPKG

@testing-library/angular

Version:
1 lines 57.1 kB
{"version":3,"file":"testing-library-angular.mjs","sources":["../../../../projects/testing-library/src/lib/models.ts","../../../../projects/testing-library/src/lib/config.ts","../../../../projects/testing-library/src/lib/testing-library.ts","../../../../projects/testing-library/src/public_api.ts","../../../../projects/testing-library/testing-library-angular.ts"],"sourcesContent":["import { Type, DebugElement, EventEmitter, Signal, InputSignalWithTransform } from '@angular/core';\nimport { ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed } from '@angular/core/testing';\nimport { Routes } from '@angular/router';\nimport { BoundFunction, Queries, queries, Config as dtlConfig, PrettyDOMOptions } from '@testing-library/dom';\n\n// TODO: import from Angular (is a breaking change)\ninterface OutputRef<T> {\n subscribe(callback: (value: T) => void): OutputRefSubscription;\n}\ninterface OutputRefSubscription {\n unsubscribe(): void;\n}\n\nexport type OutputRefKeysWithCallback<T> = {\n [key in keyof T]?: T[key] extends EventEmitter<infer U>\n ? (val: U) => void\n : T[key] extends OutputRef<infer U>\n ? (val: U) => void\n : never;\n};\n\nexport type RenderResultQueries<Q extends Queries = typeof queries> = { [P in keyof Q]: BoundFunction<Q[P]> };\nexport interface RenderResult<ComponentType, WrapperType = ComponentType> extends RenderResultQueries {\n /**\n * @description\n * The containing DOM node of your rendered Angular Component.\n * This is a regular DOM node, so you can call container.querySelector etc. to inspect the children.\n */\n container: Element;\n /**\n * @description\n * Prints out the component's DOM with syntax highlighting.\n * Accepts an optional parameter, to print out a specific DOM node.\n *\n * @param\n * element: The to be printed HTML element, if not provided it will log the whole component's DOM\n */\n debug: (\n element?: Element | Document | (Element | Document)[],\n maxLength?: number,\n options?: PrettyDOMOptions,\n ) => void;\n /**\n * @description\n * Trigger a change detection cycle for the component.\n *\n * For more info see https://angular.io/api/core/testing/ComponentFixture#detectChanges\n */\n detectChanges: () => void;\n /**\n * @description\n * The Angular `DebugElement` of the component.\n *\n * For more info see https://angular.io/api/core/DebugElement\n */\n debugElement: DebugElement;\n /**\n * @description\n * The Angular `ComponentFixture` of the component or the wrapper.\n * If a template is provided, it will be the fixture of the wrapper.\n *\n * For more info see https://angular.io/api/core/testing/ComponentFixture\n */\n fixture: ComponentFixture<WrapperType>;\n /**\n * @description\n * Navigates to the href of the element or to the path.\n *\n */\n navigate: (elementOrPath: Element | string, basePath?: string) => Promise<boolean>;\n /**\n * @description\n * Re-render the same component with different properties.\n * Properties not passed in again are removed.\n */\n rerender: (\n properties?: Pick<\n RenderTemplateOptions<ComponentType>,\n 'componentProperties' | 'componentInputs' | 'inputs' | 'componentOutputs' | 'on' | 'detectChangesOnRender'\n > & { partialUpdate?: boolean },\n ) => Promise<void>;\n /**\n * @description\n * Set the state of a deferrable block.\n */\n renderDeferBlock: (deferBlockState: DeferBlockState, deferBlockIndex?: number) => Promise<void>;\n}\n\ndeclare const ALIASED_INPUT_BRAND: unique symbol;\nexport type AliasedInput<T> = T & {\n [ALIASED_INPUT_BRAND]: T;\n};\nexport type AliasedInputs = Record<string, AliasedInput<unknown>>;\n\nexport type ComponentInput<T> =\n | {\n [P in keyof T]?: T[P] extends InputSignalWithTransform<any, infer U>\n ? U\n : T[P] extends Signal<infer U>\n ? U\n : T[P];\n }\n | AliasedInputs;\n\n/**\n * @description\n * Creates an aliased input branded type with a value\n *\n */\nexport function aliasedInput<TAlias extends string, T>(alias: TAlias, value: T): Record<TAlias, AliasedInput<T>> {\n return { [alias]: value } as Record<TAlias, AliasedInput<T>>;\n}\n\nexport interface RenderComponentOptions<ComponentType, Q extends Queries = typeof queries> {\n /**\n * @description\n * Automatically detect changes as a \"real\" running component would do.\n *\n * @default\n * true\n *\n * @example\n * await render(AppComponent, {\n * autoDetectChanges: false\n * })\n */\n autoDetectChanges?: boolean;\n /**\n * @description\n * Invokes `detectChanges` after the component is rendered\n *\n * @default\n * true\n *\n * @example\n * await render(AppComponent, {\n * detectChangesOnRender: false\n * })\n */\n detectChangesOnRender?: boolean;\n\n /**\n * @description\n * A collection of components, directives and pipes needed to render the component, for example, nested components of the component.\n *\n * For more info see https://angular.io/api/core/NgModule#declarations\n *\n * @default\n * []\n *\n * @example\n * await render(AppComponent, {\n * declarations: [ CustomerDetailComponent, ButtonComponent ]\n * })\n */\n declarations?: any[];\n /**\n * @description\n * A collection of providers needed to render the component via Dependency Injection, for example, injectable services or tokens.\n *\n * For more info see https://angular.io/api/core/NgModule#providers\n *\n * @default\n * []\n *\n * @example\n * await render(AppComponent, {\n * providers: [\n * CustomersService,\n * {\n * provide: MAX_CUSTOMERS_TOKEN,\n * useValue: 10\n * }\n * ]\n * })\n */\n providers?: any[];\n /**\n * @description\n * A collection of imports needed to render the component, for example, shared modules.\n * Adds `NoopAnimationsModule` by default if `BrowserAnimationsModule` isn't added to the collection.\n *\n * For more info see https://angular.io/api/core/NgModule#imports\n *\n * @default\n * `[NoopAnimationsModule]`\n *\n * @example\n * await render(AppComponent, {\n * imports: [\n * AppSharedModule,\n * MaterialModule,\n * ]\n * })\n */\n imports?: any[];\n /**\n * @description\n * A collection of schemas needed to render the component.\n * Allowed values are `NO_ERRORS_SCHEMA` and `CUSTOM_ELEMENTS_SCHEMA`.\n *\n * For more info see https://angular.io/api/core/NgModule#schemas\n *\n * @default\n * []\n *\n * @example\n * await render(AppComponent, {\n * schemas: [\n * NO_ERRORS_SCHEMA,\n * ]\n * })\n */\n schemas?: any[];\n /**\n * @description\n * An object to set properties of the component\n *\n * @default\n * {}\n *\n * @example\n * await render(AppComponent, {\n * componentProperties: {\n * counterValue: 10,\n * send: (value) => { ... }\n * }\n * })\n */\n componentProperties?: Partial<ComponentType>;\n /**\n * @description\n * An object to set `@Input` properties of the component\n *\n * @deprecated use the `inputs` option instead. When you need to use aliases, use the `aliasedInput(...)` helper function.\n * @default\n * {}\n *\n * @example\n * await render(AppComponent, {\n * componentInputs: {\n * counterValue: 10\n * }\n * })\n */\n componentInputs?: Partial<ComponentType> | Record<string, unknown>;\n\n /**\n * @description\n * An object to set `@Input` or `input()` properties of the component\n *\n * @default\n * {}\n *\n * @example\n * await render(AppComponent, {\n * inputs: {\n * counterValue: 10,\n * // explicitly define aliases using aliasedInput\n * ...aliasedInput('someAlias', 'someValue')\n * }\n * })\n */\n inputs?: ComponentInput<ComponentType>;\n\n /**\n * @description\n * An object to set `@Output` properties of the component\n * @deprecated use the `on` option instead. When it is necessary to override properties, use the `componentProperties` option.\n * @default\n * {}\n *\n * @example\n * const sendValue = new EventEmitter<any>();\n * await render(AppComponent, {\n * componentOutputs: {\n * send: {\n * emit: sendValue\n * }\n * }\n * })\n */\n componentOutputs?: Partial<ComponentType>;\n\n /**\n * @description\n * An object with callbacks to subscribe to EventEmitters/Observables of the component\n *\n * @default\n * {}\n *\n * @example\n * const sendValue = (value) => { ... }\n * await render(AppComponent, {\n * on: {\n * send: (value) => sendValue(value)\n * }\n * })\n */\n on?: OutputRefKeysWithCallback<ComponentType>;\n\n /**\n * @description\n * A collection of providers to inject dependencies of the component.\n *\n * For more info see https://angular.io/api/core/Directive#providers\n *\n * @default\n * []\n *\n * @example\n * await render(AppComponent, {\n * componentProviders: [\n * AppComponentService\n * ]\n * })\n */\n componentProviders?: any[];\n /**\n * @description\n * Collection of child component specified providers to override with\n *\n * @default\n * []\n *\n * @example\n * await render(AppComponent, {\n * childComponentOverrides: [\n * {\n * component: ChildOfAppComponent,\n * providers: [{ provide: MyService, useValue: { hello: 'world' } }]\n * }\n * ]\n * })\n *\n */\n childComponentOverrides?: ComponentOverride<any>[];\n /**\n * @description\n * A collection of imports to override a standalone component's imports with.\n *\n * @default\n * undefined\n *\n * @example\n * await render(AppComponent, {\n * componentImports: [\n * MockChildComponent\n * ]\n * })\n */\n componentImports?: (Type<any> | any[])[];\n /**\n * @description\n * Queries to bind. Overrides the default set from DOM Testing Library unless merged.\n *\n * @default\n * undefined\n *\n * @example\n * import * as customQueries from 'custom-queries'\n * import { queries } from '@testing-library/angular'\n *\n * await render(AppComponent, {\n * queries: { ...queries, ...customQueries }\n * })\n */\n queries?: Q;\n /**\n * @description\n * Exclude the component to be automatically be added as a declaration.\n * This is needed when the component is declared in an imported module.\n *\n * @default\n * false\n *\n * @example\n * await render(AppComponent, {\n * imports: [AppModule], // a module that includes AppComponent\n * excludeComponentDeclaration: true\n * })\n */\n excludeComponentDeclaration?: boolean;\n\n /**\n * @description\n * The route configuration to set up the router service via `RouterTestingModule.withRoutes`.\n * For more info see https://angular.io/api/router/Routes.\n *\n * @example\n * await render(AppComponent, {\n * declarations: [ChildComponent],\n * routes: [\n * {\n * path: '',\n * children: [\n * {\n * path: 'child/:id',\n * component: ChildComponent\n * }\n * ]\n * }\n * ]\n * })\n */\n routes?: Routes;\n\n /**\n * @description\n * Specifies which route should be initially navigated to\n *\n * @example\n * await render(AppComponent, {\n * initialRoute: 'myroute',\n * routes: [\n * { path: '', component: HomeComponent },\n * { path: 'myroute', component: SecondaryComponent }\n * ]\n * })\n */\n initialRoute?: string;\n\n /**\n * @description\n * Removes the Angular attributes (ng-version, and root-id) from the fixture.\n *\n * @default\n * `false`\n *\n * @example\n * await render(AppComponent, {\n * removeAngularAttributes: true\n * })\n */\n removeAngularAttributes?: boolean;\n\n /**\n * @description\n * Callback to configure the testbed before the compilation.\n *\n * @default\n * () => {}\n *\n * @example\n * await render(AppComponent, {\n * configureTestBed: (testBed) => { }\n * })\n */\n configureTestBed?: (testbed: TestBed) => void;\n\n /**\n * @description\n * Set the initial state of a deferrable block.\n */\n deferBlockStates?: DeferBlockState | { deferBlockState: DeferBlockState; deferBlockIndex: number }[];\n\n /**\n * @description\n * Set the defer blocks behavior.\n */\n deferBlockBehavior?: DeferBlockBehavior;\n}\n\nexport interface ComponentOverride<T> {\n component: Type<T>;\n providers: any[];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface RenderTemplateOptions<WrapperType, Properties extends object = {}, Q extends Queries = typeof queries>\n extends RenderComponentOptions<Properties, Q> {\n /**\n * @description\n * An Angular component to wrap the component in.\n * The template will be overridden with the `template` option.\n * NOTE: A standalone component cannot be used as a wrapper.\n *\n * @default\n * `WrapperComponent`, an empty component that strips the `ng-version` attribute\n *\n * @example\n * await render(`<div spoiler message='SPOILER'></div>`, {\n * declarations: [SpoilerDirective]\n * wrapper: CustomWrapperComponent\n * })\n */\n wrapper?: Type<WrapperType>;\n componentProperties?: Partial<WrapperType & Properties>;\n}\n\nexport interface Config extends Pick<RenderComponentOptions<any>, 'excludeComponentDeclaration'> {\n /**\n * DOM Testing Library config\n * @link https://testing-library.com/docs/dom-testing-library/api-configuration/\n */\n dom: Partial<dtlConfig>;\n /**\n * Imports that are added to the imports\n */\n defaultImports: any[];\n}\n","import { Config } from './models';\n\nlet config: Config = {\n dom: {},\n defaultImports: [],\n};\n\nexport function configure(newConfig: Partial<Config> | ((config: Partial<Config>) => Partial<Config>)) {\n if (typeof newConfig === 'function') {\n // Pass the existing config out to the provided function\n // and accept a delta in return\n newConfig = newConfig(config);\n }\n\n // Merge the incoming config delta\n config = {\n ...config,\n ...newConfig,\n };\n}\n\nexport function getConfig() {\n return config;\n}\n","import {\n ApplicationInitStatus,\n ChangeDetectorRef,\n Component,\n NgZone,\n OnChanges,\n OutputRef,\n OutputRefSubscription,\n SimpleChange,\n SimpleChanges,\n Type,\n isStandalone,\n} from '@angular/core';\nimport { ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed, tick } from '@angular/core/testing';\nimport { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';\nimport { NavigationExtras, Router } from '@angular/router';\nimport { RouterTestingModule } from '@angular/router/testing';\nimport type { BoundFunctions, Queries } from '@testing-library/dom';\nimport {\n configure as dtlConfigure,\n getQueriesForElement as dtlGetQueriesForElement,\n prettyDOM as dtlPrettyDOM,\n queries as dtlQueries,\n screen as dtlScreen,\n waitFor as dtlWaitFor,\n waitForElementToBeRemoved as dtlWaitForElementToBeRemoved,\n waitForOptions as dtlWaitForOptions,\n within as dtlWithin,\n} from '@testing-library/dom';\nimport { getConfig } from './config';\nimport {\n ComponentOverride,\n OutputRefKeysWithCallback,\n RenderComponentOptions,\n RenderResult,\n RenderTemplateOptions,\n Config,\n} from './models';\n\ntype SubscribedOutput<T> = readonly [key: keyof T, callback: (v: any) => void, subscription: OutputRefSubscription];\n\nconst mountedFixtures = new Set<ComponentFixture<any>>();\nconst safeInject = TestBed.inject || TestBed.get;\n\nexport async function render<ComponentType>(\n component: Type<ComponentType>,\n renderOptions?: RenderComponentOptions<ComponentType>,\n): Promise<RenderResult<ComponentType, ComponentType>>;\nexport async function render<WrapperType = WrapperComponent>(\n template: string,\n renderOptions?: RenderTemplateOptions<WrapperType>,\n): Promise<RenderResult<WrapperType>>;\n\nexport async function render<SutType, WrapperType = SutType>(\n sut: Type<SutType> | string,\n renderOptions: RenderComponentOptions<SutType> | RenderTemplateOptions<WrapperType> = {},\n): Promise<RenderResult<SutType>> {\n const { dom: domConfig, ...globalConfig } = getConfig();\n const {\n detectChangesOnRender = true,\n autoDetectChanges = true,\n declarations = [],\n imports = [],\n providers = [],\n schemas = [],\n queries,\n wrapper = WrapperComponent as Type<WrapperType>,\n componentProperties = {},\n componentInputs = {},\n componentOutputs = {},\n inputs: newInputs = {},\n on = {},\n componentProviders = [],\n childComponentOverrides = [],\n componentImports,\n excludeComponentDeclaration = false,\n routes = [],\n removeAngularAttributes = false,\n defaultImports = [],\n initialRoute = '',\n deferBlockStates = undefined,\n deferBlockBehavior = undefined,\n configureTestBed = () => {\n /* noop*/\n },\n } = { ...globalConfig, ...renderOptions } as RenderComponentOptions<SutType> &\n RenderTemplateOptions<WrapperType> &\n Config;\n\n dtlConfigure({\n eventWrapper: (cb) => {\n const result = cb();\n if (autoDetectChanges) {\n detectChangesForMountedFixtures();\n }\n return result;\n },\n ...domConfig,\n });\n\n TestBed.configureTestingModule({\n declarations: addAutoDeclarations(sut, {\n declarations,\n excludeComponentDeclaration,\n wrapper,\n }),\n imports: addAutoImports(sut, {\n imports: imports.concat(defaultImports),\n routes,\n }),\n providers: [...providers],\n schemas: [...schemas],\n deferBlockBehavior: deferBlockBehavior ?? DeferBlockBehavior.Manual,\n });\n overrideComponentImports(sut, componentImports);\n overrideChildComponentProviders(childComponentOverrides);\n\n configureTestBed(TestBed);\n\n await TestBed.compileComponents();\n\n // Angular supports nested arrays of providers, so we need to flatten them to emulate the same behavior.\n for (const { provide, ...provider } of componentProviders.flat(Infinity)) {\n TestBed.overrideProvider(provide, provider);\n }\n\n const componentContainer = createComponentFixture(sut, wrapper);\n\n const zone = safeInject(NgZone);\n const router = safeInject(Router);\n const _navigate = async (elementOrPath: Element | string, basePath = ''): Promise<boolean> => {\n const href = typeof elementOrPath === 'string' ? elementOrPath : elementOrPath.getAttribute('href');\n const [path, params] = (basePath + href).split('?');\n const queryParams = params\n ? params.split('&').reduce((qp, q) => {\n const [key, value] = q.split('=');\n const currentValue = qp[key];\n if (typeof currentValue === 'undefined') {\n qp[key] = value;\n } else if (Array.isArray(currentValue)) {\n qp[key] = [...currentValue, value];\n } else {\n qp[key] = [currentValue, value];\n }\n return qp;\n }, {} as Record<string, string | string[]>)\n : undefined;\n\n const navigateOptions: NavigationExtras | undefined = queryParams\n ? {\n queryParams,\n }\n : undefined;\n\n const doNavigate = () => {\n return navigateOptions ? router?.navigate([path], navigateOptions) : router?.navigate([path]);\n };\n\n let result;\n\n if (zone) {\n await zone.run(() => {\n result = doNavigate();\n });\n } else {\n result = doNavigate();\n }\n return result ?? false;\n };\n\n if (initialRoute) await _navigate(initialRoute);\n\n if (typeof router?.initialNavigation === 'function') {\n if (zone) {\n zone.run(() => router.initialNavigation());\n } else {\n router.initialNavigation();\n }\n }\n\n let detectChanges: () => void;\n\n const allInputs = { ...componentInputs, ...newInputs };\n\n let renderedPropKeys = Object.keys(componentProperties);\n let renderedInputKeys = Object.keys(allInputs);\n let renderedOutputKeys = Object.keys(componentOutputs);\n let subscribedOutputs: SubscribedOutput<SutType>[] = [];\n\n const renderFixture = async (\n properties: Partial<SutType>,\n inputs: Partial<SutType>,\n outputs: Partial<SutType>,\n subscribeTo: OutputRefKeysWithCallback<SutType>,\n ): Promise<ComponentFixture<SutType>> => {\n const createdFixture: ComponentFixture<SutType> = await createComponent(componentContainer);\n setComponentProperties(createdFixture, properties);\n setComponentInputs(createdFixture, inputs);\n setComponentOutputs(createdFixture, outputs);\n subscribedOutputs = subscribeToComponentOutputs(createdFixture, subscribeTo);\n\n if (removeAngularAttributes) {\n createdFixture.nativeElement.removeAttribute('ng-version');\n const idAttribute = createdFixture.nativeElement.getAttribute('id');\n if (idAttribute?.startsWith('root')) {\n createdFixture.nativeElement.removeAttribute('id');\n }\n }\n\n mountedFixtures.add(createdFixture);\n\n let isAlive = true;\n createdFixture.componentRef.onDestroy(() => {\n isAlive = false;\n });\n\n if (hasOnChangesHook(createdFixture.componentInstance) && Object.keys(properties).length > 0) {\n const changes = getChangesObj(null, componentProperties);\n createdFixture.componentInstance.ngOnChanges(changes);\n }\n\n detectChanges = () => {\n if (isAlive) {\n createdFixture.detectChanges();\n }\n };\n\n if (detectChangesOnRender) {\n detectChanges();\n }\n\n return createdFixture;\n };\n\n const fixture = await renderFixture(componentProperties, allInputs as any, componentOutputs, on);\n\n if (deferBlockStates) {\n if (Array.isArray(deferBlockStates)) {\n for (const deferBlockState of deferBlockStates) {\n await renderDeferBlock(fixture, deferBlockState.deferBlockState, deferBlockState.deferBlockIndex);\n }\n } else {\n await renderDeferBlock(fixture, deferBlockStates);\n }\n }\n\n const rerender = async (\n properties?: Pick<\n RenderTemplateOptions<SutType>,\n 'componentProperties' | 'componentInputs' | 'inputs' | 'componentOutputs' | 'on' | 'detectChangesOnRender'\n > & { partialUpdate?: boolean },\n ) => {\n const newComponentInputs = { ...properties?.componentInputs, ...properties?.inputs };\n const changesInComponentInput = update(\n fixture,\n renderedInputKeys,\n newComponentInputs,\n setComponentInputs,\n properties?.partialUpdate ?? false,\n );\n renderedInputKeys = Object.keys(newComponentInputs);\n\n const newComponentOutputs = properties?.componentOutputs ?? {};\n for (const outputKey of renderedOutputKeys) {\n if (!Object.prototype.hasOwnProperty.call(newComponentOutputs, outputKey)) {\n delete (fixture.componentInstance as any)[outputKey];\n }\n }\n setComponentOutputs(fixture, newComponentOutputs);\n renderedOutputKeys = Object.keys(newComponentOutputs);\n\n // first unsubscribe the no longer available or changed callback-fns\n const newObservableSubscriptions: OutputRefKeysWithCallback<SutType> = properties?.on ?? {};\n for (const [key, cb, subscription] of subscribedOutputs) {\n // when no longer provided or when the callback has changed\n if (!(key in newObservableSubscriptions) || cb !== (newObservableSubscriptions as any)[key]) {\n subscription.unsubscribe();\n }\n }\n // then subscribe the new callback-fns\n subscribedOutputs = Object.entries(newObservableSubscriptions).map(([key, cb]) => {\n const existing = subscribedOutputs.find(([k]) => k === key);\n return existing && existing[1] === cb\n ? existing // nothing to do\n : subscribeToComponentOutput(fixture, key as keyof SutType, cb as (v: any) => void);\n });\n\n const newComponentProps = properties?.componentProperties ?? {};\n const changesInComponentProps = update(\n fixture,\n renderedPropKeys,\n newComponentProps,\n setComponentProperties,\n properties?.partialUpdate ?? false,\n );\n renderedPropKeys = Object.keys(newComponentProps);\n\n if (hasOnChangesHook(fixture.componentInstance)) {\n fixture.componentInstance.ngOnChanges({\n ...changesInComponentInput,\n ...changesInComponentProps,\n });\n }\n\n if (properties?.detectChangesOnRender !== false) {\n fixture.componentRef.injector.get(ChangeDetectorRef).detectChanges();\n }\n };\n\n const navigate = async (elementOrPath: Element | string, basePath = ''): Promise<boolean> => {\n const result = await _navigate(elementOrPath, basePath);\n detectChanges();\n return result;\n };\n\n return {\n fixture,\n detectChanges: () => detectChanges(),\n navigate,\n rerender,\n renderDeferBlock: async (deferBlockState: DeferBlockState, deferBlockIndex?: number) => {\n await renderDeferBlock(fixture, deferBlockState, deferBlockIndex);\n },\n debugElement: fixture.debugElement,\n container: fixture.nativeElement,\n debug: (element = fixture.nativeElement, maxLength, options) => {\n if (Array.isArray(element)) {\n for (const e of element) {\n console.log(dtlPrettyDOM(e, maxLength, options));\n }\n } else {\n console.log(dtlPrettyDOM(element, maxLength, options));\n }\n },\n ...replaceFindWithFindAndDetectChanges(dtlGetQueriesForElement(fixture.nativeElement, queries)),\n };\n}\n\nasync function createComponent<SutType>(component: Type<SutType>): Promise<ComponentFixture<SutType>> {\n /* Make sure angular application is initialized before creating component */\n await safeInject(ApplicationInitStatus).donePromise;\n return TestBed.createComponent(component);\n}\n\nfunction createComponentFixture<SutType, WrapperType>(\n sut: Type<SutType> | string,\n wrapper: Type<WrapperType>,\n): Type<any> {\n if (typeof sut === 'string') {\n TestBed.overrideTemplate(wrapper, sut);\n return wrapper;\n }\n return sut;\n}\n\nfunction setComponentProperties<SutType>(\n fixture: ComponentFixture<SutType>,\n componentProperties: RenderTemplateOptions<SutType, any>['componentProperties'] = {},\n) {\n for (const key of Object.keys(componentProperties)) {\n const descriptor = Object.getOwnPropertyDescriptor((fixture.componentInstance as any).constructor.prototype, key);\n let _value = componentProperties[key];\n const defaultGetter = () => _value;\n const extendedSetter = (value: any) => {\n _value = value;\n descriptor?.set?.call(fixture.componentInstance, _value);\n fixture.detectChanges();\n };\n\n Object.defineProperty(fixture.componentInstance, key, {\n get: descriptor?.get || defaultGetter,\n set: extendedSetter,\n // Allow the property to be defined again later.\n // This happens when the component properties are updated after initial render.\n // For Jest this is `true` by default, for Karma and a real browser the default is `false`\n configurable: true,\n });\n\n descriptor?.set?.call(fixture.componentInstance, _value);\n }\n return fixture;\n}\n\nfunction setComponentOutputs<SutType>(\n fixture: ComponentFixture<SutType>,\n componentOutputs: RenderTemplateOptions<SutType, any>['componentOutputs'] = {},\n) {\n for (const [name, value] of Object.entries(componentOutputs)) {\n (fixture.componentInstance as any)[name] = value;\n }\n}\n\nfunction setComponentInputs<SutType>(\n fixture: ComponentFixture<SutType>,\n componentInputs: RenderTemplateOptions<SutType>['componentInputs'] = {},\n) {\n for (const [name, value] of Object.entries(componentInputs)) {\n fixture.componentRef.setInput(name, value);\n }\n}\n\nfunction subscribeToComponentOutputs<SutType>(\n fixture: ComponentFixture<SutType>,\n listeners: OutputRefKeysWithCallback<SutType>,\n): SubscribedOutput<SutType>[] {\n // with Object.entries we lose the type information of the key and callback, therefore we need to cast them\n return Object.entries(listeners).map(([key, cb]) =>\n subscribeToComponentOutput(fixture, key as keyof SutType, cb as (v: any) => void),\n );\n}\n\nfunction subscribeToComponentOutput<SutType>(\n fixture: ComponentFixture<SutType>,\n key: keyof SutType,\n cb: (val: any) => void,\n): SubscribedOutput<SutType> {\n const eventEmitter = (fixture.componentInstance as any)[key] as OutputRef<any>;\n const subscription = eventEmitter.subscribe(cb);\n fixture.componentRef.onDestroy(subscription.unsubscribe.bind(subscription));\n return [key, cb, subscription];\n}\n\nfunction overrideComponentImports<SutType>(sut: Type<SutType> | string, imports: (Type<any> | any[])[] | undefined) {\n if (imports) {\n if (typeof sut === 'function' && isStandalone(sut)) {\n TestBed.overrideComponent(sut, { set: { imports } });\n } else {\n throw new Error(\n `Error while rendering ${sut}: Cannot specify componentImports on a template or non-standalone component.`,\n );\n }\n }\n}\n\nfunction overrideChildComponentProviders(componentOverrides: ComponentOverride<any>[]) {\n if (componentOverrides) {\n for (const { component, providers } of componentOverrides) {\n TestBed.overrideComponent(component, { set: { providers } });\n }\n }\n}\n\nfunction hasOnChangesHook<SutType>(componentInstance: SutType): componentInstance is SutType & OnChanges {\n return (\n componentInstance !== null &&\n typeof componentInstance === 'object' &&\n 'ngOnChanges' in componentInstance &&\n typeof (componentInstance as SutType & OnChanges).ngOnChanges === 'function'\n );\n}\n\nfunction getChangesObj(oldProps: Record<string, any> | null, newProps: Record<string, any>) {\n const isFirstChange = oldProps === null;\n return Object.keys(newProps).reduce<SimpleChanges>((changes, key) => {\n changes[key] = new SimpleChange(isFirstChange ? null : oldProps[key], newProps[key], isFirstChange);\n return changes;\n }, {} as Record<string, any>);\n}\n\nfunction update<SutType>(\n fixture: ComponentFixture<SutType>,\n prevRenderedKeys: string[],\n newValues: Record<string, any>,\n updateFunction: (\n fixture: ComponentFixture<SutType>,\n values: RenderTemplateOptions<SutType>['componentInputs' | 'componentProperties'],\n ) => void,\n partialUpdate: boolean,\n) {\n const componentInstance = fixture.componentInstance as Record<string, any>;\n const simpleChanges: SimpleChanges = {};\n\n if (!partialUpdate) {\n for (const key of prevRenderedKeys) {\n if (!Object.prototype.hasOwnProperty.call(newValues, key)) {\n simpleChanges[key] = new SimpleChange(componentInstance[key], undefined, false);\n delete componentInstance[key];\n }\n }\n }\n\n for (const [key, value] of Object.entries(newValues)) {\n if (value !== componentInstance[key]) {\n simpleChanges[key] = new SimpleChange(componentInstance[key], value, false);\n }\n }\n\n updateFunction(fixture, newValues);\n\n return simpleChanges;\n}\n\nfunction addAutoDeclarations<SutType>(\n sut: Type<SutType> | string,\n {\n declarations = [],\n excludeComponentDeclaration,\n wrapper,\n }: Pick<RenderTemplateOptions<any>, 'declarations' | 'excludeComponentDeclaration' | 'wrapper'>,\n) {\n const nonStandaloneDeclarations = declarations?.filter((d) => !isStandalone(d));\n if (typeof sut === 'string') {\n if (wrapper && isStandalone(wrapper)) {\n return nonStandaloneDeclarations;\n }\n return [...nonStandaloneDeclarations, wrapper];\n }\n\n const components = () => (excludeComponentDeclaration || isStandalone(sut) ? [] : [sut]);\n return [...nonStandaloneDeclarations, ...components()];\n}\n\nfunction addAutoImports<SutType>(\n sut: Type<SutType> | string,\n { imports = [], routes }: Pick<RenderComponentOptions<any>, 'imports' | 'routes'>,\n) {\n const animations = () => {\n const animationIsDefined =\n imports.indexOf(NoopAnimationsModule) > -1 || imports.indexOf(BrowserAnimationsModule) > -1;\n return animationIsDefined ? [] : [NoopAnimationsModule];\n };\n\n const routing = () => (routes ? [RouterTestingModule.withRoutes(routes)] : []);\n const components = () => (typeof sut !== 'string' && isStandalone(sut) ? [sut] : []);\n return [...imports, ...components(), ...animations(), ...routing()];\n}\n\nasync function renderDeferBlock<SutType>(\n fixture: ComponentFixture<SutType>,\n deferBlockState: DeferBlockState,\n deferBlockIndex?: number,\n) {\n const deferBlockFixtures = await fixture.getDeferBlocks();\n\n if (deferBlockIndex !== undefined) {\n if (deferBlockIndex < 0) {\n throw new Error('deferBlockIndex must be a positive number');\n }\n\n const deferBlockFixture = deferBlockFixtures[deferBlockIndex];\n if (!deferBlockFixture) {\n throw new Error(`Could not find a deferrable block with index '${deferBlockIndex}'`);\n }\n await deferBlockFixture.render(deferBlockState);\n } else {\n for (const deferBlockFixture of deferBlockFixtures) {\n await deferBlockFixture.render(deferBlockState);\n }\n }\n}\n\n/**\n * Wrap waitFor to invoke the Angular change detection cycle before invoking the callback\n */\nasync function waitForWrapper<T>(\n detectChanges: () => void,\n callback: () => T extends Promise<any> ? never : T,\n options?: dtlWaitForOptions,\n): Promise<T> {\n let inFakeAsync = true;\n try {\n tick(0);\n } catch {\n inFakeAsync = false;\n }\n\n return await dtlWaitFor(() => {\n setTimeout(() => detectChanges(), 0);\n if (inFakeAsync) {\n tick(0);\n }\n return callback();\n }, options);\n}\n\n/**\n * Wrap waitForElementToBeRemovedWrapper to poke the Angular change detection cycle before invoking the callback\n */\nasync function waitForElementToBeRemovedWrapper<T>(\n detectChanges: () => void,\n callback: (() => T) | T,\n options?: dtlWaitForOptions,\n): Promise<void> {\n let cb: () => T;\n if (typeof callback !== 'function') {\n const elements = (Array.isArray(callback) ? callback : [callback]) as Element[];\n const getRemainingElements = elements.map((element) => {\n let parent = element.parentElement as Element;\n while (parent.parentElement) {\n parent = parent.parentElement;\n }\n return () => (parent.contains(element) ? element : null);\n });\n cb = () => getRemainingElements.map((c) => c()).find(Boolean) as unknown as T;\n } else {\n cb = callback as () => T;\n }\n\n return await dtlWaitForElementToBeRemoved(() => {\n const result = cb();\n detectChanges();\n return result;\n }, options);\n}\n\nfunction cleanup() {\n mountedFixtures.forEach(cleanupAtFixture);\n}\n\nfunction cleanupAtFixture(fixture: ComponentFixture<any>) {\n fixture.destroy();\n\n if (!fixture.nativeElement.getAttribute('ng-version') && fixture.nativeElement.parentNode === document.body) {\n document.body.removeChild(fixture.nativeElement);\n } else if (!fixture.nativeElement.getAttribute('id') && document.body.children?.[0] === fixture.nativeElement) {\n document.body.removeChild(fixture.nativeElement);\n }\n\n mountedFixtures.delete(fixture);\n}\n\n// if we're running in a test runner that supports afterEach\n// then we'll automatically run cleanup afterEach test\n// this ensures that tests run in isolation from each other\n// if you don't like this, set the ATL_SKIP_AUTO_CLEANUP env variable to 'true'\nif (typeof process === 'undefined' || !process.env?.ATL_SKIP_AUTO_CLEANUP) {\n if (typeof afterEach === 'function') {\n afterEach(() => {\n cleanup();\n });\n }\n}\n\n@Component({ selector: 'atl-wrapper-component', template: '', standalone: false })\nclass WrapperComponent {}\n\n/**\n * Wrap findBy queries to poke the Angular change detection cycle\n */\nfunction replaceFindWithFindAndDetectChanges<T extends Record<string, any>>(originalQueriesForContainer: T): T {\n return Object.keys(originalQueriesForContainer).reduce((newQueries, key) => {\n const getByQuery = originalQueriesForContainer[key.replace('find', 'get')];\n if (key.startsWith('find') && getByQuery) {\n newQueries[key] = async (...queryOptions: any[]) => {\n const waitOptions = queryOptions.length === 3 ? queryOptions.pop() : undefined;\n // original implementation at https://github.com/testing-library/dom-testing-library/blob/main/src/query-helpers.js\n return await waitForWrapper(detectChangesForMountedFixtures, () => getByQuery(...queryOptions), waitOptions);\n };\n } else {\n newQueries[key] = originalQueriesForContainer[key];\n }\n\n return newQueries;\n }, {} as Record<string, any>) as T;\n}\n\n/**\n * Call detectChanges for all fixtures\n */\nfunction detectChangesForMountedFixtures() {\n for (const fixture of mountedFixtures) {\n try {\n fixture.detectChanges();\n } catch (err: any) {\n if (!err.message.startsWith('ViewDestroyedError')) {\n throw err;\n }\n }\n }\n}\n\n/**\n * Re-export screen with patched queries\n */\nconst screen = replaceFindWithFindAndDetectChanges(dtlScreen);\n\n/**\n * Re-export within with patched queries\n */\nconst within = <QueriesToBind extends Queries = typeof dtlQueries, T extends QueriesToBind = QueriesToBind>(\n element: HTMLElement,\n queriesToBind?: T,\n): BoundFunctions<T> => {\n const container = dtlWithin<T>(element, queriesToBind);\n return replaceFindWithFindAndDetectChanges(container);\n};\n\n/**\n * Re-export waitFor with patched waitFor\n */\nasync function waitFor<T>(callback: () => T extends Promise<any> ? never : T, options?: dtlWaitForOptions): Promise<T> {\n return waitForWrapper(detectChangesForMountedFixtures, callback, options);\n}\n\n/**\n * Re-export waitForElementToBeRemoved with patched waitForElementToBeRemoved\n */\nasync function waitForElementToBeRemoved<T>(callback: (() => T) | T, options?: dtlWaitForOptions): Promise<void> {\n return waitForElementToBeRemovedWrapper(detectChangesForMountedFixtures, callback, options);\n}\n\n/**\n * Manually export otherwise we get the following error while running Jest tests\n * TypeError: Cannot set property fireEvent of [object Object] which has only a getter\n * exports.fireEvent = fireEvent\n */\nexport {\n fireEvent,\n buildQueries,\n getByLabelText,\n getAllByLabelText,\n queryByLabelText,\n queryAllByLabelText,\n findByLabelText,\n findAllByLabelText,\n getByPlaceholderText,\n getAllByPlaceholderText,\n queryByPlaceholderText,\n queryAllByPlaceholderText,\n findByPlaceholderText,\n findAllByPlaceholderText,\n getByText,\n getAllByText,\n queryByText,\n queryAllByText,\n findByText,\n findAllByText,\n getByAltText,\n getAllByAltText,\n queryByAltText,\n queryAllByAltText,\n findByAltText,\n findAllByAltText,\n getByTitle,\n getAllByTitle,\n queryByTitle,\n queryAllByTitle,\n findByTitle,\n findAllByTitle,\n getByDisplayValue,\n getAllByDisplayValue,\n queryByDisplayValue,\n queryAllByDisplayValue,\n findByDisplayValue,\n findAllByDisplayValue,\n getByRole,\n getAllByRole,\n queryByRole,\n queryAllByRole,\n findByRole,\n findAllByRole,\n getByTestId,\n getAllByTestId,\n queryByTestId,\n queryAllByTestId,\n findByTestId,\n findAllByTestId,\n createEvent,\n getDefaultNormalizer,\n getElementError,\n getNodeText,\n getQueriesForElement,\n getRoles,\n isInaccessible,\n logDOM,\n logRoles,\n prettyDOM,\n queries,\n queryAllByAttribute,\n queryByAttribute,\n queryHelpers,\n} from '@testing-library/dom';\n\n// export patched dtl\nexport { screen, waitFor, waitForElementToBeRemoved, within };\n","/*\n * Public API Surface of testing-library\n */\n\nexport * from './lib/models';\nexport * from './lib/config';\nexport * from './lib/testing-library';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["dtlConfigure","dtlPrettyDOM","dtlGetQueriesForElement","dtlWaitFor","dtlWaitForElementToBeRemoved","dtlScreen","dtlWithin"],"mappings":";;;;;;;;;AAwGA;;;;AAIG;AACa,SAAA,YAAY,CAA2B,KAAa,EAAE,KAAQ,EAAA;AAC5E,IAAA,OAAO,EAAE,CAAC,KAAK,GAAG,KAAK,EAAqC;AAC9D;;AC7GA,IAAI,MAAM,GAAW;AACnB,IAAA,GAAG,EAAE,EAAE;AACP,IAAA,cAAc,EAAE,EAAE;CACnB;AAEK,SAAU,SAAS,CAAC,SAA2E,EAAA;AACnG,IAAA,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE;;;AAGnC,QAAA,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;;;AAI/B,IAAA,MAAM,GAAG;AACP,QAAA,GAAG,MAAM;AACT,QAAA,GAAG,SAAS;KACb;AACH;SAEgB,SAAS,GAAA;AACvB,IAAA,OAAO,MAAM;AACf;;ACkBA,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyB;AACxD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG;AAWzC,eAAe,MAAM,CAC1B,GAA2B,EAC3B,gBAAsF,EAAE,EAAA;IAExF,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,GAAG,SAAS,EAAE;IACvD,MAAM,EACJ,qBAAqB,GAAG,IAAI,EAC5B,iBAAiB,GAAG,IAAI,EACxB,YAAY,GAAG,EAAE,EACjB,OAAO,GAAG,EAAE,EACZ,SAAS,GAAG,EAAE,EACd,OAAO,GAAG,EAAE,EACZ,OAAO,EACP,OAAO,GAAG,gBAAqC,EAC/C,mBAAmB,GAAG,EAAE,EACxB,eAAe,GAAG,EAAE,EACpB,gBAAgB,GAAG,EAAE,EACrB,MAAM,EAAE,SAAS,GAAG,EAAE,EACtB,EAAE,GAAG,EAAE,EACP,kBAAkB,GAAG,EAAE,EACvB,uBAAuB,GAAG,EAAE,EAC5B,gBAAgB,EAChB,2BAA2B,GAAG,KAAK,EACnC,MAAM,GAAG,EAAE,EACX,uBAAuB,GAAG,KAAK,EAC/B,cAAc,GAAG,EAAE,EACnB,YAAY,GAAG,EAAE,EACjB,gBAAgB,GAAG,SAAS,EAC5B,kBAAkB,GAAG,SAAS,EAC9B,gBAAgB,GAAG,MAAK;;KAEvB,GACF,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,aAAa,EAE/B;AAER,IAAAA,WAAY,CAAC;AACX,QAAA,YAAY,EAAE,CAAC,EAAE,KAAI;AACnB,YAAA,MAAM,MAAM,GAAG,EAAE,EAAE;YACnB,IAAI,iBAAiB,EAAE;AACrB,gBAAA,+BAA+B,EAAE;;AAEnC,YAAA,OAAO,MAAM;SACd;AACD,QAAA,GAAG,SAAS;AACb,KAAA,CAAC;IAEF,OAAO,CAAC,sBAAsB,CAAC;AAC7B,QAAA,YAAY,EAAE,mBAAmB,CAAC,GAAG,EAAE;YACrC,YAAY;YACZ,2BAA2B;YAC3B,OAAO;SACR,CAAC;AACF,QAAA,OAAO,EAAE,cAAc,CAAC,GAAG,EAAE;AAC3B,YAAA,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;YACvC,MAAM;SACP,CAAC;AACF,QAAA,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC;AACzB,QAAA,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC;AACrB,QAAA,kBAAkB,EAAE,kBAAkB,IAAI,kBAAkB,CAAC,MAAM;AACpE,KAAA,CAAC;AACF,IAAA,wBAAwB,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/C,+BAA+B,CAAC,uBAAuB,CAAC;IAExD,gBAAgB,CAAC,OAAO,CAAC;AAEzB,IAAA,MAAM,OAAO,CAAC,iBAAiB,EAAE;;AAGjC,IAAA,KAAK,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACxE,QAAA,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC;;IAG7C,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC;AAE/D,IAAA,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC;AAC/B,IAAA,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IACjC,MAAM,SAAS,GAAG,OAAO,aAA+B,EAAE,QAAQ,GAAG,EAAE,KAAsB;AAC3F,QAAA,MAAM,IAAI,GAAG,OAAO,aAAa,KAAK,QAAQ,GAAG,aAAa,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;AACnG,QAAA,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;QACnD,MAAM,WAAW,GAAG;AAClB,cAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,KAAI;AACjC,gBAAA,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;AACjC,gBAAA,MAAM,YAAY,GAAG,EAAE,CAAC,GAAG,CAAC;AAC5B,gBAAA,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;AACvC,oBAAA,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK;;AACV,qBAAA,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;oBACtC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC;;qBAC7B;oBACL,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC;;AAEjC,gBAAA,OAAO,EAAE;aACV,EAAE,EAAuC;cAC1C,SAAS;QAEb,MAAM,eAAe,GAAiC;AACpD,cAAE;gBACE,WAAW;AACZ;cACD,SAAS;QAEb,MAAM,UAAU,GAAG,MAAK;YACtB,OAAO,eAAe,GAAG,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,GAAG,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;AAC/F,SAAC;AAED,QAAA,IAAI,MAAM;QAEV,IAAI,IAAI,EAAE;AACR,YAAA,MAAM,IAAI,CAAC,GAAG,CAAC,MAAK;gBAClB,MAAM,GAAG,UAAU,EAAE;AACvB,aAAC,CAAC;;aACG;YACL,MAAM,GAAG,UAAU,EAAE;;QAEvB,OAAO,MAAM,IAAI,KAAK;AACxB,KAAC;AAED,IAAA,IAAI,YAAY;AAAE,QAAA,MAAM,SAAS,CAAC,YAAY,CAAC;AAE/C,IAAA,IAAI,OAAO,MAAM,EAAE,iBAAiB,KAAK,UAAU,EAAE;QACnD,IAAI,IAAI,EAAE;YACR,IAAI,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC;;aACrC;YACL,MAAM,CAAC,iBAAiB,EAAE;;;AAI9B,IAAA,IAAI,aAAyB;IAE7B,MAAM,SAAS,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,SAAS,EAAE;IAEtD,IAAI,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC;IACvD,IAAI,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;IAC9C,IAAI,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;IACtD,IAAI,iBAAiB,GAAgC,EAAE;AAEvD,IAAA,MAAM,aAAa,GAAG,OACpB,UAA4B,EAC5B,MAAwB,EACxB,OAAyB,EACzB,WAA+C,KACT;AACtC,QAAA,MAAM,cAAc,GAA8B,MAAM,eAAe,CAAC,kBAAkB,CAAC;AAC3F,QAAA,sBAAsB,CAAC,cAAc,EAAE,UAAU,CAAC;AAClD,QAAA,kBAAkB,CAAC,cAAc,EAAE,MAAM,CAAC;AAC1C,QAAA,mBAAmB,CAAC,cAAc,EAAE,OAAO,CAAC;AAC5C,QAAA,iBAAiB,GAAG,2BAA2B,CAAC,cAAc,EAAE,WAAW,CAAC;QAE5E,IAAI,uBAAuB,EAAE;AAC3B,YAAA,cAAc,CAAC,aAAa,CAAC,eAAe,CAAC,YAAY,CAAC;YAC1D,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC;AACnE,YAAA,IAAI,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE;AACnC,gBAAA,cAAc,CAAC,aAAa,CAAC,eAAe,CAAC,IAAI,CAAC;;;AAItD,QAAA,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC;QAEnC,IAAI,OAAO,GAAG,IAAI;AAClB,QAAA,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,MAAK;YACzC,OAAO,GAAG,KAAK;AACjB,SAAC,CAAC;AAEF,QAAA,IAAI,gBAAgB,CAAC,cAAc,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC5F,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC;AACxD,YAAA,cAAc,CAAC,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC;;QAGvD,aAAa,GAAG,MAAK;YACnB,IAAI,OAAO,EAAE;gBACX,cAAc,CAAC,aAAa,EAAE;;AAElC,SAAC;QAED,IAAI,qBAAqB,EAAE;AACzB,YAAA,aAAa,EAAE;;AAGjB,QAAA,OAAO,cAAc;AACvB,KAAC;AAED,IAAA,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,mBAAmB,EAAE,SAAgB,EAAE,gBAAgB,EAAE,EAAE,CAAC;IAEhG,IAAI,gBAAgB,EAAE;AACpB,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;AACnC,YAAA,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE;AAC9C,gBAAA,MAAM,gBAAgB,CAAC,OAAO,EAAE,eAAe,CAAC,eAAe,EAAE,eAAe,CAAC,eAAe,CAAC;;;aAE9F;AACL,YAAA,MAAM,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC;;;AAIrD,IAAA,MAAM,QAAQ,GAAG,OACf,UAG+B,KAC7B;AACF,QAAA,MAAM,kBAAkB,GAAG,EAAE,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE;AACpF,QAAA,MAAM,uBAAuB,GAAG,MAAM,CACpC,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EAAE,aAAa,IAAI,KAAK,CACnC;AACD,QAAA,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC;AAEnD,QAAA,MAAM,mBAAmB,GAAG,UAAU,EAAE,gBAAgB,IAAI,EAAE;AAC9D,QAAA,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE;AAC1C,YAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,EAAE;AACzE,gBAAA,OAAQ,OAAO,CAAC,iBAAyB,CAAC,SAAS,CAAC;;;AAGxD,QAAA,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,CAAC;AACjD,QAAA,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC;;AAGrD,QAAA,MAAM,0BAA0B,GAAuC,UAAU,EAAE,EAAE,IAAI,EAAE;QAC3F,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,YAAY,CAAC,IAAI,iBAAiB,EAAE;;AAEvD,YAAA,IAAI,EAAE,GAAG,IAAI,0BAA0B,CAAC,IAAI,EAAE,KAAM,0BAAkC,CAAC,GAAG,CAAC,EAAE;gBAC3F,YAAY,CAAC,WAAW,EAAE;;;;AAI9B,QAAA,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAI;AAC/E,YAAA,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC;AAC3D,YAAA,OAAO,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK;kBAC/B,QAAQ;kBACR,0BAA0B,CAAC,OAAO,EAAE,GAAoB,EAAE,EAAsB,CAAC;AACvF,SAAC,CAAC;AAEF,QAAA,MAAM,iBAAiB,GAAG,UAAU,EAAE,mBAAmB,IAAI,EAAE;AAC/D,QAAA,MAAM,uBAAuB,GAAG,MAAM,CACpC,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EAAE,aAAa,IAAI,KAAK,CACnC;AACD,QAAA,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAEjD,QAAA,IAAI,gBAAgB,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE;AAC/C,YAAA,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC;AACpC,gBAAA,GAAG,uBAAuB;AAC1B,gBAAA,GAAG,uBAAuB;AAC3B,aAAA,CAAC;;AAGJ,QAAA,IAAI,UAAU,EAAE,qBAAqB,KAAK,KAAK,EAAE;AAC/C,YAAA,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,aAAa,EAAE;;AAExE,KAAC;IAED,MAAM,QAAQ,GAAG,OAAO,aAA+B,EAAE,QAAQ,GAAG,EAAE,KAAsB;QAC1F,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC;AACvD,QAAA,aAAa,EAAE;AACf,QAAA,OAAO,MAAM;AACf,KAAC;IAED,OAAO;QACL,OAAO;AACP,QAAA,aAAa,EAAE,MAAM,aAAa,EAAE;QACpC,QAAQ;QACR,QAAQ;AACR,QAAA,gBAAgB,EAAE,OAAO,eAAgC,EAAE,eAAwB,KAAI;YACrF,MAAM,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,eAAe,CAAC;SAClE;QACD,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,SAAS,EAAE,OAAO,CAAC,aAAa;AAChC,QAAA,KAAK,EAAE,CAAC,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,SAAS,EAAE,OAAO,KAAI;AAC7D,YAAA,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AAC1B,gBAAA,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE;AACvB,oBAAA,OAAO,CAAC,GAAG,CAACC,SAAY,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;;;iBAE7C;AACL,gBAAA,OAAO,CAAC,GAAG,CAACA,SAAY,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;;SAEzD;QACD,GAAG,mCAAmC,CAACC,oBAAuB,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;KAChG;AACH;AAEA,eAAe,eAAe,CAAU,SAAwB,EAAA;;AAE9D,IAAA,MAAM,UAAU,CAAC,qBAAqB,CAAC,CAAC,WAAW;AACnD,IAAA,OAAO,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC;AAC3C;AAEA,SAAS,sBAAsB,CAC7B,GAA2B,EAC3B,OAA0B,EAAA;AAE1B,IAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAC3B,QAAA,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC;AACtC,QAAA,OAAO,OAAO;;AAEhB,IAAA,OAAO,GAAG;AACZ;AAEA,SAAS,sBAAsB,CAC7B,OAAkC,EAClC,sBAAkF,EAAE,EAAA;IAEpF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE;AAClD,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAE,OAAO,CAAC,iBAAyB,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC;AACjH,QAAA,IAAI,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC;AACrC,QAAA,MAAM,aAAa,GAAG,MAAM,MAAM;AAClC,QAAA,MAAM,cAAc,GAAG,CAAC,KAAU,KAAI;YACpC,MAAM,GAAG,KAAK;YACd,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM,CAAC;YACxD,OAAO,CAAC,aAAa,EAAE;AACzB,SAAC;QAED,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,EAAE;AACpD,YAAA,GAAG,EAAE,UAAU,EAAE,GAAG,IAAI,aAAa;AACrC,YAAA,GAAG,EAAE,cAAc;;;;AAInB,YAAA,YAAY,EAAE,IAAI;AACnB,SAAA,CAAC;QAEF,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM,CAAC;;AAE1D,IAAA,OAAO,OAAO;AAChB;AAEA,SAAS,mBAAmB,CAC1B,OAAkC,EAClC,mBAA4E,EAAE,EAAA;AAE9E,IAAA,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;AAC3D,QAAA,OAAO,CAAC,iBAAyB,CAAC,IAAI,CAAC,GAAG,KAAK;;AAEpD;AAEA,SAAS,kBAAkB,CACzB,OAAkC,EAClC,kBAAqE,EAAE,EAAA;AAEvE,IAAA,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE;QAC3D,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;;AAE9C;AAEA,SAAS,2BAA2B,CAClC,OAAkC,EAClC,SAA6C,EAAA;;IAG7C,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAC7C,0BAA0B,CAAC,OAAO,EAAE,GAAoB,EAAE,EAAsB,CAAC,CAClF;AACH;AAEA,SAAS,0BAA0B,CACjC,OAAkC,EAClC,GAAkB,EAClB,EAAsB,EAAA;IAEtB,MAAM,YAAY,GAAI,OAAO,CAAC,iBAAyB,CAAC,GAAG,CAAmB;IAC9E,MAAM,YAAY,GAAG,YAAY,