@fhss-web-team/frontend-utils 21.3.1 → 21.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -488,6 +488,161 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
488
488
  args: [{ selector: 'fhss-server-error', imports: [SystemPage], template: "<fhss-system-page [config]=\"config\" ></fhss-system-page>" }]
489
489
  }] });
490
490
 
491
+ function ok(value) {
492
+ return {
493
+ ok: true,
494
+ value,
495
+ };
496
+ }
497
+ function err(error) {
498
+ return {
499
+ ok: false,
500
+ error,
501
+ };
502
+ }
503
+
504
+ const FileTypeMap = {
505
+ gif: ['image/gif', '.gif'],
506
+ avif: ['image/avif', '.avif'],
507
+ jpeg: ['image/jpeg', '.jpeg'],
508
+ png: ['image/png', '.png'],
509
+ svg: ['image/svg+xml', '.svg'],
510
+ webp: ['image/webp', '.webp'],
511
+ pdf: ['application/pdf', '.pdf'],
512
+ word: [
513
+ 'application/msword',
514
+ '.doc',
515
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
516
+ '.docx',
517
+ ],
518
+ markdown: ['text/markdown', '.md'],
519
+ text: ['text/plain', '.txt'],
520
+ csv: ['text/csv', '.csv'],
521
+ excel: [
522
+ 'application/vnd.ms-excel',
523
+ '.xls',
524
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
525
+ '.xlsx',
526
+ ],
527
+ powerpoint: [
528
+ 'application/vnd.ms-powerpoint',
529
+ '.ppt',
530
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
531
+ '.pptx',
532
+ ],
533
+ mpeg: ['video/mpeg', '.mpeg'],
534
+ mp4: ['video/mp4', '.mp4'],
535
+ mp3: ['audio/mpeg', '.mp3'],
536
+ zip: ['application/zip', '.zip', 'application/x-zip-compressed'],
537
+ xml: ['application/xml', '.xml'],
538
+ json: ['application/json', '.json'],
539
+ image: ['image/*'],
540
+ document: [
541
+ 'application/msword',
542
+ '.doc',
543
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
544
+ '.docx',
545
+ 'application/pdf',
546
+ '.pdf',
547
+ 'text/markdown',
548
+ '.md',
549
+ 'text/plain',
550
+ '.txt',
551
+ ],
552
+ spreadsheet: [
553
+ 'application/vnd.ms-excel',
554
+ '.xls',
555
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
556
+ '.xlsx',
557
+ 'text/csv',
558
+ '.csv',
559
+ ],
560
+ presentation: [
561
+ '.ppt',
562
+ 'application/vnd.ms-powerpoint',
563
+ '.pptx',
564
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
565
+ ],
566
+ audio: ['audio/*'],
567
+ video: ['video/*'],
568
+ archive: ['application/zip', '.zip', 'application/x-zip-compressed'],
569
+ data: ['application/xml', '.xml', 'application/json', '.json'],
570
+ };
571
+
572
+ /**
573
+ * Downloads a file from the specified URL.
574
+ *
575
+ * This function performs a HEAD request to check if the file is available
576
+ * before initiating the download. If the file is available, it uses a
577
+ * temporary <a> to initiate a browser download.
578
+ *
579
+ * @param url - The URL of the file to download.
580
+ * @returns A promise that resolves to a Result.
581
+ */
582
+ async function downloadFileFrom(url) {
583
+ const head = await fetch(url, { method: 'HEAD' });
584
+ if (!head.ok) {
585
+ if (head.status === 404)
586
+ return err('Not Found');
587
+ else
588
+ return err('Unknown');
589
+ }
590
+ const a = document.createElement('a');
591
+ a.href = url;
592
+ a.rel = 'noopener';
593
+ document.body.appendChild(a);
594
+ a.click();
595
+ document.body.removeChild(a);
596
+ return ok();
597
+ }
598
+ /**
599
+ * Generates a comma-separated string of unique file types from the given file label groups.
600
+ * This allows the developer to easily define the `<input type="file" />`'s `accept` property.
601
+ * @param groups - An array of file labels to retrieve file types for.
602
+ * @returns A comma-separated string of unique file types.
603
+ */
604
+ function getFileTypes(groups) {
605
+ const allTypes = groups.flatMap(label => FileTypeMap[label]);
606
+ const uniqueTypes = Array.from(new Set(allTypes));
607
+ return uniqueTypes.join(',');
608
+ }
609
+ /**
610
+ * Uploads a file to the specified URL using XMLHttpRequest.
611
+ *
612
+ * @param file - The file to upload
613
+ * @param url - The URL endpoint where the file will be uploaded (PUT request)
614
+ * @param setProgress - Optional callback function to track upload progress as a percentage (0-100)
615
+ * @returns A promise that resolves to a Result object containing either void on success or an UploadError on failure
616
+ */
617
+ function uploadFile(file, url, setProgress) {
618
+ return new Promise(resolve => {
619
+ const xhr = new XMLHttpRequest();
620
+ xhr.open('PUT', url, true);
621
+ xhr.setRequestHeader('Content-Type', file.type);
622
+ if (setProgress) {
623
+ setProgress(0);
624
+ xhr.upload.onprogress = ev => {
625
+ if (ev.lengthComputable) {
626
+ const pct = Math.floor((ev.loaded / ev.total) * 100);
627
+ setProgress(pct);
628
+ }
629
+ };
630
+ }
631
+ xhr.onload = () => {
632
+ if (xhr.status >= 200 && xhr.status < 300) {
633
+ resolve(ok());
634
+ }
635
+ else {
636
+ resolve(err('Upload failed'));
637
+ }
638
+ };
639
+ xhr.onerror = () => {
640
+ resolve(err('Network error during upload'));
641
+ };
642
+ xhr.send(file);
643
+ });
644
+ }
645
+
491
646
  function trpcResource(procedure, input, options) {
492
647
  const currentInput = computed(input, ...(ngDevMode ? [{ debugName: "currentInput" }] : []));
493
648
  const value = linkedSignal(options?.valueComputation ?? (() => options?.initialValue ?? options?.defaultValue), { ...(ngDevMode ? { debugName: "value" } : {}), equal: options?.equal });
@@ -778,5 +933,5 @@ const debounce = (callback, wait) => {
778
933
  * Generated bundle index. Do not edit.
779
934
  */
780
935
 
781
- export { AuthErrorPage, AuthService, ByuFooterComponent, ByuHeaderComponent, ComboBoxComponent, ConfirmationDialog, FHSS_CONFIG, ForbiddenPage, NotFoundPage, ScrollAnchorDirective, ScrollRegistryService, ServerErrorPage, authGuard, debounced, debugTrpcResource, fetchSignal, homeRedirectGuard, permissionGuard, provideFhss, trpcResource };
936
+ export { AuthErrorPage, AuthService, ByuFooterComponent, ByuHeaderComponent, ComboBoxComponent, ConfirmationDialog, FHSS_CONFIG, ForbiddenPage, NotFoundPage, ScrollAnchorDirective, ScrollRegistryService, ServerErrorPage, authGuard, debounced, debugTrpcResource, downloadFileFrom, fetchSignal, getFileTypes, homeRedirectGuard, permissionGuard, provideFhss, trpcResource, uploadFile };
782
937
  //# sourceMappingURL=fhss-web-team-frontend-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fhss-web-team-frontend-utils.mjs","sources":["../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.ts","../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.html","../../../projects/frontend-utils/src/lib/config/lib.config.ts","../../../projects/frontend-utils/src/lib/services/auth/auth.service.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.html","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.html","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.ts","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.html","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.ts","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.html","../../../projects/frontend-utils/src/lib/config/utils.config.ts","../../../projects/frontend-utils/src/lib/services/scroll-registry/scroll-registry.service.ts","../../../projects/frontend-utils/src/lib/directives/scroll-anchor.directive.ts","../../../projects/frontend-utils/src/lib/guards/auth/auth.guard.ts","../../../projects/frontend-utils/src/lib/guards/permission/permission.guard.ts","../../../projects/frontend-utils/src/lib/guards/home-redirect/home-redirect.guard.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.html","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.ts","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.html","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.ts","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.html","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.ts","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.html","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.ts","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.html","../../../projects/frontend-utils/src/lib/signals/trpcResource/trpcResource.ts","../../../projects/frontend-utils/src/lib/signals/fetch-signal/fetch-signal.ts","../../../projects/frontend-utils/src/lib/signals/debounced/debounced.ts","../../../projects/frontend-utils/src/public-api.ts","../../../projects/frontend-utils/src/fhss-web-team-frontend-utils.ts"],"sourcesContent":["import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'byu-footer',\n imports: [],\n templateUrl: './byu-footer.component.html',\n styleUrl: './byu-footer.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuFooterComponent {\n currentYear: number = new Date().getFullYear(); // Automatically updates the year\n}\n","<footer>\n <p class=\"title\"><a href=\"https://www.byu.edu/\">BRIGHAM YOUNG UNIVERSITY</a></p>\n <p>Provo, UT 84602, USA | © {{ currentYear }} All rights reserved.</p>\n <p>\n <a href=\"https://privacy.byu.edu/privacy-notice\">Privacy Notice</a> |\n <a href=\"https://privacy.byu.edu/cookie-prefs\">Cookie Preferences</a>\n </p>\n</footer>\n \n\n","import { InjectionToken } from '@angular/core';\n\nexport const FHSS_CONFIG = new InjectionToken<FhssConfig>('FHSS_CONFIG');\n\nexport interface FhssConfig {\n rolePermissionMap: Record<string, string[]>;\n defaultHomePages: Record<string, string>;\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { FHSS_CONFIG } from '../../config/lib.config';\n\ntype AuthUser = {\n id: string;\n preferredFirstName: string;\n preferredLastName: string;\n roles: string[];\n permissions: string[];\n};\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthService {\n private readonly FhssConfig = inject(FHSS_CONFIG);\n private readonly readyPromise: Promise<AuthUser | null>;\n\n constructor() {\n this.readyPromise = this.whoAmI();\n }\n\n /**\n * Returns a promise that resolves when the authentication service is ready.\n */\n ready() {\n return this.readyPromise;\n }\n\n /**\n * Updates the authentication state by retrieving the current user's information.\n *\n * @returns A promise containing the current user's authentication details.\n */\n update() {\n return this.whoAmI();\n }\n\n readonly authenticated = signal(false);\n readonly userId = signal<string | undefined>(undefined);\n readonly preferredFirstName = signal<string | undefined>(undefined);\n readonly preferredLastName = signal<string | undefined>(undefined);\n readonly roles = signal<string[]>([]);\n readonly permissions = signal<string[]>([]);\n\n /**\n * Contains all of the user's permissions, meaning those explicitly given, as well as\n * those provided by the user's roles.\n *\n * The result is a `Set` containing all unique permissions granted to the user.\n */\n readonly effectivePermissions = computed(\n () =>\n new Set(\n this.roles()\n .flatMap(role => this.FhssConfig.rolePermissionMap[role])\n .concat(this.permissions())\n )\n );\n\n /**\n * Computes the user's preferred full name by concatenating the preferred first name\n * and, if available, the preferred last name separated by a space.\n * If the preferred first name is not set, an empty string is used.\n * If the preferred last name is not set, only the first name is returned.\n *\n * @returns The computed preferred full name as a string.\n */\n readonly preferredName = computed(() => {\n const prefLast = this.preferredLastName();\n return `${this.preferredFirstName() ?? ''}${prefLast ? ` ${prefLast}` : ''}`;\n });\n\n private resetAuthState() {\n this.authenticated.set(false);\n this.userId.set(undefined);\n this.preferredFirstName.set(undefined);\n this.preferredLastName.set(undefined);\n this.roles.set([]);\n this.permissions.set([]);\n }\n\n private setUser(user: AuthUser) {\n this.authenticated.set(true);\n this.userId.set(user.id);\n this.preferredFirstName.set(user.preferredFirstName);\n this.preferredLastName.set(user.preferredLastName);\n this.roles.set(user.roles);\n this.permissions.set(user.permissions);\n }\n\n /**\n * Redirects the user to the login page.\n *\n * @param nextUri - (Optional) The URI to redirect to after login.\n */\n login(nextUri?: string): Promise<void> {\n window.location.href = `/login${nextUri ? `?next_uri=${nextUri}` : ''}`;\n return new Promise(() => {});\n }\n\n /**\n * Logs the user out by resetting the authentication state and redirecting to the logout page.\n */\n logout() {\n this.resetAuthState();\n window.location.href = '/logout';\n return new Promise(() => {});\n }\n\n /**\n * Retrieves information about the currently authenticated user.\n *\n * @returns A promise that resolves to a `WhoAmI` object\n * representing the current user, or `null` if not authenticated or on error.\n */\n private async whoAmI(): Promise<AuthUser | null> {\n try {\n const res = await fetch('/sys/who-am-i');\n const user = await res.json();\n if (!user) {\n this.resetAuthState();\n return null;\n }\n this.setUser(user);\n return user;\n } catch (error) {\n this.resetAuthState();\n return null;\n }\n }\n}\n","import { Component, computed, input } from \"@angular/core\";\nimport { RouterLink, RouterLinkActive, UrlTree, } from \"@angular/router\";\n\nexport type HeaderLink = {\n /** text content of link */\n text: string;\n\n /** \n * If the path is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | readonly any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n};\n\n@Component({\n selector: 'byu-header-link',\n imports: [RouterLink, RouterLinkActive],\n templateUrl: 'byu-header-link.html',\n styleUrl: 'byu-header-link.scss'\n})\nexport class NormalizedHeaderItem {\n headerItem = input.required<HeaderLink | string>();\n\n normalizeHeaderItem = computed(() => {\n const item = this.headerItem();\n if (typeof item === 'string') {\n return {\n text: item,\n routerLink: null,\n href: null,\n newTab: null,\n }\n } else {\n const httpPath = typeof item.path === 'string' && item.path.startsWith('http') ? item.path : null;\n return {\n text: item.text,\n routerLink: httpPath === null ? item.path : null,\n href: httpPath !== null ? httpPath : null,\n newTab: item.newTab ?? false\n }\n }\n })\n}","@let item = normalizeHeaderItem();\n\n@if (item.routerLink) {\n <a [routerLink]=\"item.routerLink\" routerLinkActive=\"active\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else if (item.href) {\n <a [href]=\"item.href\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else {\n <a>{{ item.text }}</a>\n}","import { Component, input, inject, signal, HostListener, ViewEncapsulation } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { UrlTree } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { HeaderLink, NormalizedHeaderItem } from './byu-header-link/byu-header-link';\n\ntype MenuLink<T extends string> = {\n /** text content of the link */\n text: string,\n\n /** \n * If the link is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | readonly any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n\n /** list of permissions that a user must have at least one of to see the link */\n requiredPermissions?: T[];\n\n /** if instead the user should have all of the required permissions */\n haveAll?: boolean;\n\n /** if the user must be authenticated to see the link */\n needsAuthentication?: boolean;\n}\n\ntype MenuDropdown<T extends string> = {\n /** text content of the link */\n text: string;\n\n /** items to display in the dropdown menu */\n items: MenuLink<T>[];\n} \n\ntype HeaderMenu<T extends string> = MenuLink<T> | MenuDropdown<T>\n\nexport type HeaderConfig<Permission extends string> = {\n /** Main site title: a link or plain text */\n title: HeaderLink | string;\n\n /** Optional subtitle: a link or plain text */\n subtitle?: HeaderLink | string;\n\n /** Optional breadcrumbs for navigational context: links or plain texts */\n breadcrumbs?: (HeaderLink | string)[];\n\n /** Optional menu items: links or dropdowns, potentially restricted by authentication or permissions */\n menu?: HeaderMenu<Permission>[];\n}\n\n@Component({\n selector: 'byu-header',\n imports: [NormalizedHeaderItem, NgTemplateOutlet],\n templateUrl: './byu-header.component.html',\n styleUrl: './byu-header.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuHeaderComponent {\n auth = inject(AuthService)\n config = input.required<HeaderConfig<string>>();\n\n openDropdown: MenuDropdown<string> | null = null;\n isMenuOpen = signal(false);\n\n isMenuLink(item: HeaderMenu<string>): item is MenuLink<string> {\n return 'path' in item;\n }\n \n isMenuLinkVisible(link: MenuLink<string>) {\n return link.requiredPermissions !== undefined\n ? link.requiredPermissions[link.haveAll ? 'every' : 'some']((permission) => this.auth.effectivePermissions().has(permission))\n : this.auth.authenticated() || !link.needsAuthentication;\n }\n\n isMenuDropdownVisible(dropdown: MenuDropdown<string>) {\n return dropdown.items.some(item => this.isMenuLinkVisible(item));\n }\n \n toggleDropdown(dropdown: MenuDropdown<string>) {\n this.openDropdown = this.openDropdown === dropdown ? null : dropdown;\n }\n\n toggleMenu() {\n this.isMenuOpen.update(prev => !prev)\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(ev: MouseEvent) {\n const path = (ev.composedPath?.() ?? []);\n const target = path[0];\n\n if (target instanceof Element) {\n if (target.className !== 'nav-item-content') {\n this.openDropdown = null;\n \n if (target.className !== 'hamburger' && target.className !== 'bar') {\n this.isMenuOpen.set(false);\n }\n }\n }\n\n }\n}\n","@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\" />\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\" />\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\" />\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\" />\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\" />\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\" />\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div class=\"nav-item dropdown\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\" />\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n","import { Component, inject, Injectable } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogModule,\n MAT_DIALOG_DATA,\n MatDialog,\n} from '@angular/material/dialog';\n\ntype ConfirmationConfig =\n | {\n title?: string;\n action?: string;\n description?: never;\n buttons?: readonly string[];\n }\n | {\n title?: string;\n action?: never;\n description?: string;\n buttons?: readonly string[];\n };\n\ntype ConfirmationResult<C extends ConfirmationConfig | undefined> = C extends {\n buttons: readonly string[];\n}\n ? C['buttons'][number]\n : boolean;\n\n@Component({\n selector: 'fhss-confirmation',\n imports: [MatDialogModule, MatButtonModule],\n templateUrl: './confirmation.dialog.html',\n styleUrl: './confirmation.dialog.scss',\n})\nclass ConfirmationDialogContainer {\n protected readonly config: ConfirmationConfig | undefined =\n inject(MAT_DIALOG_DATA);\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ConfirmationDialog {\n private readonly dialog = inject(MatDialog);\n\n open<C extends ConfirmationConfig | undefined>(config?: C) {\n const dialogRef = this.dialog.open<\n ConfirmationDialogContainer,\n ConfirmationConfig,\n ConfirmationResult<C>\n >(ConfirmationDialogContainer, {\n data: config,\n });\n\n return dialogRef;\n }\n}\n","<h2 mat-dialog-title>{{ config?.title ?? \"Are you sure?\"}}</h2>\n\n<mat-dialog-content>\n @if (config?.description) {\n <p>{{ config?.description }}</p>\n } @else {\n <p>Are you sure you would like to {{ config?.action ?? 'continue' }}?</p>\n }</mat-dialog-content\n>\n\n<mat-dialog-actions>\n @if (config?.buttons) { @for (name of config?.buttons; track name) {\n <button mat-button [mat-dialog-close]=\"name\">{{name}}</button>\n } } @else {\n <button mat-button [mat-dialog-close]=\"false\">No</button>\n <button mat-button [mat-dialog-close]=\"true\">Yes</button>\n }\n</mat-dialog-actions>\n","import { Component, input, model, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\n\ntype value = string | number;\nexport type Option = { label: string; value: value | null };\n\ntype Boolish = string | boolean | undefined;\nfunction fromBoolish(v: Boolish): boolean {\n if (v === undefined || v === false) return false;\n if (typeof v === 'string') {\n return v.trim().toLowerCase() !== 'false';\n }\n return true;\n}\n\n@Component({\n selector: 'fhss-combo-box',\n imports: [\n MatSelectModule,\n MatButtonModule,\n MatIconModule,\n MatFormFieldModule,\n MatInputModule,\n FormsModule,\n ],\n templateUrl: './combo-box.component.html',\n styleUrl: './combo-box.component.scss',\n})\nexport class ComboBoxComponent {\n options = input.required<Option[]>();\n placeholder = input.required<string>();\n appearance = input<'outline' | 'fill'>('fill');\n multiple = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n showClear = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n\n /**\n * Takes a signal to store the selected value(s) in.\n */\n selected = model.required<value[] | value | null>();\n\n filter = signal('');\n protected isOptionHidden = (opt: Option) =>\n !opt.label.toLowerCase().includes(this.filter().toLowerCase());\n\n clearSelected() {\n if (Array.isArray(this.selected())) {\n this.selected.set([]);\n } else {\n this.selected.set(null);\n }\n }\n}\n","<mat-form-field\n (click)=\"filter.set('')\"\n [appearance]=\"appearance()\"\n subscriptSizing=\"dynamic\">\n <mat-label>{{ placeholder() }}</mat-label>\n <mat-select [(ngModel)]=\"selected\" [multiple]=\"multiple()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <input matInput placeholder=\"Search...\" [(ngModel)]=\"filter\" />\n <button mat-icon-button matSuffix (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n @for (option of options(); track option.value) {\n <mat-option\n [value]=\"option.value\"\n [class.hidden]=\"isOptionHidden(option)\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n\n @if (showClear()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"$event.stopPropagation(); clearSelected()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n</mat-form-field>\n","import { Provider } from \"@angular/core\";\nimport { FHSS_CONFIG, FhssConfig } from \"./lib.config\";\n\nexport const provideFhss = (config: FhssConfig): Provider => ({\n provide: FHSS_CONFIG,\n useValue: config,\n});\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ScrollRegistryService {\n private anchors = new Map<string, HTMLElement>();\n private pending = new Map<string, (() => void)[]>();\n\n register(key: string, el: HTMLElement) {\n this.anchors.set(key, el);\n const queue = this.pending.get(key);\n if (queue) {\n queue.forEach(fn => fn());\n this.pending.delete(key);\n }\n }\n\n unregister(key: string) {\n this.anchors.delete(key);\n }\n\n scrollTo(\n key: string,\n opts: ScrollIntoViewOptions & { delay?: number } = { behavior: 'smooth', block: 'center', delay: 0 }\n ) {\n setTimeout(() => {\n const el = this.anchors.get(key);\n if (el) el.scrollIntoView(opts);\n else {\n const q = this.pending.get(key) ?? [];\n q.push(() => this.anchors.get(key)?.scrollIntoView(opts));\n this.pending.set(key, q);\n }\n }, opts.delay ?? 0)\n }\n}\n","import { Directive, ElementRef, inject, input } from '@angular/core';\nimport { ScrollRegistryService } from '../services/scroll-registry/scroll-registry.service';\n\n@Directive({\n selector: '[scrollAnchor]',\n})\nexport class ScrollAnchorDirective {\n private readonly registery = inject(ScrollRegistryService);\n scrollAnchor = input.required<string>();\n\n constructor(private element: ElementRef<HTMLElement>) {}\n\n ngOnInit() {\n this.registery.register(this.scrollAnchor(), this.element.nativeElement);\n }\n\n ngOnDestroy() {\n this.registery.unregister(this.scrollAnchor());\n }\n}\n","import { inject } from '@angular/core';\nimport { CanActivateFn } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\n\n/**\n * This guard checks if the client is authenticated, redirecting to login if not.\n */\nexport const authGuard: CanActivateFn = async (_route, state) => {\n const authService = inject(AuthService);\n if (!(await authService.ready())) {\n await authService.login(state.url);\n return false;\n }\n return true;\n};\n","import { CanActivateFn, Router } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { inject } from '@angular/core';\n\n/**\n * A permission-based route guard.\n *\n * This guard checks if the current user has the required permissions to access a route.\n * If the user is not authenticated, they are redirected to the login page.\n * If the user lacks the necessary permissions, they are redirected to the `/forbidden` page.\n *\n * Pass the Permission type to get intellisense on requiredPermissions\n * @param requiredPermissions - An array of permission strings that the user must have.\n * @param haveAll - If `true`, the user must have all required permissions. If `false` or omitted, the user must have at least one of the required permissions.\n * @returns A `CanActivateFn` function to be used as a route guard.\n * \n * @example\n * ```typescript\n * const routes: Routes = [\n * {\n * path: 'admin',\n * component: AdminPage,\n * canActivate: [permissionGuard<Permission>(['manage-users', 'see-data'], true)],\n * },\n * ];\n * ```\n */\nexport const permissionGuard: <Permission extends string>(\n requiredPermissions: Permission[],\n haveAll?: boolean,\n) => CanActivateFn = (reqPerms, haveAll) => {\n return async (_route, state) => {\n const router = inject(Router);\n const authService = inject(AuthService);\n\n if (!await authService.ready()) {\n await authService.login(state.url);\n return false;\n }\n\n const hasAccess = reqPerms[haveAll ? 'every' : 'some']((role) =>\n authService.effectivePermissions().has(role),\n );\n\n return hasAccess || router.parseUrl('/forbidden');\n };\n};\n","import { inject } from '@angular/core';\nimport { CanActivateFn, Router, UrlTree } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { FHSS_CONFIG } from '../../config/lib.config';\n\n/**\n * Guard factory that returns a CanActivateFn which redirects an authenticated user\n * to their default \"home\" page based on their role, or to a provided fallback.\n *\n * @param fallbackRedirect - Route path string or UrlTree to use when no role matches or no user is present.\n * @returns A CanActivateFn that resolves to an UrlTree to perform the redirect.\n */\nexport function homeRedirectGuard(\n fallbackRedirect: string | UrlTree\n): CanActivateFn {\n return async () => {\n const { defaultHomePages } = inject(FHSS_CONFIG);\n const router = inject(Router);\n const auth = inject(AuthService);\n const user = await auth.ready();\n\n for (const [role, path] of Object.entries(defaultHomePages)) {\n if (user?.roles.includes(role)) {\n if (path !== undefined) {\n return router.parseUrl(path);\n }\n }\n }\n\n return typeof fallbackRedirect === 'string'\n ? router.parseUrl(fallbackRedirect)\n : fallbackRedirect;\n };\n}\n","import { Component, input } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport type SystemConfig = {\n title?: string,\n message?: string,\n image?: string\n}\n\n@Component({\n selector: 'fhss-system-page',\n imports: [MatButtonModule],\n templateUrl: './system.page.html',\n styleUrl: './system.page.scss',\n})\nexport class SystemPage {\n readonly config = input.required<SystemConfig>();\n}\n","@let title = config().title;\n@let message = config().message;\n@let image = config().image;\n\n<div class=\"container\">\n @if (image) {\n <div [class]=\"['image', image]\"></div>\n }\n <h1>{{ title ?? 'Application Error' }}</h1>\n <p>{{ message ?? 'Oops! Something went wrong!' }}</p>\n <a mat-flat-button href=\"/\">Go back home</a>\n</div>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from \"../system/system.page\";\n\n@Component({\n selector: 'fhss-auth-error',\n imports: [SystemPage],\n templateUrl: './auth-error.page.html',\n styleUrl: './auth-error.page.scss'\n})\nexport class AuthErrorPage {\n protected readonly config: SystemConfig = {\n title: 'Login Failed',\n message: 'Something went wrong while trying to log you in.',\n image: 'sad-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-forbidden',\n imports: [SystemPage],\n templateUrl: './forbidden.page.html',\n styleUrl: './forbidden.page.scss',\n})\nexport class ForbiddenPage {\n protected readonly config: SystemConfig = {\n title: \"403 - Forbidden\",\n message: \"You don't have permission to access this page.\",\n image: 'police-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from '../system/system.page';\n\n@Component({\n selector: 'fhss-not-found',\n imports: [SystemPage],\n templateUrl: './not-found.page.html',\n styleUrl: './not-found.page.scss',\n})\nexport class NotFoundPage {\n protected readonly config: SystemConfig = {\n title: \"404 - Page not found\",\n message: \"The page you are looking for doesn't exist or it may have moved.\",\n image: 'confused-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-server-error',\n imports: [SystemPage],\n templateUrl: './server-error.page.html',\n styleUrl: './server-error.page.scss',\n})\nexport class ServerErrorPage {\n protected readonly config: SystemConfig = {\n title: \"500 - Internal Server Error\",\n message: \"We ran into an unexpected error!\",\n image: 'error-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","import { computed, effect, inject, Injector, linkedSignal, signal } from \"@angular/core\";\nimport { isTRPCClientError, Resolver } from \"@trpc/client\";\nimport { ResolverDef, TrpcResource, TrpcResourceOptions } from \"./trpcResource.types\";\n\nfunction trpcResource<TDef extends ResolverDef>(procedure: Resolver<TDef>, input: () => TDef['input'] | undefined, options?: TrpcResourceOptions<TDef['output']>): TrpcResource<TDef> {\n const currentInput = computed(input);\n\n const value = linkedSignal<TDef['output'] | undefined>(options?.valueComputation ?? (() => options?.initialValue ?? options?.defaultValue), { equal: options?.equal });\n const error = signal<TDef['errorShape'] | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n\n if (options?.autoRefresh) {\n effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n // refresh reads currentInput which triggers the effect\n refresh(controller.signal, true);\n }, { injector: options?.injector || inject(Injector)});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort: boolean = true,\n ):Promise<boolean> => {\n // if we have the special case where the current input is undefined\n // then set everything to it's initial state\n if (currentInput() === undefined) {\n value.set(options?.initialValue ?? options?.defaultValue);\n error.set(undefined);\n isLoading.set(false);\n return true;\n }\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n error.set(undefined);\n\n try {\n value.set(await procedure(currentInput(), {\n signal: abortSignal\n }));\n error.set(undefined)\n } catch (err) {\n if (isTRPCClientError(err)) {\n // if the trpc request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.cause?.name === 'AbortError' && keepLoadingThroughAbort) {\n return false;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n console.error(\"A non-tRPC error has occured on this trpcResource: \", String(err));\n }\n value.set(options?.defaultValue);\n }\n isLoading.set(false);\n return !error();\n }\n\n return {\n value,\n error,\n isLoading,\n refresh\n };\n}\n\nfunction debugTrpcResource<TDef extends ResolverDef>(_trpcResource: TrpcResource<TDef>) {\n return {\n value: _trpcResource.value(),\n error: _trpcResource.error(),\n isLoading: _trpcResource.isLoading(),\n }\n}\n\nexport { debugTrpcResource, trpcResource };","import { computed, effect, EffectRef, inject, Injector, signal, untracked } from '@angular/core';\nimport { FetchSignal, FetchSignalFactory, FetchSignalOptions, FetchSignalRequest, FetchSignalStatus, HttpMethod, Json, ResponseTransformer } from './fetch-signal.types';\n\n\n/**\n * Creates a reactive fetch signal.\n *\n * The request function can include Signals for properties. These are unwrapped in the refresh function.\n */\nfunction createFetchSignal<Response, ErrorResponse, RawResponse>(\n request: () => FetchSignalRequest,\n method: HttpMethod,\n transform: ResponseTransformer<Response>,\n options?: FetchSignalOptions<Response, RawResponse>,\n): FetchSignal<Response, ErrorResponse> {\n // Use a computed signal so that any changes to Signals in the request object trigger updates.\n const currentRequest = computed<FetchSignalRequest>(request);\n\n const value = signal<Response | undefined>(options?.defaultValue, { equal: options?.equal });\n const errorResponse = signal<ErrorResponse | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n const statusCode = signal<number | undefined>(undefined);\n const headers = signal<Record<string, string> | undefined>(undefined);\n\n const status = signal<FetchSignalStatus>('idle');\n const error = signal<Error | undefined>(undefined);\n\n const injector = inject(Injector);\n let effectRef: EffectRef | undefined = undefined;\n if (options?.autoRefresh) {\n effectRef = effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n refresh(controller.signal, true);\n }, { injector: options?.injector || injector});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort?: boolean,\n ) => {\n // if the fetchSignal has been destroyed, do nothing\n if (untracked(status) === 'destroyed') return;\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n errorResponse.set(undefined);\n statusCode.set(undefined);\n headers.set(undefined);\n status.set('loading');\n error.set(undefined);\n\n // Unwrap the current request.\n const req = currentRequest();\n const url = req.url;\n const params = req.params;\n const requestHeaders = req.headers;\n const body = req.body;\n\n // Build URL with query parameters.\n let uri = url;\n if (params) {\n const searchParams = new URLSearchParams();\n for (const key in params) {\n if (params[key] !== undefined)\n searchParams.append(key, String(params[key]));\n }\n uri += (uri.includes('?') ? '&' : '?') + searchParams.toString();\n }\n \n // Filter out undefined header values\n const filteredHeaders = requestHeaders\n ? Object.fromEntries(\n Object.entries(requestHeaders).filter(\n ([, value]) => value !== undefined\n ) as [string, string][]\n )\n : undefined;\n \n try {\n // send the request\n const response = await fetch(uri, {\n method,\n headers: filteredHeaders,\n // Only include a body if one is provided.\n body: body,\n signal: abortSignal,\n });\n\n // set the status code\n statusCode.set(response.status);\n\n // Extract response headers.\n const headersObj: Record<string, string> = {};\n response.headers.forEach((val, key) => {\n headersObj[key] = val;\n });\n headers.set(headersObj);\n\n // if the response is ok, transform the body\n if (response.ok) {\n value.set(await transform(response));\n status.set('resolved');\n } else {\n // try to parse the error as json\n try {\n errorResponse.set(await response.json());\n value.set(undefined);\n status.set('resolved');\n } catch {\n throw new Error('Unable to parse error response.')\n }\n }\n } catch (err: any) {\n if (err instanceof Error) {\n // if the fetch request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.name === 'AbortError' && keepLoadingThroughAbort) {\n return;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n error.set(new Error(String(err)));\n }\n value.set(undefined);\n status.set('error');\n }\n isLoading.set(false);\n };\n\n const destroy = () => {\n // if the fetchSignal has been destroyed, do nothing\n if (status() === 'destroyed') return;\n\n if (effectRef) {\n effectRef.destroy();\n }\n status.set('destroyed');\n value.set(undefined);\n errorResponse.set(undefined);\n isLoading.set(false);\n statusCode.set(undefined);\n headers.set(undefined);\n error.set(undefined);\n }\n\n return {\n value,\n errorResponse,\n isLoading,\n statusCode,\n headers,\n status,\n error,\n refresh,\n destroy\n };\n}\n\n//\n// Helpers for attaching response transforms.\n//\nconst createHelper = <Response, Error>(method: HttpMethod, transform: ResponseTransformer<Response>) =>\n (request: () => FetchSignalRequest, options?: FetchSignalOptions<Response, any>): FetchSignal<Response, Error> =>\n createFetchSignal<Response, Error, any>(request, method, transform, options);\n\n// Transforms\nconst jsonTransformer: ResponseTransformer<any> = (response: Response) => response.json();\nconst textTransformer: ResponseTransformer<string> = (response: Response) => response.text();\nconst blobTransformer: ResponseTransformer<Blob> = (response: Response) => response.blob();\nconst arrayBufferTransformer: ResponseTransformer<ArrayBuffer> = (response: Response) => response.arrayBuffer();\n\n//\n// Build the defaults - GET chain\n//\nconst fetchSignal = createHelper('GET', jsonTransformer) as FetchSignalFactory;\nfetchSignal.json = createHelper('GET', jsonTransformer);\nfetchSignal.text = createHelper('GET', textTransformer);\nfetchSignal.blob = createHelper('GET', blobTransformer);\nfetchSignal.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the GET chain\n//\nfetchSignal.get = createHelper(\n 'GET',\n jsonTransformer,\n) as FetchSignalFactory['get'];\nfetchSignal.get.json = createHelper('GET', jsonTransformer);\nfetchSignal.get.text = createHelper('GET', textTransformer);\nfetchSignal.get.blob = createHelper('GET', blobTransformer);\nfetchSignal.get.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the POST chain.\n//\nfetchSignal.post = createHelper(\n 'POST',\n jsonTransformer,\n) as FetchSignalFactory['post'];\nfetchSignal.post.json = createHelper('POST', jsonTransformer);\nfetchSignal.post.text = createHelper('POST', textTransformer);\nfetchSignal.post.blob = createHelper('POST', blobTransformer);\nfetchSignal.post.arrayBuffer = createHelper('POST', arrayBufferTransformer);\n\n//\n// Build the PUT chain.\n//\nfetchSignal.put = createHelper(\n 'PUT',\n jsonTransformer,\n) as FetchSignalFactory['put'];\nfetchSignal.put.json = createHelper('PUT', jsonTransformer);\nfetchSignal.put.text = createHelper('PUT', textTransformer);\nfetchSignal.put.blob = createHelper('PUT', blobTransformer);\nfetchSignal.put.arrayBuffer = createHelper('PUT', arrayBufferTransformer);\n\n//\n// Build the PATCH chain.\n//\nfetchSignal.patch = createHelper(\n 'PATCH',\n jsonTransformer,\n) as FetchSignalFactory['patch'];\nfetchSignal.patch.json = createHelper('PATCH', jsonTransformer);\nfetchSignal.patch.text = createHelper('PATCH', textTransformer);\nfetchSignal.patch.blob = createHelper('PATCH', blobTransformer);\nfetchSignal.patch.arrayBuffer = createHelper('PATCH', arrayBufferTransformer);\n\n//\n// Build the DELETE chain\n//\nfetchSignal.delete = createHelper(\n 'DELETE',\n jsonTransformer,\n) as FetchSignalFactory['delete'];\nfetchSignal.delete.json = createHelper('DELETE', jsonTransformer);\nfetchSignal.delete.text = createHelper('DELETE', textTransformer);\nfetchSignal.delete.blob = createHelper('DELETE', blobTransformer);\nfetchSignal.delete.arrayBuffer = createHelper('DELETE', arrayBufferTransformer);\n\nexport { fetchSignal };\nexport type { Json };\n\n","import { effect, signal, Signal } from '@angular/core';\n\nexport const debounced = <T>(inputSignal: Signal<T>, wait: number = 400) => {\n const debouncedSignal = signal<T>(inputSignal());\n const setSignal = debounce(value => debouncedSignal.set(value), wait);\n\n effect(() => {\n setSignal(inputSignal());\n });\n\n return debouncedSignal;\n};\n\nconst debounce = (callback: (...args: any[]) => void, wait: number) => {\n let timeoutId: number | undefined;\n return (...args: any[]) => {\n window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(() => {\n callback(...args);\n }, wait);\n };\n};\n","/**\n * Components\n */\nexport * from './lib/components/byu-footer/byu-footer.component';\nexport { ByuHeaderComponent } from './lib/components/byu-header/byu-header.component';\nexport type { HeaderConfig } from './lib/components/byu-header/byu-header.component';\nexport * from './lib/components/confirmation/confirmation.dialog';\nexport * from './lib/components/combo-box/combo-box.component';\n\n/**\n * Config\n */\nexport * from './lib/config/lib.config';\nexport * from './lib/config/utils.config';\n\n/**\n * Directives\n */\nexport * from './lib/directives/scroll-anchor.directive';\n\n/**\n * Guards\n */\nexport * from './lib/guards/auth/auth.guard';\nexport * from './lib/guards/permission/permission.guard';\nexport * from './lib/guards/home-redirect/home-redirect.guard';\n\n/**\n * Pages\n */\nexport * from './lib/pages/auth-error/auth-error.page';\nexport * from './lib/pages/forbidden/forbidden.page';\nexport * from './lib/pages/not-found/not-found.page';\nexport * from './lib/pages/server-error/server-error.page';\n\n/**\n * Services\n */\nexport * from './lib/services/auth/auth.service';\nexport * from './lib/services/scroll-registry/scroll-registry.service';\n\n/**\n * Signals\n */\nexport * from './lib/signals/trpcResource/trpcResource';\nexport * from './lib/signals/fetch-signal/fetch-signal';\nexport * from './lib/signals/debounced/debounced';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"fhss-web-team-frontend-utils.mjs","sources":["../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.ts","../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.html","../../../projects/frontend-utils/src/lib/config/lib.config.ts","../../../projects/frontend-utils/src/lib/services/auth/auth.service.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.html","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.html","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.ts","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.html","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.ts","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.html","../../../projects/frontend-utils/src/lib/config/utils.config.ts","../../../projects/frontend-utils/src/lib/services/scroll-registry/scroll-registry.service.ts","../../../projects/frontend-utils/src/lib/directives/scroll-anchor.directive.ts","../../../projects/frontend-utils/src/lib/guards/auth/auth.guard.ts","../../../projects/frontend-utils/src/lib/guards/permission/permission.guard.ts","../../../projects/frontend-utils/src/lib/guards/home-redirect/home-redirect.guard.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.html","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.ts","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.html","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.ts","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.html","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.ts","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.html","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.ts","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.html","../../../projects/frontend-utils/src/lib/utils/result.ts","../../../projects/frontend-utils/src/lib/services/file/file.types.ts","../../../projects/frontend-utils/src/lib/services/file/file.ts","../../../projects/frontend-utils/src/lib/signals/trpcResource/trpcResource.ts","../../../projects/frontend-utils/src/lib/signals/fetch-signal/fetch-signal.ts","../../../projects/frontend-utils/src/lib/signals/debounced/debounced.ts","../../../projects/frontend-utils/src/public-api.ts","../../../projects/frontend-utils/src/fhss-web-team-frontend-utils.ts"],"sourcesContent":["import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'byu-footer',\n imports: [],\n templateUrl: './byu-footer.component.html',\n styleUrl: './byu-footer.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuFooterComponent {\n currentYear: number = new Date().getFullYear(); // Automatically updates the year\n}\n","<footer>\n <p class=\"title\"><a href=\"https://www.byu.edu/\">BRIGHAM YOUNG UNIVERSITY</a></p>\n <p>Provo, UT 84602, USA | © {{ currentYear }} All rights reserved.</p>\n <p>\n <a href=\"https://privacy.byu.edu/privacy-notice\">Privacy Notice</a> |\n <a href=\"https://privacy.byu.edu/cookie-prefs\">Cookie Preferences</a>\n </p>\n</footer>\n \n\n","import { InjectionToken } from '@angular/core';\n\nexport const FHSS_CONFIG = new InjectionToken<FhssConfig>('FHSS_CONFIG');\n\nexport interface FhssConfig {\n rolePermissionMap: Record<string, string[]>;\n defaultHomePages: Record<string, string>;\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { FHSS_CONFIG } from '../../config/lib.config';\n\ntype AuthUser = {\n id: string;\n preferredFirstName: string;\n preferredLastName: string;\n roles: string[];\n permissions: string[];\n};\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthService {\n private readonly FhssConfig = inject(FHSS_CONFIG);\n private readonly readyPromise: Promise<AuthUser | null>;\n\n constructor() {\n this.readyPromise = this.whoAmI();\n }\n\n /**\n * Returns a promise that resolves when the authentication service is ready.\n */\n ready() {\n return this.readyPromise;\n }\n\n /**\n * Updates the authentication state by retrieving the current user's information.\n *\n * @returns A promise containing the current user's authentication details.\n */\n update() {\n return this.whoAmI();\n }\n\n readonly authenticated = signal(false);\n readonly userId = signal<string | undefined>(undefined);\n readonly preferredFirstName = signal<string | undefined>(undefined);\n readonly preferredLastName = signal<string | undefined>(undefined);\n readonly roles = signal<string[]>([]);\n readonly permissions = signal<string[]>([]);\n\n /**\n * Contains all of the user's permissions, meaning those explicitly given, as well as\n * those provided by the user's roles.\n *\n * The result is a `Set` containing all unique permissions granted to the user.\n */\n readonly effectivePermissions = computed(\n () =>\n new Set(\n this.roles()\n .flatMap(role => this.FhssConfig.rolePermissionMap[role])\n .concat(this.permissions())\n )\n );\n\n /**\n * Computes the user's preferred full name by concatenating the preferred first name\n * and, if available, the preferred last name separated by a space.\n * If the preferred first name is not set, an empty string is used.\n * If the preferred last name is not set, only the first name is returned.\n *\n * @returns The computed preferred full name as a string.\n */\n readonly preferredName = computed(() => {\n const prefLast = this.preferredLastName();\n return `${this.preferredFirstName() ?? ''}${prefLast ? ` ${prefLast}` : ''}`;\n });\n\n private resetAuthState() {\n this.authenticated.set(false);\n this.userId.set(undefined);\n this.preferredFirstName.set(undefined);\n this.preferredLastName.set(undefined);\n this.roles.set([]);\n this.permissions.set([]);\n }\n\n private setUser(user: AuthUser) {\n this.authenticated.set(true);\n this.userId.set(user.id);\n this.preferredFirstName.set(user.preferredFirstName);\n this.preferredLastName.set(user.preferredLastName);\n this.roles.set(user.roles);\n this.permissions.set(user.permissions);\n }\n\n /**\n * Redirects the user to the login page.\n *\n * @param nextUri - (Optional) The URI to redirect to after login.\n */\n login(nextUri?: string): Promise<void> {\n window.location.href = `/login${nextUri ? `?next_uri=${nextUri}` : ''}`;\n return new Promise(() => {});\n }\n\n /**\n * Logs the user out by resetting the authentication state and redirecting to the logout page.\n */\n logout() {\n this.resetAuthState();\n window.location.href = '/logout';\n return new Promise(() => {});\n }\n\n /**\n * Retrieves information about the currently authenticated user.\n *\n * @returns A promise that resolves to a `WhoAmI` object\n * representing the current user, or `null` if not authenticated or on error.\n */\n private async whoAmI(): Promise<AuthUser | null> {\n try {\n const res = await fetch('/sys/who-am-i');\n const user = await res.json();\n if (!user) {\n this.resetAuthState();\n return null;\n }\n this.setUser(user);\n return user;\n } catch (error) {\n this.resetAuthState();\n return null;\n }\n }\n}\n","import { Component, computed, input } from \"@angular/core\";\nimport { RouterLink, RouterLinkActive, UrlTree, } from \"@angular/router\";\n\nexport type HeaderLink = {\n /** text content of link */\n text: string;\n\n /** \n * If the path is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | readonly any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n};\n\n@Component({\n selector: 'byu-header-link',\n imports: [RouterLink, RouterLinkActive],\n templateUrl: 'byu-header-link.html',\n styleUrl: 'byu-header-link.scss'\n})\nexport class NormalizedHeaderItem {\n headerItem = input.required<HeaderLink | string>();\n\n normalizeHeaderItem = computed(() => {\n const item = this.headerItem();\n if (typeof item === 'string') {\n return {\n text: item,\n routerLink: null,\n href: null,\n newTab: null,\n }\n } else {\n const httpPath = typeof item.path === 'string' && item.path.startsWith('http') ? item.path : null;\n return {\n text: item.text,\n routerLink: httpPath === null ? item.path : null,\n href: httpPath !== null ? httpPath : null,\n newTab: item.newTab ?? false\n }\n }\n })\n}","@let item = normalizeHeaderItem();\n\n@if (item.routerLink) {\n <a [routerLink]=\"item.routerLink\" routerLinkActive=\"active\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else if (item.href) {\n <a [href]=\"item.href\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else {\n <a>{{ item.text }}</a>\n}","import { Component, input, inject, signal, HostListener, ViewEncapsulation } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { UrlTree } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { HeaderLink, NormalizedHeaderItem } from './byu-header-link/byu-header-link';\n\ntype MenuLink<T extends string> = {\n /** text content of the link */\n text: string,\n\n /** \n * If the link is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | readonly any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n\n /** list of permissions that a user must have at least one of to see the link */\n requiredPermissions?: T[];\n\n /** if instead the user should have all of the required permissions */\n haveAll?: boolean;\n\n /** if the user must be authenticated to see the link */\n needsAuthentication?: boolean;\n}\n\ntype MenuDropdown<T extends string> = {\n /** text content of the link */\n text: string;\n\n /** items to display in the dropdown menu */\n items: MenuLink<T>[];\n} \n\ntype HeaderMenu<T extends string> = MenuLink<T> | MenuDropdown<T>\n\nexport type HeaderConfig<Permission extends string> = {\n /** Main site title: a link or plain text */\n title: HeaderLink | string;\n\n /** Optional subtitle: a link or plain text */\n subtitle?: HeaderLink | string;\n\n /** Optional breadcrumbs for navigational context: links or plain texts */\n breadcrumbs?: (HeaderLink | string)[];\n\n /** Optional menu items: links or dropdowns, potentially restricted by authentication or permissions */\n menu?: HeaderMenu<Permission>[];\n}\n\n@Component({\n selector: 'byu-header',\n imports: [NormalizedHeaderItem, NgTemplateOutlet],\n templateUrl: './byu-header.component.html',\n styleUrl: './byu-header.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuHeaderComponent {\n auth = inject(AuthService)\n config = input.required<HeaderConfig<string>>();\n\n openDropdown: MenuDropdown<string> | null = null;\n isMenuOpen = signal(false);\n\n isMenuLink(item: HeaderMenu<string>): item is MenuLink<string> {\n return 'path' in item;\n }\n \n isMenuLinkVisible(link: MenuLink<string>) {\n return link.requiredPermissions !== undefined\n ? link.requiredPermissions[link.haveAll ? 'every' : 'some']((permission) => this.auth.effectivePermissions().has(permission))\n : this.auth.authenticated() || !link.needsAuthentication;\n }\n\n isMenuDropdownVisible(dropdown: MenuDropdown<string>) {\n return dropdown.items.some(item => this.isMenuLinkVisible(item));\n }\n \n toggleDropdown(dropdown: MenuDropdown<string>) {\n this.openDropdown = this.openDropdown === dropdown ? null : dropdown;\n }\n\n toggleMenu() {\n this.isMenuOpen.update(prev => !prev)\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(ev: MouseEvent) {\n const path = (ev.composedPath?.() ?? []);\n const target = path[0];\n\n if (target instanceof Element) {\n if (target.className !== 'nav-item-content') {\n this.openDropdown = null;\n \n if (target.className !== 'hamburger' && target.className !== 'bar') {\n this.isMenuOpen.set(false);\n }\n }\n }\n\n }\n}\n","@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\" />\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\" />\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\" />\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\" />\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\" />\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\" />\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div class=\"nav-item dropdown\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\" />\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n","import { Component, inject, Injectable } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogModule,\n MAT_DIALOG_DATA,\n MatDialog,\n} from '@angular/material/dialog';\n\ntype ConfirmationConfig =\n | {\n title?: string;\n action?: string;\n description?: never;\n buttons?: readonly string[];\n }\n | {\n title?: string;\n action?: never;\n description?: string;\n buttons?: readonly string[];\n };\n\ntype ConfirmationResult<C extends ConfirmationConfig | undefined> = C extends {\n buttons: readonly string[];\n}\n ? C['buttons'][number]\n : boolean;\n\n@Component({\n selector: 'fhss-confirmation',\n imports: [MatDialogModule, MatButtonModule],\n templateUrl: './confirmation.dialog.html',\n styleUrl: './confirmation.dialog.scss',\n})\nclass ConfirmationDialogContainer {\n protected readonly config: ConfirmationConfig | undefined =\n inject(MAT_DIALOG_DATA);\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ConfirmationDialog {\n private readonly dialog = inject(MatDialog);\n\n open<C extends ConfirmationConfig | undefined>(config?: C) {\n const dialogRef = this.dialog.open<\n ConfirmationDialogContainer,\n ConfirmationConfig,\n ConfirmationResult<C>\n >(ConfirmationDialogContainer, {\n data: config,\n });\n\n return dialogRef;\n }\n}\n","<h2 mat-dialog-title>{{ config?.title ?? \"Are you sure?\"}}</h2>\n\n<mat-dialog-content>\n @if (config?.description) {\n <p>{{ config?.description }}</p>\n } @else {\n <p>Are you sure you would like to {{ config?.action ?? 'continue' }}?</p>\n }</mat-dialog-content\n>\n\n<mat-dialog-actions>\n @if (config?.buttons) { @for (name of config?.buttons; track name) {\n <button mat-button [mat-dialog-close]=\"name\">{{name}}</button>\n } } @else {\n <button mat-button [mat-dialog-close]=\"false\">No</button>\n <button mat-button [mat-dialog-close]=\"true\">Yes</button>\n }\n</mat-dialog-actions>\n","import { Component, input, model, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\n\ntype value = string | number;\nexport type Option = { label: string; value: value | null };\n\ntype Boolish = string | boolean | undefined;\nfunction fromBoolish(v: Boolish): boolean {\n if (v === undefined || v === false) return false;\n if (typeof v === 'string') {\n return v.trim().toLowerCase() !== 'false';\n }\n return true;\n}\n\n@Component({\n selector: 'fhss-combo-box',\n imports: [\n MatSelectModule,\n MatButtonModule,\n MatIconModule,\n MatFormFieldModule,\n MatInputModule,\n FormsModule,\n ],\n templateUrl: './combo-box.component.html',\n styleUrl: './combo-box.component.scss',\n})\nexport class ComboBoxComponent {\n options = input.required<Option[]>();\n placeholder = input.required<string>();\n appearance = input<'outline' | 'fill'>('fill');\n multiple = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n showClear = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n\n /**\n * Takes a signal to store the selected value(s) in.\n */\n selected = model.required<value[] | value | null>();\n\n filter = signal('');\n protected isOptionHidden = (opt: Option) =>\n !opt.label.toLowerCase().includes(this.filter().toLowerCase());\n\n clearSelected() {\n if (Array.isArray(this.selected())) {\n this.selected.set([]);\n } else {\n this.selected.set(null);\n }\n }\n}\n","<mat-form-field\n (click)=\"filter.set('')\"\n [appearance]=\"appearance()\"\n subscriptSizing=\"dynamic\">\n <mat-label>{{ placeholder() }}</mat-label>\n <mat-select [(ngModel)]=\"selected\" [multiple]=\"multiple()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <input matInput placeholder=\"Search...\" [(ngModel)]=\"filter\" />\n <button mat-icon-button matSuffix (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n @for (option of options(); track option.value) {\n <mat-option\n [value]=\"option.value\"\n [class.hidden]=\"isOptionHidden(option)\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n\n @if (showClear()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"$event.stopPropagation(); clearSelected()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n</mat-form-field>\n","import { Provider } from \"@angular/core\";\nimport { FHSS_CONFIG, FhssConfig } from \"./lib.config\";\n\nexport const provideFhss = (config: FhssConfig): Provider => ({\n provide: FHSS_CONFIG,\n useValue: config,\n});\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ScrollRegistryService {\n private anchors = new Map<string, HTMLElement>();\n private pending = new Map<string, (() => void)[]>();\n\n register(key: string, el: HTMLElement) {\n this.anchors.set(key, el);\n const queue = this.pending.get(key);\n if (queue) {\n queue.forEach(fn => fn());\n this.pending.delete(key);\n }\n }\n\n unregister(key: string) {\n this.anchors.delete(key);\n }\n\n scrollTo(\n key: string,\n opts: ScrollIntoViewOptions & { delay?: number } = { behavior: 'smooth', block: 'center', delay: 0 }\n ) {\n setTimeout(() => {\n const el = this.anchors.get(key);\n if (el) el.scrollIntoView(opts);\n else {\n const q = this.pending.get(key) ?? [];\n q.push(() => this.anchors.get(key)?.scrollIntoView(opts));\n this.pending.set(key, q);\n }\n }, opts.delay ?? 0)\n }\n}\n","import { Directive, ElementRef, inject, input } from '@angular/core';\nimport { ScrollRegistryService } from '../services/scroll-registry/scroll-registry.service';\n\n@Directive({\n selector: '[scrollAnchor]',\n})\nexport class ScrollAnchorDirective {\n private readonly registery = inject(ScrollRegistryService);\n scrollAnchor = input.required<string>();\n\n constructor(private element: ElementRef<HTMLElement>) {}\n\n ngOnInit() {\n this.registery.register(this.scrollAnchor(), this.element.nativeElement);\n }\n\n ngOnDestroy() {\n this.registery.unregister(this.scrollAnchor());\n }\n}\n","import { inject } from '@angular/core';\nimport { CanActivateFn } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\n\n/**\n * This guard checks if the client is authenticated, redirecting to login if not.\n */\nexport const authGuard: CanActivateFn = async (_route, state) => {\n const authService = inject(AuthService);\n if (!(await authService.ready())) {\n await authService.login(state.url);\n return false;\n }\n return true;\n};\n","import { CanActivateFn, Router } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { inject } from '@angular/core';\n\n/**\n * A permission-based route guard.\n *\n * This guard checks if the current user has the required permissions to access a route.\n * If the user is not authenticated, they are redirected to the login page.\n * If the user lacks the necessary permissions, they are redirected to the `/forbidden` page.\n *\n * Pass the Permission type to get intellisense on requiredPermissions\n * @param requiredPermissions - An array of permission strings that the user must have.\n * @param haveAll - If `true`, the user must have all required permissions. If `false` or omitted, the user must have at least one of the required permissions.\n * @returns A `CanActivateFn` function to be used as a route guard.\n * \n * @example\n * ```typescript\n * const routes: Routes = [\n * {\n * path: 'admin',\n * component: AdminPage,\n * canActivate: [permissionGuard<Permission>(['manage-users', 'see-data'], true)],\n * },\n * ];\n * ```\n */\nexport const permissionGuard: <Permission extends string>(\n requiredPermissions: Permission[],\n haveAll?: boolean,\n) => CanActivateFn = (reqPerms, haveAll) => {\n return async (_route, state) => {\n const router = inject(Router);\n const authService = inject(AuthService);\n\n if (!await authService.ready()) {\n await authService.login(state.url);\n return false;\n }\n\n const hasAccess = reqPerms[haveAll ? 'every' : 'some']((role) =>\n authService.effectivePermissions().has(role),\n );\n\n return hasAccess || router.parseUrl('/forbidden');\n };\n};\n","import { inject } from '@angular/core';\nimport { CanActivateFn, Router, UrlTree } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { FHSS_CONFIG } from '../../config/lib.config';\n\n/**\n * Guard factory that returns a CanActivateFn which redirects an authenticated user\n * to their default \"home\" page based on their role, or to a provided fallback.\n *\n * @param fallbackRedirect - Route path string or UrlTree to use when no role matches or no user is present.\n * @returns A CanActivateFn that resolves to an UrlTree to perform the redirect.\n */\nexport function homeRedirectGuard(\n fallbackRedirect: string | UrlTree\n): CanActivateFn {\n return async () => {\n const { defaultHomePages } = inject(FHSS_CONFIG);\n const router = inject(Router);\n const auth = inject(AuthService);\n const user = await auth.ready();\n\n for (const [role, path] of Object.entries(defaultHomePages)) {\n if (user?.roles.includes(role)) {\n if (path !== undefined) {\n return router.parseUrl(path);\n }\n }\n }\n\n return typeof fallbackRedirect === 'string'\n ? router.parseUrl(fallbackRedirect)\n : fallbackRedirect;\n };\n}\n","import { Component, input } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport type SystemConfig = {\n title?: string,\n message?: string,\n image?: string\n}\n\n@Component({\n selector: 'fhss-system-page',\n imports: [MatButtonModule],\n templateUrl: './system.page.html',\n styleUrl: './system.page.scss',\n})\nexport class SystemPage {\n readonly config = input.required<SystemConfig>();\n}\n","@let title = config().title;\n@let message = config().message;\n@let image = config().image;\n\n<div class=\"container\">\n @if (image) {\n <div [class]=\"['image', image]\"></div>\n }\n <h1>{{ title ?? 'Application Error' }}</h1>\n <p>{{ message ?? 'Oops! Something went wrong!' }}</p>\n <a mat-flat-button href=\"/\">Go back home</a>\n</div>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from \"../system/system.page\";\n\n@Component({\n selector: 'fhss-auth-error',\n imports: [SystemPage],\n templateUrl: './auth-error.page.html',\n styleUrl: './auth-error.page.scss'\n})\nexport class AuthErrorPage {\n protected readonly config: SystemConfig = {\n title: 'Login Failed',\n message: 'Something went wrong while trying to log you in.',\n image: 'sad-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-forbidden',\n imports: [SystemPage],\n templateUrl: './forbidden.page.html',\n styleUrl: './forbidden.page.scss',\n})\nexport class ForbiddenPage {\n protected readonly config: SystemConfig = {\n title: \"403 - Forbidden\",\n message: \"You don't have permission to access this page.\",\n image: 'police-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from '../system/system.page';\n\n@Component({\n selector: 'fhss-not-found',\n imports: [SystemPage],\n templateUrl: './not-found.page.html',\n styleUrl: './not-found.page.scss',\n})\nexport class NotFoundPage {\n protected readonly config: SystemConfig = {\n title: \"404 - Page not found\",\n message: \"The page you are looking for doesn't exist or it may have moved.\",\n image: 'confused-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-server-error',\n imports: [SystemPage],\n templateUrl: './server-error.page.html',\n styleUrl: './server-error.page.scss',\n})\nexport class ServerErrorPage {\n protected readonly config: SystemConfig = {\n title: \"500 - Internal Server Error\",\n message: \"We ran into an unexpected error!\",\n image: 'error-duck'\n }\n}\n","<fhss-system-page [config]=\"config\" ></fhss-system-page>","type Ok<T> = { ok: true; value: T };\ntype Err<E = unknown> = { ok: false; error: E };\nexport type Result<T, E> = Ok<T> | Err<E>;\n\nexport function ok<T = undefined>(value?: T): Ok<T>;\nexport function ok(value?: unknown): Ok<unknown> {\n return {\n ok: true,\n value,\n };\n}\n\nexport function err<E>(error: E): Err<E> {\n return {\n ok: false,\n error,\n };\n}\n","import { err as _err, ok as _ok, Result } from '../../utils/result';\n\nexport type FileData = {\n contentType: string;\n size: number;\n fileName: string;\n};\n\nexport type UploadUrlGenerator<E> = (\n fileData: FileData,\n ok: typeof _ok,\n err: typeof _err\n) => Promise<Result<{ url: string; key: string }, E>>;\n\nexport type RequestError = 'Network error during upload' | 'Upload failed';\nexport type UploadError =\n | 'Disabled component'\n | 'No file'\n | 'Url generation failed'\n | 'Unknown'\n | RequestError;\n\nexport type FileType =\n | 'image/gif'\n | '.gif'\n | 'image/avif'\n | '.avif'\n | 'image/jpeg'\n | '.jpeg'\n | 'image/png'\n | '.png'\n | 'image/svg+xml'\n | '.svg'\n | 'image/webp'\n | '.webp'\n | 'image/*'\n | 'application/pdf'\n | '.pdf'\n | 'application/msword'\n | '.doc'\n | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n | '.docx'\n | 'text/markdown'\n | '.md'\n | 'text/plain'\n | '.txt'\n | 'text/csv'\n | '.csv'\n | 'application/vnd.ms-excel'\n | '.xls'\n | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n | '.xlsx'\n | 'application/vnd.ms-powerpoint'\n | '.ppt'\n | 'application/vnd.openxmlformats-officedocument.presentationml.presentation'\n | '.pptx'\n | 'audio/mpeg'\n | '.mp3'\n | 'audio/*'\n | 'video/mp4'\n | '.mp4'\n | 'video/mpeg'\n | '.mpeg'\n | 'video/*'\n | 'application/zip'\n | '.zip'\n | 'application/x-zip-compressed'\n | 'application/xml'\n | '.xml'\n | 'application/json'\n | '.json';\n\nexport type FileLabel =\n | 'image'\n | 'document'\n | 'spreadsheet'\n | 'presentation'\n | 'audio'\n | 'video'\n | 'archive'\n | 'data'\n | 'gif'\n | 'avif'\n | 'jpeg'\n | 'png'\n | 'svg'\n | 'webp'\n | 'pdf'\n | 'word'\n | 'markdown'\n | 'text'\n | 'csv'\n | 'excel'\n | 'powerpoint'\n | 'mp3'\n | 'mpeg'\n | 'mp4'\n | 'zip'\n | 'xml'\n | 'json';\n\nexport const FileTypeMap: Record<FileLabel, FileType[]> = {\n gif: ['image/gif', '.gif'],\n avif: ['image/avif', '.avif'],\n jpeg: ['image/jpeg', '.jpeg'],\n png: ['image/png', '.png'],\n svg: ['image/svg+xml', '.svg'],\n webp: ['image/webp', '.webp'],\n pdf: ['application/pdf', '.pdf'],\n word: [\n 'application/msword',\n '.doc',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n '.docx',\n ],\n markdown: ['text/markdown', '.md'],\n text: ['text/plain', '.txt'],\n csv: ['text/csv', '.csv'],\n excel: [\n 'application/vnd.ms-excel',\n '.xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n '.xlsx',\n ],\n powerpoint: [\n 'application/vnd.ms-powerpoint',\n '.ppt',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n '.pptx',\n ],\n mpeg: ['video/mpeg', '.mpeg'],\n mp4: ['video/mp4', '.mp4'],\n mp3: ['audio/mpeg', '.mp3'],\n zip: ['application/zip', '.zip', 'application/x-zip-compressed'],\n xml: ['application/xml', '.xml'],\n json: ['application/json', '.json'],\n image: ['image/*'],\n document: [\n 'application/msword',\n '.doc',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n '.docx',\n 'application/pdf',\n '.pdf',\n 'text/markdown',\n '.md',\n 'text/plain',\n '.txt',\n ],\n spreadsheet: [\n 'application/vnd.ms-excel',\n '.xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n '.xlsx',\n 'text/csv',\n '.csv',\n ],\n presentation: [\n '.ppt',\n 'application/vnd.ms-powerpoint',\n '.pptx',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n ],\n audio: ['audio/*'],\n video: ['video/*'],\n archive: ['application/zip', '.zip', 'application/x-zip-compressed'],\n data: ['application/xml', '.xml', 'application/json', '.json'],\n} as const;\n","import { err, ok, Result } from '../../utils/result';\nimport { FileLabel, FileTypeMap } from './file.types';\n\ntype DownloadError = 'Not Found' | 'Unknown';\n\n/**\n * Downloads a file from the specified URL.\n *\n * This function performs a HEAD request to check if the file is available\n * before initiating the download. If the file is available, it uses a\n * temporary <a> to initiate a browser download.\n *\n * @param url - The URL of the file to download.\n * @returns A promise that resolves to a Result.\n */\nexport async function downloadFileFrom(\n url: string\n): Promise<Result<void, DownloadError>> {\n const head = await fetch(url, { method: 'HEAD' });\n if (!head.ok) {\n if (head.status === 404) return err('Not Found');\n else return err('Unknown');\n }\n\n const a = document.createElement('a');\n a.href = url;\n a.rel = 'noopener';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n\n return ok();\n}\n\n/**\n * Generates a comma-separated string of unique file types from the given file label groups.\n * This allows the developer to easily define the `<input type=\"file\" />`'s `accept` property.\n * @param groups - An array of file labels to retrieve file types for.\n * @returns A comma-separated string of unique file types.\n */\nexport function getFileTypes(groups: FileLabel[]): string {\n const allTypes = groups.flatMap(label => FileTypeMap[label]);\n const uniqueTypes = Array.from(new Set(allTypes));\n return uniqueTypes.join(',');\n}\n\nexport type UploadError = 'Network error during upload' | 'Upload failed';\n\n/**\n * Uploads a file to the specified URL using XMLHttpRequest.\n *\n * @param file - The file to upload\n * @param url - The URL endpoint where the file will be uploaded (PUT request)\n * @param setProgress - Optional callback function to track upload progress as a percentage (0-100)\n * @returns A promise that resolves to a Result object containing either void on success or an UploadError on failure\n */\nexport function uploadFile(\n file: File,\n url: string,\n setProgress?: (percent: number) => void\n) {\n return new Promise<Result<void, UploadError>>(resolve => {\n const xhr = new XMLHttpRequest();\n\n xhr.open('PUT', url, true);\n xhr.setRequestHeader('Content-Type', file.type);\n\n if (setProgress) {\n setProgress(0);\n xhr.upload.onprogress = ev => {\n if (ev.lengthComputable) {\n const pct = Math.floor((ev.loaded / ev.total) * 100);\n setProgress(pct);\n }\n };\n }\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(ok());\n } else {\n resolve(err('Upload failed'));\n }\n };\n\n xhr.onerror = () => {\n resolve(err('Network error during upload'));\n };\n\n xhr.send(file);\n });\n}\n","import { computed, effect, inject, Injector, linkedSignal, signal } from \"@angular/core\";\nimport { isTRPCClientError, Resolver } from \"@trpc/client\";\nimport { ResolverDef, TrpcResource, TrpcResourceOptions } from \"./trpcResource.types\";\n\nfunction trpcResource<TDef extends ResolverDef>(procedure: Resolver<TDef>, input: () => TDef['input'] | undefined, options?: TrpcResourceOptions<TDef['output']>): TrpcResource<TDef> {\n const currentInput = computed(input);\n\n const value = linkedSignal<TDef['output'] | undefined>(options?.valueComputation ?? (() => options?.initialValue ?? options?.defaultValue), { equal: options?.equal });\n const error = signal<TDef['errorShape'] | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n\n if (options?.autoRefresh) {\n effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n // refresh reads currentInput which triggers the effect\n refresh(controller.signal, true);\n }, { injector: options?.injector || inject(Injector)});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort: boolean = true,\n ):Promise<boolean> => {\n // if we have the special case where the current input is undefined\n // then set everything to it's initial state\n if (currentInput() === undefined) {\n value.set(options?.initialValue ?? options?.defaultValue);\n error.set(undefined);\n isLoading.set(false);\n return true;\n }\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n error.set(undefined);\n\n try {\n value.set(await procedure(currentInput(), {\n signal: abortSignal\n }));\n error.set(undefined)\n } catch (err) {\n if (isTRPCClientError(err)) {\n // if the trpc request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.cause?.name === 'AbortError' && keepLoadingThroughAbort) {\n return false;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n console.error(\"A non-tRPC error has occured on this trpcResource: \", String(err));\n }\n value.set(options?.defaultValue);\n }\n isLoading.set(false);\n return !error();\n }\n\n return {\n value,\n error,\n isLoading,\n refresh\n };\n}\n\nfunction debugTrpcResource<TDef extends ResolverDef>(_trpcResource: TrpcResource<TDef>) {\n return {\n value: _trpcResource.value(),\n error: _trpcResource.error(),\n isLoading: _trpcResource.isLoading(),\n }\n}\n\nexport { debugTrpcResource, trpcResource };","import { computed, effect, EffectRef, inject, Injector, signal, untracked } from '@angular/core';\nimport { FetchSignal, FetchSignalFactory, FetchSignalOptions, FetchSignalRequest, FetchSignalStatus, HttpMethod, Json, ResponseTransformer } from './fetch-signal.types';\n\n\n/**\n * Creates a reactive fetch signal.\n *\n * The request function can include Signals for properties. These are unwrapped in the refresh function.\n */\nfunction createFetchSignal<Response, ErrorResponse, RawResponse>(\n request: () => FetchSignalRequest,\n method: HttpMethod,\n transform: ResponseTransformer<Response>,\n options?: FetchSignalOptions<Response, RawResponse>,\n): FetchSignal<Response, ErrorResponse> {\n // Use a computed signal so that any changes to Signals in the request object trigger updates.\n const currentRequest = computed<FetchSignalRequest>(request);\n\n const value = signal<Response | undefined>(options?.defaultValue, { equal: options?.equal });\n const errorResponse = signal<ErrorResponse | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n const statusCode = signal<number | undefined>(undefined);\n const headers = signal<Record<string, string> | undefined>(undefined);\n\n const status = signal<FetchSignalStatus>('idle');\n const error = signal<Error | undefined>(undefined);\n\n const injector = inject(Injector);\n let effectRef: EffectRef | undefined = undefined;\n if (options?.autoRefresh) {\n effectRef = effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n refresh(controller.signal, true);\n }, { injector: options?.injector || injector});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort?: boolean,\n ) => {\n // if the fetchSignal has been destroyed, do nothing\n if (untracked(status) === 'destroyed') return;\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n errorResponse.set(undefined);\n statusCode.set(undefined);\n headers.set(undefined);\n status.set('loading');\n error.set(undefined);\n\n // Unwrap the current request.\n const req = currentRequest();\n const url = req.url;\n const params = req.params;\n const requestHeaders = req.headers;\n const body = req.body;\n\n // Build URL with query parameters.\n let uri = url;\n if (params) {\n const searchParams = new URLSearchParams();\n for (const key in params) {\n if (params[key] !== undefined)\n searchParams.append(key, String(params[key]));\n }\n uri += (uri.includes('?') ? '&' : '?') + searchParams.toString();\n }\n \n // Filter out undefined header values\n const filteredHeaders = requestHeaders\n ? Object.fromEntries(\n Object.entries(requestHeaders).filter(\n ([, value]) => value !== undefined\n ) as [string, string][]\n )\n : undefined;\n \n try {\n // send the request\n const response = await fetch(uri, {\n method,\n headers: filteredHeaders,\n // Only include a body if one is provided.\n body: body,\n signal: abortSignal,\n });\n\n // set the status code\n statusCode.set(response.status);\n\n // Extract response headers.\n const headersObj: Record<string, string> = {};\n response.headers.forEach((val, key) => {\n headersObj[key] = val;\n });\n headers.set(headersObj);\n\n // if the response is ok, transform the body\n if (response.ok) {\n value.set(await transform(response));\n status.set('resolved');\n } else {\n // try to parse the error as json\n try {\n errorResponse.set(await response.json());\n value.set(undefined);\n status.set('resolved');\n } catch {\n throw new Error('Unable to parse error response.')\n }\n }\n } catch (err: any) {\n if (err instanceof Error) {\n // if the fetch request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.name === 'AbortError' && keepLoadingThroughAbort) {\n return;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n error.set(new Error(String(err)));\n }\n value.set(undefined);\n status.set('error');\n }\n isLoading.set(false);\n };\n\n const destroy = () => {\n // if the fetchSignal has been destroyed, do nothing\n if (status() === 'destroyed') return;\n\n if (effectRef) {\n effectRef.destroy();\n }\n status.set('destroyed');\n value.set(undefined);\n errorResponse.set(undefined);\n isLoading.set(false);\n statusCode.set(undefined);\n headers.set(undefined);\n error.set(undefined);\n }\n\n return {\n value,\n errorResponse,\n isLoading,\n statusCode,\n headers,\n status,\n error,\n refresh,\n destroy\n };\n}\n\n//\n// Helpers for attaching response transforms.\n//\nconst createHelper = <Response, Error>(method: HttpMethod, transform: ResponseTransformer<Response>) =>\n (request: () => FetchSignalRequest, options?: FetchSignalOptions<Response, any>): FetchSignal<Response, Error> =>\n createFetchSignal<Response, Error, any>(request, method, transform, options);\n\n// Transforms\nconst jsonTransformer: ResponseTransformer<any> = (response: Response) => response.json();\nconst textTransformer: ResponseTransformer<string> = (response: Response) => response.text();\nconst blobTransformer: ResponseTransformer<Blob> = (response: Response) => response.blob();\nconst arrayBufferTransformer: ResponseTransformer<ArrayBuffer> = (response: Response) => response.arrayBuffer();\n\n//\n// Build the defaults - GET chain\n//\nconst fetchSignal = createHelper('GET', jsonTransformer) as FetchSignalFactory;\nfetchSignal.json = createHelper('GET', jsonTransformer);\nfetchSignal.text = createHelper('GET', textTransformer);\nfetchSignal.blob = createHelper('GET', blobTransformer);\nfetchSignal.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the GET chain\n//\nfetchSignal.get = createHelper(\n 'GET',\n jsonTransformer,\n) as FetchSignalFactory['get'];\nfetchSignal.get.json = createHelper('GET', jsonTransformer);\nfetchSignal.get.text = createHelper('GET', textTransformer);\nfetchSignal.get.blob = createHelper('GET', blobTransformer);\nfetchSignal.get.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the POST chain.\n//\nfetchSignal.post = createHelper(\n 'POST',\n jsonTransformer,\n) as FetchSignalFactory['post'];\nfetchSignal.post.json = createHelper('POST', jsonTransformer);\nfetchSignal.post.text = createHelper('POST', textTransformer);\nfetchSignal.post.blob = createHelper('POST', blobTransformer);\nfetchSignal.post.arrayBuffer = createHelper('POST', arrayBufferTransformer);\n\n//\n// Build the PUT chain.\n//\nfetchSignal.put = createHelper(\n 'PUT',\n jsonTransformer,\n) as FetchSignalFactory['put'];\nfetchSignal.put.json = createHelper('PUT', jsonTransformer);\nfetchSignal.put.text = createHelper('PUT', textTransformer);\nfetchSignal.put.blob = createHelper('PUT', blobTransformer);\nfetchSignal.put.arrayBuffer = createHelper('PUT', arrayBufferTransformer);\n\n//\n// Build the PATCH chain.\n//\nfetchSignal.patch = createHelper(\n 'PATCH',\n jsonTransformer,\n) as FetchSignalFactory['patch'];\nfetchSignal.patch.json = createHelper('PATCH', jsonTransformer);\nfetchSignal.patch.text = createHelper('PATCH', textTransformer);\nfetchSignal.patch.blob = createHelper('PATCH', blobTransformer);\nfetchSignal.patch.arrayBuffer = createHelper('PATCH', arrayBufferTransformer);\n\n//\n// Build the DELETE chain\n//\nfetchSignal.delete = createHelper(\n 'DELETE',\n jsonTransformer,\n) as FetchSignalFactory['delete'];\nfetchSignal.delete.json = createHelper('DELETE', jsonTransformer);\nfetchSignal.delete.text = createHelper('DELETE', textTransformer);\nfetchSignal.delete.blob = createHelper('DELETE', blobTransformer);\nfetchSignal.delete.arrayBuffer = createHelper('DELETE', arrayBufferTransformer);\n\nexport { fetchSignal };\nexport type { Json };\n\n","import { effect, signal, Signal } from '@angular/core';\n\nexport const debounced = <T>(inputSignal: Signal<T>, wait: number = 400) => {\n const debouncedSignal = signal<T>(inputSignal());\n const setSignal = debounce(value => debouncedSignal.set(value), wait);\n\n effect(() => {\n setSignal(inputSignal());\n });\n\n return debouncedSignal;\n};\n\nconst debounce = (callback: (...args: any[]) => void, wait: number) => {\n let timeoutId: number | undefined;\n return (...args: any[]) => {\n window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(() => {\n callback(...args);\n }, wait);\n };\n};\n","/**\n * Components\n */\nexport * from './lib/components/byu-footer/byu-footer.component';\nexport { ByuHeaderComponent } from './lib/components/byu-header/byu-header.component';\nexport type { HeaderConfig } from './lib/components/byu-header/byu-header.component';\nexport * from './lib/components/confirmation/confirmation.dialog';\nexport * from './lib/components/combo-box/combo-box.component';\n\n/**\n * Config\n */\nexport * from './lib/config/lib.config';\nexport * from './lib/config/utils.config';\n\n/**\n * Directives\n */\nexport * from './lib/directives/scroll-anchor.directive';\n\n/**\n * Guards\n */\nexport * from './lib/guards/auth/auth.guard';\nexport * from './lib/guards/permission/permission.guard';\nexport * from './lib/guards/home-redirect/home-redirect.guard';\n\n/**\n * Pages\n */\nexport * from './lib/pages/auth-error/auth-error.page';\nexport * from './lib/pages/forbidden/forbidden.page';\nexport * from './lib/pages/not-found/not-found.page';\nexport * from './lib/pages/server-error/server-error.page';\n\n/**\n * Services\n */\nexport * from './lib/services/auth/auth.service';\nexport * from './lib/services/file/file';\nexport * from './lib/services/scroll-registry/scroll-registry.service';\n\n/**\n * Signals\n */\nexport * from './lib/signals/trpcResource/trpcResource';\nexport * from './lib/signals/fetch-signal/fetch-signal';\nexport * from './lib/signals/debounced/debounced';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1"],"mappings":";;;;;;;;;;;;;;;;;;;MASa,kBAAkB,CAAA;IAC7B,WAAW,GAAW,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;uGADpC,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,sECT/B,6WAUA,EAAA,MAAA,EAAA,CAAA,+cAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,SAAA,EAAA,CAAA;;2FDDa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,EAAA,OAAA,EACb,EAAE,EAAA,aAAA,EAGI,iBAAiB,CAAC,SAAS,EAAA,QAAA,EAAA,6WAAA,EAAA,MAAA,EAAA,CAAA,+cAAA,CAAA,EAAA;;;MEL/B,WAAW,GAAG,IAAI,cAAc,CAAa,aAAa;;MCY1D,WAAW,CAAA;AACL,IAAA,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;AAChC,IAAA,YAAY;AAE7B,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE;IACnC;AAEA;;AAEG;IACH,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,YAAY;IAC1B;AAEA;;;;AAIG;IACH,MAAM,GAAA;AACJ,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE;IACtB;AAES,IAAA,aAAa,GAAG,MAAM,CAAC,KAAK,yDAAC;AAC7B,IAAA,MAAM,GAAG,MAAM,CAAqB,SAAS,kDAAC;AAC9C,IAAA,kBAAkB,GAAG,MAAM,CAAqB,SAAS,8DAAC;AAC1D,IAAA,iBAAiB,GAAG,MAAM,CAAqB,SAAS,6DAAC;AACzD,IAAA,KAAK,GAAG,MAAM,CAAW,EAAE,iDAAC;AAC5B,IAAA,WAAW,GAAG,MAAM,CAAW,EAAE,uDAAC;AAE3C;;;;;AAKG;AACM,IAAA,oBAAoB,GAAG,QAAQ,CACtC,MACE,IAAI,GAAG,CACL,IAAI,CAAC,KAAK;AACP,SAAA,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC;SACvD,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAC9B,gEACJ;AAED;;;;;;;AAOG;AACM,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAK;AACrC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE;QACzC,OAAO,CAAA,EAAG,IAAI,CAAC,kBAAkB,EAAE,IAAI,EAAE,GAAG,QAAQ,GAAG,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAE,GAAG,EAAE,EAAE;AAC9E,IAAA,CAAC,yDAAC;IAEM,cAAc,GAAA;AACpB,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7B,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;AAC1B,QAAA,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC;AACtC,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;AACrC,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAClB,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;IAC1B;AAEQ,IAAA,OAAO,CAAC,IAAc,EAAA;AAC5B,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACpD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;IACxC;AAEA;;;;AAIG;AACH,IAAA,KAAK,CAAC,OAAgB,EAAA;AACpB,QAAA,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAA,MAAA,EAAS,OAAO,GAAG,CAAA,UAAA,EAAa,OAAO,CAAA,CAAE,GAAG,EAAE,EAAE;QACvE,OAAO,IAAI,OAAO,CAAC,MAAK,EAAE,CAAC,CAAC;IAC9B;AAEA;;AAEG;IACH,MAAM,GAAA;QACJ,IAAI,CAAC,cAAc,EAAE;AACrB,QAAA,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS;QAChC,OAAO,IAAI,OAAO,CAAC,MAAK,EAAE,CAAC,CAAC;IAC9B;AAEA;;;;;AAKG;AACK,IAAA,MAAM,MAAM,GAAA;AAClB,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC;AACxC,YAAA,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE;YAC7B,IAAI,CAAC,IAAI,EAAE;gBACT,IAAI,CAAC,cAAc,EAAE;AACrB,gBAAA,OAAO,IAAI;YACb;AACA,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;AAClB,YAAA,OAAO,IAAI;QACb;QAAE,OAAO,KAAK,EAAE;YACd,IAAI,CAAC,cAAc,EAAE;AACrB,YAAA,OAAO,IAAI;QACb;IACF;uGApHW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cAFV,MAAM,EAAA,CAAA;;2FAEP,WAAW,EAAA,UAAA,EAAA,CAAA;kBAHvB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;MCWY,oBAAoB,CAAA;AAC/B,IAAA,UAAU,GAAG,KAAK,CAAC,QAAQ,qDAAuB;AAElD,IAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAK;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;AAC9B,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,OAAO;AACL,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,UAAU,EAAE,IAAI;AAChB,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,MAAM,EAAE,IAAI;aACb;QACH;aAAO;YACL,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI;YACjG,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,gBAAA,UAAU,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI;gBAChD,IAAI,EAAE,QAAQ,KAAK,IAAI,GAAG,QAAQ,GAAG,IAAI;AACzC,gBAAA,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI;aACxB;QACH;AACF,IAAA,CAAC,+DAAC;uGArBS,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECxBjC,mWAQC,EAAA,MAAA,EAAA,CAAA,q6BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDYW,UAAU,oOAAE,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,uBAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAI3B,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBANhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,OAAA,EAClB,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAA,QAAA,EAAA,mWAAA,EAAA,MAAA,EAAA,CAAA,q6BAAA,CAAA,EAAA;;;MEyC5B,kBAAkB,CAAA;AAC7B,IAAA,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;AAC1B,IAAA,MAAM,GAAG,KAAK,CAAC,QAAQ,iDAAwB;IAE/C,YAAY,GAAgC,IAAI;AAChD,IAAA,UAAU,GAAG,MAAM,CAAC,KAAK,sDAAC;AAE1B,IAAA,UAAU,CAAC,IAAwB,EAAA;QACjC,OAAO,MAAM,IAAI,IAAI;IACvB;AAEA,IAAA,iBAAiB,CAAC,IAAsB,EAAA;AACtC,QAAA,OAAO,IAAI,CAAC,mBAAmB,KAAK;AACpC,cAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;AAC5H,cAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB;IAC1D;AAEA,IAAA,qBAAqB,CAAC,QAA8B,EAAA;AAClD,QAAA,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClE;AAEA,IAAA,cAAc,CAAC,QAA8B,EAAA;AAC3C,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,KAAK,QAAQ,GAAG,IAAI,GAAG,QAAQ;IACtE;IAEA,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;IACvC;AAGA,IAAA,eAAe,CAAC,EAAc,EAAA;QAC5B,MAAM,IAAI,IAAI,EAAE,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;AACxC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;AAEtB,QAAA,IAAI,MAAM,YAAY,OAAO,EAAE;AAC7B,YAAA,IAAI,MAAM,CAAC,SAAS,KAAK,kBAAkB,EAAE;AAC3C,gBAAA,IAAI,CAAC,YAAY,GAAG,IAAI;AAExB,gBAAA,IAAI,MAAM,CAAC,SAAS,KAAK,WAAW,IAAI,MAAM,CAAC,SAAS,KAAK,KAAK,EAAE;AAClE,oBAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;gBAC5B;YACF;QACF;IAEF;uGA5CW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,yBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC7D/B,ktFAoEA,EAAA,MAAA,EAAA,CAAA,o6gBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDZY,oBAAoB,oFAAE,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,SAAA,EAAA,CAAA;;2FAKrC,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;+BACE,YAAY,EAAA,OAAA,EACb,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,EAAA,aAAA,EAGlC,iBAAiB,CAAC,SAAS,EAAA,QAAA,EAAA,ktFAAA,EAAA,MAAA,EAAA,CAAA,o6gBAAA,CAAA,EAAA;;sBA+BzC,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;;AE9D5C,MAMM,2BAA2B,CAAA;AACZ,IAAA,MAAM,GACvB,MAAM,CAAC,eAAe,CAAC;uGAFrB,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA3B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,2BAA2B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClCjC,mmBAkBA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDYY,eAAe,+nBAAE,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,iOAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAItC,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBANhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,EAAA,OAAA,EACpB,CAAC,eAAe,EAAE,eAAe,CAAC,EAAA,QAAA,EAAA,mmBAAA,EAAA;;MAUhC,kBAAkB,CAAA;AACZ,IAAA,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;AAE3C,IAAA,IAAI,CAA2C,MAAU,EAAA;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAIhC,2BAA2B,EAAE;AAC7B,YAAA,IAAI,EAAE,MAAM;AACb,SAAA,CAAC;AAEF,QAAA,OAAO,SAAS;IAClB;uGAbW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cADL,MAAM,EAAA,CAAA;;2FACnB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;AE3BlC,SAAS,WAAW,CAAC,CAAU,EAAA;AAC7B,IAAA,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,KAAK;AAAE,QAAA,OAAO,KAAK;AAChD,IAAA,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;QACzB,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,OAAO;IAC3C;AACA,IAAA,OAAO,IAAI;AACb;MAea,iBAAiB,CAAA;AAC5B,IAAA,OAAO,GAAG,KAAK,CAAC,QAAQ,kDAAY;AACpC,IAAA,WAAW,GAAG,KAAK,CAAC,QAAQ,sDAAU;AACtC,IAAA,UAAU,GAAG,KAAK,CAAqB,MAAM,sDAAC;IAC9C,QAAQ,GAAG,KAAK,CAAmB,KAAK,qDACtC,SAAS,EAAE,WAAW,EAAA,CACtB;IACF,SAAS,GAAG,KAAK,CAAmB,KAAK,sDACvC,SAAS,EAAE,WAAW,EAAA,CACtB;AAEF;;AAEG;AACH,IAAA,QAAQ,GAAG,KAAK,CAAC,QAAQ,mDAA0B;AAEnD,IAAA,MAAM,GAAG,MAAM,CAAC,EAAE,kDAAC;IACT,cAAc,GAAG,CAAC,GAAW,KACrC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;IAEhE,aAAa,GAAA;QACX,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AAClC,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB;aAAO;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QACzB;IACF;uGA1BW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjC9B,g7BA+BA,EAAA,MAAA,EAAA,CAAA,kEAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDRI,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,YAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,QAAA,EAAA,QAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,SAAA,EAAA,QAAA,EAAA,+CAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,SAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,eAAA,EAAA,UAAA,EAAA,8BAAA,EAAA,aAAA,EAAA,UAAA,EAAA,UAAA,EAAA,wBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,2BAAA,EAAA,gBAAA,EAAA,IAAA,EAAA,YAAA,EAAA,0BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,SAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,sFAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACb,kBAAkB,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAClB,cAAc,iYACd,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAKF,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAb7B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB;wBACP,eAAe;wBACf,eAAe;wBACf,aAAa;wBACb,kBAAkB;wBAClB,cAAc;wBACd,WAAW;AACZ,qBAAA,EAAA,QAAA,EAAA,g7BAAA,EAAA,MAAA,EAAA,CAAA,kEAAA,CAAA,EAAA;;;ME1BU,WAAW,GAAG,CAAC,MAAkB,MAAgB;AAC5D,IAAA,OAAO,EAAE,WAAW;AACpB,IAAA,QAAQ,EAAE,MAAM;AACjB,CAAA;;MCDY,qBAAqB,CAAA;AACxB,IAAA,OAAO,GAAG,IAAI,GAAG,EAAuB;AACxC,IAAA,OAAO,GAAG,IAAI,GAAG,EAA0B;IAEnD,QAAQ,CAAC,GAAW,EAAE,EAAe,EAAA;QACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;QACnC,IAAI,KAAK,EAAE;YACT,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;AACzB,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QAC1B;IACF;AAEA,IAAA,UAAU,CAAC,GAAW,EAAA;AACpB,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;IAC1B;AAEA,IAAA,QAAQ,CACN,GAAW,EACX,IAAA,GAAmD,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAA;QAEpG,UAAU,CAAC,MAAK;YACd,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AAChC,YAAA,IAAI,EAAE;AAAE,gBAAA,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC;iBAC1B;AACH,gBAAA,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;gBACrC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1B;AACF,QAAA,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IACrB;uGA9BW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAArB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qBAAqB,cAFpB,MAAM,EAAA,CAAA;;2FAEP,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAHjC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;MCEY,qBAAqB,CAAA;AAIZ,IAAA,OAAA;AAHH,IAAA,SAAS,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAC1D,IAAA,YAAY,GAAG,KAAK,CAAC,QAAQ,uDAAU;AAEvC,IAAA,WAAA,CAAoB,OAAgC,EAAA;QAAhC,IAAA,CAAA,OAAO,GAAP,OAAO;IAA4B;IAEvD,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;IAC1E;IAEA,WAAW,GAAA;QACT,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;IAChD;uGAZW,qBAAqB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAArB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAHjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC3B,iBAAA;;;ACDD;;AAEG;AACI,MAAM,SAAS,GAAkB,OAAO,MAAM,EAAE,KAAK,KAAI;AAC9D,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACvC,IAAI,EAAE,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE;QAChC,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;AAClC,QAAA,OAAO,KAAK;IACd;AACA,IAAA,OAAO,IAAI;AACb;;ACVA;;;;;;;;;;;;;;;;;;;;;;AAsBG;MACU,eAAe,GAGP,CAAC,QAAQ,EAAE,OAAO,KAAI;AACzC,IAAA,OAAO,OAAO,MAAM,EAAE,KAAK,KAAI;AAC7B,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AAEvC,QAAA,IAAI,CAAC,MAAM,WAAW,CAAC,KAAK,EAAE,EAAE;YAC9B,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;AAClC,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,KAC1D,WAAW,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAC7C;QAED,OAAO,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;AACnD,IAAA,CAAC;AACH;;ACzCA;;;;;;AAMG;AACG,SAAU,iBAAiB,CAC/B,gBAAkC,EAAA;IAElC,OAAO,YAAW;QAChB,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;AAChD,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;AAChC,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE;AAE/B,QAAA,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;YAC3D,IAAI,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AAC9B,gBAAA,IAAI,IAAI,KAAK,SAAS,EAAE;AACtB,oBAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC9B;YACF;QACF;QAEA,OAAO,OAAO,gBAAgB,KAAK;AACjC,cAAE,MAAM,CAAC,QAAQ,CAAC,gBAAgB;cAChC,gBAAgB;AACtB,IAAA,CAAC;AACH;;MClBa,UAAU,CAAA;AACZ,IAAA,MAAM,GAAG,KAAK,CAAC,QAAQ,iDAAgB;uGADrC,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAV,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECfvB,iWAWM,EAAA,MAAA,EAAA,CAAA,gnp6CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDAM,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,iOAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAId,UAAU,EAAA,UAAA,EAAA,CAAA;kBANtB,SAAS;+BACE,kBAAkB,EAAA,OAAA,EACnB,CAAC,eAAe,CAAC,EAAA,QAAA,EAAA,iWAAA,EAAA,MAAA,EAAA,CAAA,gnp6CAAA,CAAA,EAAA;;;MEFf,aAAa,CAAA;AACL,IAAA,MAAM,GAAiB;AACxC,QAAA,KAAK,EAAE,cAAc;AACrB,QAAA,OAAO,EAAE,kDAAkD;AAC3D,QAAA,KAAK,EAAE;KACR;uGALU,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECT1B,4DAAwD,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDK5C,UAAU,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAIT,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;+BACE,iBAAiB,EAAA,OAAA,EAClB,CAAC,UAAU,CAAC,EAAA,QAAA,EAAA,4DAAA,EAAA;;;MEIV,aAAa,CAAA;AACL,IAAA,MAAM,GAAiB;AACxC,QAAA,KAAK,EAAE,iBAAiB;AACxB,QAAA,OAAO,EAAE,gDAAgD;AACzD,QAAA,KAAK,EAAE;KACR;uGALU,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECT1B,4DAAwD,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDK5C,UAAU,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAIT,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;+BACE,gBAAgB,EAAA,OAAA,EACjB,CAAC,UAAU,CAAC,EAAA,QAAA,EAAA,4DAAA,EAAA;;;MEIV,YAAY,CAAA;AACJ,IAAA,MAAM,GAAiB;AACtC,QAAA,KAAK,EAAE,sBAAsB;AAC7B,QAAA,OAAO,EAAE,kEAAkE;AAC3E,QAAA,KAAK,EAAE;KACR;uGALQ,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAZ,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECTzB,4DAAwD,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDK5C,UAAU,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAIT,YAAY,EAAA,UAAA,EAAA,CAAA;kBANxB,SAAS;+BACE,gBAAgB,EAAA,OAAA,EACjB,CAAC,UAAU,CAAC,EAAA,QAAA,EAAA,4DAAA,EAAA;;;MEIV,eAAe,CAAA;AACP,IAAA,MAAM,GAAiB;AACxC,QAAA,KAAK,EAAE,6BAA6B;AACpC,QAAA,OAAO,EAAE,kCAAkC;AAC3C,QAAA,KAAK,EAAE;KACR;uGALU,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAf,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECT5B,4DAAwD,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDK5C,UAAU,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAIT,eAAe,EAAA,UAAA,EAAA,CAAA;kBAN3B,SAAS;+BACE,mBAAmB,EAAA,OAAA,EACpB,CAAC,UAAU,CAAC,EAAA,QAAA,EAAA,4DAAA,EAAA;;;AEAjB,SAAU,EAAE,CAAC,KAAe,EAAA;IAChC,OAAO;AACL,QAAA,EAAE,EAAE,IAAI;QACR,KAAK;KACN;AACH;AAEM,SAAU,GAAG,CAAI,KAAQ,EAAA;IAC7B,OAAO;AACL,QAAA,EAAE,EAAE,KAAK;QACT,KAAK;KACN;AACH;;ACoFO,MAAM,WAAW,GAAkC;AACxD,IAAA,GAAG,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;AAC1B,IAAA,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;AAC7B,IAAA,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;AAC7B,IAAA,GAAG,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;AAC1B,IAAA,GAAG,EAAE,CAAC,eAAe,EAAE,MAAM,CAAC;AAC9B,IAAA,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;AAC7B,IAAA,GAAG,EAAE,CAAC,iBAAiB,EAAE,MAAM,CAAC;AAChC,IAAA,IAAI,EAAE;QACJ,oBAAoB;QACpB,MAAM;QACN,yEAAyE;QACzE,OAAO;AACR,KAAA;AACD,IAAA,QAAQ,EAAE,CAAC,eAAe,EAAE,KAAK,CAAC;AAClC,IAAA,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;AAC5B,IAAA,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;AACzB,IAAA,KAAK,EAAE;QACL,0BAA0B;QAC1B,MAAM;QACN,mEAAmE;QACnE,OAAO;AACR,KAAA;AACD,IAAA,UAAU,EAAE;QACV,+BAA+B;QAC/B,MAAM;QACN,2EAA2E;QAC3E,OAAO;AACR,KAAA;AACD,IAAA,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;AAC7B,IAAA,GAAG,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;AAC1B,IAAA,GAAG,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;AAC3B,IAAA,GAAG,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,8BAA8B,CAAC;AAChE,IAAA,GAAG,EAAE,CAAC,iBAAiB,EAAE,MAAM,CAAC;AAChC,IAAA,IAAI,EAAE,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACnC,KAAK,EAAE,CAAC,SAAS,CAAC;AAClB,IAAA,QAAQ,EAAE;QACR,oBAAoB;QACpB,MAAM;QACN,yEAAyE;QACzE,OAAO;QACP,iBAAiB;QACjB,MAAM;QACN,eAAe;QACf,KAAK;QACL,YAAY;QACZ,MAAM;AACP,KAAA;AACD,IAAA,WAAW,EAAE;QACX,0BAA0B;QAC1B,MAAM;QACN,mEAAmE;QACnE,OAAO;QACP,UAAU;QACV,MAAM;AACP,KAAA;AACD,IAAA,YAAY,EAAE;QACZ,MAAM;QACN,+BAA+B;QAC/B,OAAO;QACP,2EAA2E;AAC5E,KAAA;IACD,KAAK,EAAE,CAAC,SAAS,CAAC;IAClB,KAAK,EAAE,CAAC,SAAS,CAAC;AAClB,IAAA,OAAO,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,8BAA8B,CAAC;IACpE,IAAI,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC;CACtD;;AClKV;;;;;;;;;AASG;AACI,eAAe,gBAAgB,CACpC,GAAW,EAAA;AAEX,IAAA,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACjD,IAAA,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;AACZ,QAAA,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG;AAAE,YAAA,OAAO,GAAG,CAAC,WAAW,CAAC;;AAC3C,YAAA,OAAO,GAAG,CAAC,SAAS,CAAC;IAC5B;IAEA,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC;AACrC,IAAA,CAAC,CAAC,IAAI,GAAG,GAAG;AACZ,IAAA,CAAC,CAAC,GAAG,GAAG,UAAU;AAClB,IAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC,KAAK,EAAE;AACT,IAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE5B,OAAO,EAAE,EAAE;AACb;AAEA;;;;;AAKG;AACG,SAAU,YAAY,CAAC,MAAmB,EAAA;AAC9C,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;AAC5D,IAAA,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;AACjD,IAAA,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AAC9B;AAIA;;;;;;;AAOG;SACa,UAAU,CACxB,IAAU,EACV,GAAW,EACX,WAAuC,EAAA;AAEvC,IAAA,OAAO,IAAI,OAAO,CAA4B,OAAO,IAAG;AACtD,QAAA,MAAM,GAAG,GAAG,IAAI,cAAc,EAAE;QAEhC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC;QAC1B,GAAG,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC;QAE/C,IAAI,WAAW,EAAE;YACf,WAAW,CAAC,CAAC,CAAC;AACd,YAAA,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,IAAG;AAC3B,gBAAA,IAAI,EAAE,CAAC,gBAAgB,EAAE;AACvB,oBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,CAAC;oBACpD,WAAW,CAAC,GAAG,CAAC;gBAClB;AACF,YAAA,CAAC;QACH;AAEA,QAAA,GAAG,CAAC,MAAM,GAAG,MAAK;AAChB,YAAA,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;AACzC,gBAAA,OAAO,CAAC,EAAE,EAAE,CAAC;YACf;iBAAO;AACL,gBAAA,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC/B;AACF,QAAA,CAAC;AAED,QAAA,GAAG,CAAC,OAAO,GAAG,MAAK;AACjB,YAAA,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAC7C,QAAA,CAAC;AAED,QAAA,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;AAChB,IAAA,CAAC,CAAC;AACJ;;ACvFA,SAAS,YAAY,CAA2B,SAAyB,EAAE,KAAsC,EAAE,OAA6C,EAAA;AAC9J,IAAA,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,wDAAC;IAEpC,MAAM,KAAK,GAAG,YAAY,CAA6B,OAAO,EAAE,gBAAgB,KAAK,MAAM,OAAO,EAAE,YAAY,IAAI,OAAO,EAAE,YAAY,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,OAAA,EAAA,GAAA,EAAA,CAAA,EAAI,KAAK,EAAE,OAAO,EAAE,KAAK,EAAA,CAAG;AACtK,IAAA,MAAM,KAAK,GAAG,MAAM,CAAiC,SAAS,iDAAC;AAC/D,IAAA,MAAM,SAAS,GAAG,MAAM,CAAU,KAAK,qDAAC;AAExC,IAAA,IAAI,OAAO,EAAE,WAAW,EAAE;AACxB,QAAA,MAAM,CAAC,CAAC,SAAS,KAAI;;AAEnB,YAAA,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE;YACxC,SAAS,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;;;AAInC,YAAA,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC;AAClC,QAAA,CAAC,EAAE,EAAE,QAAQ,EAAG,OAAO,EAAE,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAC,CAAC;IACzD;IAEA,MAAM,OAAO,GAAG,OACd,WAAyB,EACzB,uBAAA,GAAmC,IAAI,KACpB;;;AAGnB,QAAA,IAAI,YAAY,EAAE,KAAK,SAAS,EAAE;YAChC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,IAAI,OAAO,EAAE,YAAY,CAAC;AACzD,YAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AACpB,YAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACpB,YAAA,OAAO,IAAI;QACb;;AAGA,QAAA,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACnB,QAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AAEpB,QAAA,IAAI;YACF,KAAK,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,YAAY,EAAE,EAAE;AACxC,gBAAA,MAAM,EAAE;AACT,aAAA,CAAC,CAAC;AACH,YAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;QACtB;QAAE,OAAO,GAAG,EAAE;AACZ,YAAA,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE;;;;;gBAK1B,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,KAAK,YAAY,IAAI,uBAAuB,EAAE;AAC/D,oBAAA,OAAO,KAAK;gBACd;AACA,gBAAA,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAChB;iBAAO;;gBAEL,OAAO,CAAC,KAAK,CAAC,qDAAqD,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YACnF;AACA,YAAA,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC;QAClC;AACA,QAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QACpB,OAAO,CAAC,KAAK,EAAE;AACjB,IAAA,CAAC;IAED,OAAO;QACL,KAAK;QACL,KAAK;QACL,SAAS;QACT;KACD;AACH;AAEA,SAAS,iBAAiB,CAA2B,aAAiC,EAAA;IACpF,OAAO;AACL,QAAA,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE;AAC5B,QAAA,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE;AAC5B,QAAA,SAAS,EAAE,aAAa,CAAC,SAAS,EAAE;KACrC;AACH;;AC3EA;;;;AAIG;AACH,SAAS,iBAAiB,CACxB,OAAiC,EACjC,MAAkB,EAClB,SAAwC,EACxC,OAAmD,EAAA;;AAGnD,IAAA,MAAM,cAAc,GAAG,QAAQ,CAAqB,OAAO,0DAAC;AAE5D,IAAA,MAAM,KAAK,GAAG,MAAM,CAAuB,OAAO,EAAE,YAAY,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,OAAA,EAAA,GAAA,EAAA,CAAA,EAAI,KAAK,EAAE,OAAO,EAAE,KAAK,GAAG;AAC5F,IAAA,MAAM,aAAa,GAAG,MAAM,CAA4B,SAAS,yDAAC;AAClE,IAAA,MAAM,SAAS,GAAG,MAAM,CAAU,KAAK,qDAAC;AACxC,IAAA,MAAM,UAAU,GAAG,MAAM,CAAqB,SAAS,sDAAC;AACxD,IAAA,MAAM,OAAO,GAAG,MAAM,CAAqC,SAAS,mDAAC;AAErE,IAAA,MAAM,MAAM,GAAG,MAAM,CAAoB,MAAM,kDAAC;AAChD,IAAA,MAAM,KAAK,GAAG,MAAM,CAAoB,SAAS,iDAAC;AAElD,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,IAAI,SAAS,GAA0B,SAAS;AAChD,IAAA,IAAI,OAAO,EAAE,WAAW,EAAE;AACxB,QAAA,SAAS,GAAG,MAAM,CAAC,CAAC,SAAS,KAAI;;AAE/B,YAAA,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE;YACxC,SAAS,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;;AAGnC,YAAA,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC;QAClC,CAAC,EAAE,EAAE,QAAQ,EAAG,OAAO,EAAE,QAAQ,IAAI,QAAQ,EAAC,CAAC;IACjD;IAEA,MAAM,OAAO,GAAG,OACd,WAAyB,EACzB,uBAAiC,KAC/B;;AAEF,QAAA,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,WAAW;YAAE;;AAGvC,QAAA,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACnB,QAAA,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;AAC5B,QAAA,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;AACzB,QAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;AACtB,QAAA,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;AACrB,QAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;;AAGpB,QAAA,MAAM,GAAG,GAAG,cAAc,EAAE;AAC5B,QAAA,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG;AACnB,QAAA,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM;AACzB,QAAA,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO;AAClC,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI;;QAGrB,IAAI,GAAG,GAAG,GAAG;QACb,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,YAAY,GAAG,IAAI,eAAe,EAAE;AAC1C,YAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACxB,gBAAA,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS;AAC3B,oBAAA,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACjD;YACA,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE;QAClE;;QAGA,MAAM,eAAe,GAAG;cACtB,MAAM,CAAC,WAAW,CAClB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,MAAM,CACnC,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,KAAK,SAAS,CACb;cAEvB,SAAS;AAEX,QAAA,IAAI;;AAEF,YAAA,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM;AACN,gBAAA,OAAO,EAAE,eAAe;;AAExB,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,MAAM,EAAE,WAAW;AACpB,aAAA,CAAC;;AAGF,YAAA,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;;YAG/B,MAAM,UAAU,GAA2B,EAAE;YAC7C,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,KAAI;AACpC,gBAAA,UAAU,CAAC,GAAG,CAAC,GAAG,GAAG;AACvB,YAAA,CAAC,CAAC;AACF,YAAA,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;;AAGvB,YAAA,IAAI,QAAQ,CAAC,EAAE,EAAE;gBACf,KAAK,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;AACpC,gBAAA,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;YACxB;iBAAO;;AAEL,gBAAA,IAAI;oBACF,aAAa,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AACxC,oBAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AACpB,oBAAA,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;gBACxB;AAAE,gBAAA,MAAM;AACN,oBAAA,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC;gBACpD;YACF;QACF;QAAE,OAAO,GAAQ,EAAE;AACjB,YAAA,IAAI,GAAG,YAAY,KAAK,EAAE;;;;;gBAKxB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,uBAAuB,EAAE;oBACxD;gBACF;AACA,gBAAA,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAChB;iBAAO;;AAEL,gBAAA,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACnC;AACA,YAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AACpB,YAAA,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;QACrB;AACA,QAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,IAAA,CAAC;IAED,MAAM,OAAO,GAAG,MAAK;;QAEnB,IAAI,MAAM,EAAE,KAAK,WAAW;YAAE;QAE9B,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,OAAO,EAAE;QACrB;AACA,QAAA,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;AACvB,QAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AACpB,QAAA,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;AAC5B,QAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACpB,QAAA,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;AACzB,QAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;AACtB,QAAA,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AACtB,IAAA,CAAC;IAED,OAAO;QACL,KAAK;QACL,aAAa;QACb,SAAS;QACT,UAAU;QACV,OAAO;QACP,MAAM;QACN,KAAK;QACL,OAAO;QACP;KACD;AACH;AAEA;AACA;AACA;AACA,MAAM,YAAY,GAAG,CAAkB,MAAkB,EAAE,SAAwC,KACjG,CAAC,OAAiC,EAAE,OAA2C,KAC7E,iBAAiB,CAAuB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC;AAEhF;AACA,MAAM,eAAe,GAA6B,CAAC,QAAkB,KAAK,QAAQ,CAAC,IAAI,EAAE;AACzF,MAAM,eAAe,GAAgC,CAAC,QAAkB,KAAK,QAAQ,CAAC,IAAI,EAAE;AAC5F,MAAM,eAAe,GAA8B,CAAC,QAAkB,KAAK,QAAQ,CAAC,IAAI,EAAE;AAC1F,MAAM,sBAAsB,GAAqC,CAAC,QAAkB,KAAK,QAAQ,CAAC,WAAW,EAAE;AAE/G;AACA;AACA;AACA,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe;AACvD,WAAW,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AACvD,WAAW,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AACvD,WAAW,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AACvD,WAAW,CAAC,WAAW,GAAG,YAAY,CAAC,KAAK,EAAE,sBAAsB,CAAC;AAErE;AACA;AACA;AACA,WAAW,CAAC,GAAG,GAAG,YAAY,CAC5B,KAAK,EACL,eAAe,CACa;AAC9B,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AAC3D,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AAC3D,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AAC3D,WAAW,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,KAAK,EAAE,sBAAsB,CAAC;AAEzE;AACA;AACA;AACA,WAAW,CAAC,IAAI,GAAG,YAAY,CAC7B,MAAM,EACN,eAAe,CACc;AAC/B,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE,eAAe,CAAC;AAC7D,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE,eAAe,CAAC;AAC7D,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE,eAAe,CAAC;AAC7D,WAAW,CAAC,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,MAAM,EAAE,sBAAsB,CAAC;AAE3E;AACA;AACA;AACA,WAAW,CAAC,GAAG,GAAG,YAAY,CAC5B,KAAK,EACL,eAAe,CACa;AAC9B,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AAC3D,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AAC3D,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC;AAC3D,WAAW,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,KAAK,EAAE,sBAAsB,CAAC;AAEzE;AACA;AACA;AACA,WAAW,CAAC,KAAK,GAAG,YAAY,CAC9B,OAAO,EACP,eAAe,CACe;AAChC,WAAW,CAAC,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC;AAC/D,WAAW,CAAC,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC;AAC/D,WAAW,CAAC,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC;AAC/D,WAAW,CAAC,KAAK,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,EAAE,sBAAsB,CAAC;AAE7E;AACA;AACA;AACA,WAAW,CAAC,MAAM,GAAG,YAAY,CAC/B,QAAQ,EACR,eAAe,CACgB;AACjC,WAAW,CAAC,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC;AACjE,WAAW,CAAC,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC;AACjE,WAAW,CAAC,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC;AACjE,WAAW,CAAC,MAAM,CAAC,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,sBAAsB,CAAC;;ACnPxE,MAAM,SAAS,GAAG,CAAI,WAAsB,EAAE,IAAA,GAAe,GAAG,KAAI;AACzE,IAAA,MAAM,eAAe,GAAG,MAAM,CAAI,WAAW,EAAE,2DAAC;AAChD,IAAA,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IAErE,MAAM,CAAC,MAAK;AACV,QAAA,SAAS,CAAC,WAAW,EAAE,CAAC;AAC1B,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,eAAe;AACxB;AAEA,MAAM,QAAQ,GAAG,CAAC,QAAkC,EAAE,IAAY,KAAI;AACpE,IAAA,IAAI,SAA6B;AACjC,IAAA,OAAO,CAAC,GAAG,IAAW,KAAI;AACxB,QAAA,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC;AAC9B,QAAA,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,MAAK;AACjC,YAAA,QAAQ,CAAC,GAAG,IAAI,CAAC;QACnB,CAAC,EAAE,IAAI,CAAC;AACV,IAAA,CAAC;AACH,CAAC;;ACrBD;;AAEG;;ACFH;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fhss-web-team/frontend-utils",
3
- "version": "21.3.1",
3
+ "version": "21.4.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.3",
6
6
  "@angular/core": "^21.0.3"
@@ -276,6 +276,48 @@ declare class ServerErrorPage {
276
276
  static ɵcmp: i0.ɵɵComponentDeclaration<ServerErrorPage, "fhss-server-error", never, {}, {}, never, never, true, never>;
277
277
  }
278
278
 
279
+ type Ok<T> = {
280
+ ok: true;
281
+ value: T;
282
+ };
283
+ type Err<E = unknown> = {
284
+ ok: false;
285
+ error: E;
286
+ };
287
+ type Result<T, E> = Ok<T> | Err<E>;
288
+
289
+ type FileLabel = 'image' | 'document' | 'spreadsheet' | 'presentation' | 'audio' | 'video' | 'archive' | 'data' | 'gif' | 'avif' | 'jpeg' | 'png' | 'svg' | 'webp' | 'pdf' | 'word' | 'markdown' | 'text' | 'csv' | 'excel' | 'powerpoint' | 'mp3' | 'mpeg' | 'mp4' | 'zip' | 'xml' | 'json';
290
+
291
+ type DownloadError = 'Not Found' | 'Unknown';
292
+ /**
293
+ * Downloads a file from the specified URL.
294
+ *
295
+ * This function performs a HEAD request to check if the file is available
296
+ * before initiating the download. If the file is available, it uses a
297
+ * temporary <a> to initiate a browser download.
298
+ *
299
+ * @param url - The URL of the file to download.
300
+ * @returns A promise that resolves to a Result.
301
+ */
302
+ declare function downloadFileFrom(url: string): Promise<Result<void, DownloadError>>;
303
+ /**
304
+ * Generates a comma-separated string of unique file types from the given file label groups.
305
+ * This allows the developer to easily define the `<input type="file" />`'s `accept` property.
306
+ * @param groups - An array of file labels to retrieve file types for.
307
+ * @returns A comma-separated string of unique file types.
308
+ */
309
+ declare function getFileTypes(groups: FileLabel[]): string;
310
+ type UploadError = 'Network error during upload' | 'Upload failed';
311
+ /**
312
+ * Uploads a file to the specified URL using XMLHttpRequest.
313
+ *
314
+ * @param file - The file to upload
315
+ * @param url - The URL endpoint where the file will be uploaded (PUT request)
316
+ * @param setProgress - Optional callback function to track upload progress as a percentage (0-100)
317
+ * @returns A promise that resolves to a Result object containing either void on success or an UploadError on failure
318
+ */
319
+ declare function uploadFile(file: File, url: string, setProgress?: (percent: number) => void): Promise<Result<void, UploadError>>;
320
+
279
321
  declare class ScrollRegistryService {
280
322
  private anchors;
281
323
  private pending;
@@ -803,5 +845,5 @@ declare const fetchSignal: FetchSignalFactory;
803
845
 
804
846
  declare const debounced: <T>(inputSignal: Signal<T>, wait?: number) => i0.WritableSignal<T>;
805
847
 
806
- export { AuthErrorPage, AuthService, ByuFooterComponent, ByuHeaderComponent, ComboBoxComponent, ConfirmationDialog, FHSS_CONFIG, ForbiddenPage, NotFoundPage, ScrollAnchorDirective, ScrollRegistryService, ServerErrorPage, authGuard, debounced, debugTrpcResource, fetchSignal, homeRedirectGuard, permissionGuard, provideFhss, trpcResource };
807
- export type { FhssConfig, HeaderConfig, Json, Option };
848
+ export { AuthErrorPage, AuthService, ByuFooterComponent, ByuHeaderComponent, ComboBoxComponent, ConfirmationDialog, FHSS_CONFIG, ForbiddenPage, NotFoundPage, ScrollAnchorDirective, ScrollRegistryService, ServerErrorPage, authGuard, debounced, debugTrpcResource, downloadFileFrom, fetchSignal, getFileTypes, homeRedirectGuard, permissionGuard, provideFhss, trpcResource, uploadFile };
849
+ export type { FhssConfig, HeaderConfig, Json, Option, UploadError };