UNPKG

@cisstech/nge

Version:

NG Essentials is a collection of libraries for Angular developers.

654 lines 50.5 kB
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, inject, Injector, ChangeDetectorRef, ViewContainerRef, Component, ChangeDetectionStrategy, ViewChild, ElementRef, Directive, Input, EventEmitter, Output, NgModule } from '@angular/core';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i1 from '@angular/router';
import { NavigationEnd, Scroll, RouterModule } from '@angular/router';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { filter } from 'rxjs/operators';
import * as i1$1 from '@angular/cdk/layout';
import { Breakpoints } from '@angular/cdk/layout';
import { HttpClient } from '@angular/common/http';
import { CompilerService } from '@cisstech/nge/services';

/** Custom renderers components */
const NGE_DOC_RENDERERS = new InjectionToken('NGE_DOC_RENDERERS');
const isNgeDocSettings = (v) => !!v && typeof v === 'object' && !Array.isArray(v) && !!v.meta && !!v.pages;
const extractNgeDocSettings = (v) => {
    let settings = [];
    if (isNgeDocSettings(v)) {
        settings.push(v);
    }
    else if (typeof v === 'object') {
        settings.push(...Object.values(v)
            .map((v) => extractNgeDocSettings(v))
            .flat());
    }
    return settings;
};

class NgeDocService {
    /** documentation state */
    get stateChanges() {
        return this.state.pipe(filter((state) => !!state.currLink));
    }
    constructor(router, injector, location, activatedRoute) {
        this.router = router;
        this.injector = injector;
        this.location = location;
        this.activatedRoute = activatedRoute;
        this.state = new BehaviorSubject({
            meta: {
                root: '',
                name: '',
            },
            links: [],
            prevLink: undefined,
            nextLink: undefined,
            currLink: undefined,
        });
        this.pages = new Map();
        this.links = [];
        this.subscriptions = [];
    }
    ngOnDestroy() {
        this.reset();
    }
    /**
     * Loads navigation from the router configuration.
     */
    async setup() {
        this.reset();
        const { data } = this.activatedRoute.snapshot;
        const settings = extractNgeDocSettings(data);
        for (const setting of settings) {
            const links = [];
            let meta;
            if (typeof setting.meta === 'function') {
                meta = await setting.meta(this.injector);
            }
            else {
                meta = setting.meta;
            }
            if (!meta) {
                throw new Error('[nge-doc]: Missing setting.meta');
            }
            for (const item of setting.pages) {
                const pages = [];
                let object;
                if (typeof item === 'function') {
                    object = await item(this.injector);
                }
                else {
                    object = item;
                }
                if (Array.isArray(object)) {
                    pages.push(...object);
                }
                else {
                    pages.push(object);
                }
                pages.forEach((page) => {
                    links.push(page);
                    this.resolvePageLinks(meta, page);
                });
                this.pages.set(meta.root, {
                    meta,
                    links: links,
                });
            }
        }
        this.subscriptions.push(this.router.events.pipe(filter((e) => e instanceof NavigationEnd)).subscribe(this.onChangeRoute.bind(this)));
        this.onChangeRoute();
    }
    /**
     * Checks whether the given `link` is active.
     * @param link The link to test.
     */
    isActive(link) {
        const tree = this.location.path().split('/');
        for (let i = 0; i < tree.length; i++) {
            const path = tree.slice(0, tree.length - i).join('/');
            if (path && path.endsWith(link.href)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Checks whether the given `link` includes sub links.
     * @param link The link to test.
     */
    isExpandable(link) {
        return !!link.children?.length;
    }
    join(a, b) {
        if (a.endsWith('/')) {
            a = a.slice(0, a.length - 1);
        }
        if (b.startsWith('/')) {
            b = b.slice(1);
        }
        return a + '/' + b;
    }
    resolvePageLinks(meta, page) {
        const createLink = (link, parent) => {
            link.href = this.join(parent, link.href);
            this.links.push(link);
            link.children?.forEach((child) => {
                createLink(child, link.href);
            });
        };
        createLink(page, meta.root);
    }
    async onChangeRoute() {
        if (!this.pages.size) {
            return;
        }
        const path = this.location.path();
        const paths = [path, path + '/'];
        let meta;
        let links = [];
        for (const [k, v] of this.pages) {
            if (paths.some((path) => path.includes(k))) {
                meta = v.meta;
                links = v.links;
                break;
            }
        }
        if (!meta) {
            throw new Error('[nge-doc]: Unregisted page ' + path);
        }
        let { currLink, prevLink, nextLink } = this.state.value;
        // ignore same page navigation (fragment navigation)
        if (currLink && paths.some((p) => p.endsWith(currLink.href))) {
            return;
        }
        // calculate current, previous and next links
        // https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
        const modulo = (a, n) => {
            return ((a % n) + n) % n;
        };
        for (let i = 0; i < this.links.length; i++) {
            const link = this.links[i];
            if (paths.some((path) => path.endsWith(link.href))) {
                const prevIndex = modulo(i - 1, this.links.length);
                const nextIndex = modulo(i + 1, this.links.length);
                currLink = link;
                nextLink = this.links[nextIndex];
                prevLink = this.links[prevIndex];
                break;
            }
        }
        // navigate to first page if currLink is not defined
        if (!currLink) {
            this.router.navigateByUrl(links[0].href, {
                replaceUrl: true,
            });
            return;
        }
        // navigate to first children if currLink doesn't have a renderer
        if (!currLink.renderer && currLink.children?.length) {
            this.router.navigateByUrl(currLink.children[0].href, {
                replaceUrl: true,
            });
            return;
        }
        // expand visible links
        this.links.forEach((link) => {
            if (paths.some((path) => path.endsWith(link.href))) {
                link.expanded = true;
            }
        });
        // notify state change
        this.state.next({
            meta,
            links,
            prevLink,
            currLink,
            nextLink,
        });
    }
    reset() {
        this.subscriptions.forEach((s) => s.unsubscribe());
        this.subscriptions.splice(0, this.subscriptions.length);
        this.pages.clear();
        this.links.splice(0, this.links.length);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocService, deps: [{ token: i1.Router }, { token: i0.Injector }, { token: i2.Location }, { token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocService, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.Router }, { type: i0.Injector }, { type: i2.Location }, { type: i1.ActivatedRoute }] });

class NgeDocRendererComponent {
    constructor() {
        this.injector = inject(Injector);
        this.renderers = inject(NGE_DOC_RENDERERS);
        this.docService = inject(NgeDocService);
        this.compilerService = inject(CompilerService);
        this.changeDetectorRef = inject(ChangeDetectorRef);
        this.subscriptions = [];
        this.loading = false;
        this.noFound = false;
        this.componentRefByTypes = new Map();
    }
    ngOnInit() {
        this.subscriptions.push(this.docService.stateChanges.subscribe(this.onChangeState.bind(this)));
    }
    ngOnDestroy() {
        this.clearViewContainer();
        this.subscriptions.forEach((s) => s.unsubscribe());
    }
    showLoading() {
        this.loading = true;
        // if loading is still true after 1s then we force change detection
        // This is useful to show the loading indicator only if the loading is not too fast
        // so that the loading indicator does not blink.
        setTimeout(() => {
            if (this.loading) {
                this.changeDetectorRef.markForCheck();
            }
        }, 1000);
    }
    clearViewContainer() {
        const componentRefs = Array.from(this.componentRefByTypes.values());
        if (this.componentRef && componentRefs.includes(this.componentRef)) {
            while (this.container.length > 0) {
                this.container.detach();
            }
        }
        else {
            this.componentRef?.destroy();
            this.componentRef = undefined;
            this.container.clear();
        }
    }
    async onChangeState(state) {
        try {
            this.showLoading();
            this.clearViewContainer();
            if (state.currLink) {
                const renderer = await state.currLink.renderer;
                switch (typeof renderer) {
                    case 'string':
                        await this.renderMarkdown(renderer);
                        break;
                    case 'function':
                        this.componentRef = await this.compilerService.render({
                            type: await renderer(),
                            inputs: state.currLink.inputs,
                            container: this.container,
                        });
                        break;
                }
            }
        }
        catch (error) {
            console.error(error);
        }
        finally {
            this.loading = false;
            this.noFound = !this.componentRef;
            this.changeDetectorRef.markForCheck();
        }
    }
    async renderMarkdown(data) {
        if (!this.renderers?.markdown) {
            throw new Error('[nge-doc]: missing markdown renderer.');
        }
        const renderer = this.renderers.markdown;
        const type = await renderer.component();
        const createInputs = async () => {
            let inputs = {
                data, // we assume that data is a markdown content.
            };
            if (!data.includes('\n')) {
                // if data does not include at least two lines then it's an url
                const http = this.injector.get(HttpClient, null);
                if (!http) {
                    throw new Error('[nge-doc] When using the `file` renderer you *have to* pass the `HttpClient` as a parameter of the `forRoot` method. See README for more information');
                }
                inputs = {
                    data: await firstValueFrom(http.get(data, { responseType: 'text' })),
                };
            }
            let customInputs = {};
            if (typeof renderer.inputs === 'function') {
                customInputs = await renderer.inputs(this.injector);
            }
            else if (typeof renderer.inputs === 'object') {
                customInputs = renderer.inputs;
            }
            return { ...customInputs, ...inputs };
        };
        const markdownComponent = this.componentRefByTypes.get(type);
        if (markdownComponent) {
            this.attachComponent(markdownComponent, await createInputs());
            return;
        }
        const componentRef = await this.compilerService.render({
            type,
            inputs: await createInputs(),
            container: this.container,
        });
        this.componentRef = componentRef;
        this.componentRefByTypes.set(type, componentRef);
    }
    async attachComponent(componentRef, inputs) {
        this.container.insert(componentRef.hostView);
        this.componentRef = componentRef;
        // compute changes
        const changes = {};
        const { instance, changeDetectorRef } = componentRef;
        Object.keys(inputs).forEach((key) => {
            changes[key] = {
                currentValue: inputs[key],
                previousValue: instance[key],
                firstChange: false,
                isFirstChange: () => false,
            };
            instance[key] = inputs[key];
        });
        // call ngOnChanges
        if (instance.ngOnChanges) {
            await instance.ngOnChanges(changes);
        }
        changeDetectorRef.markForCheck();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: NgeDocRendererComponent, selector: "nge-doc-renderer", viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div class=\"loading-container\" *ngIf=\"loading\">\n  <div class=\"loading-spinner\"></div>\n  <div class=\"loading-text\">Loading...</div>\n</div>\n<div *ngIf=\"noFound\">\n  <h1>Ooops!</h1>\n  <hr />\n  <p>It looks like this page doesn't exist.</p>\n</div>\n<div #container></div>\n", styles: [":host{display:block;width:100%;position:relative}.loading-container{display:flex;align-items:center;flex-direction:column;justify-content:center}.loading-spinner{border:4px solid rgba(0,0,0,.1);border-top:4px solid var(--nge-doc-primary-color);border-radius:50%;width:40px;height:40px;animation:spin 1s linear infinite;margin-bottom:20px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-text{font-family:Arial,sans-serif;font-size:18px;color:#333}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererComponent, decorators: [{
            type: Component,
            args: [{ selector: 'nge-doc-renderer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"loading-container\" *ngIf=\"loading\">\n  <div class=\"loading-spinner\"></div>\n  <div class=\"loading-text\">Loading...</div>\n</div>\n<div *ngIf=\"noFound\">\n  <h1>Ooops!</h1>\n  <hr />\n  <p>It looks like this page doesn't exist.</p>\n</div>\n<div #container></div>\n", styles: [":host{display:block;width:100%;position:relative}.loading-container{display:flex;align-items:center;flex-direction:column;justify-content:center}.loading-spinner{border:4px solid rgba(0,0,0,.1);border-top:4px solid var(--nge-doc-primary-color);border-radius:50%;width:40px;height:40px;animation:spin 1s linear infinite;margin-bottom:20px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-text{font-family:Arial,sans-serif;font-size:18px;color:#333}\n"] }]
        }], propDecorators: { container: [{
                type: ViewChild,
                args: ['container', { read: ViewContainerRef, static: true }]
            }] } });

class NgeDocTocDirective {
    constructor(router, location, elementRef, activatedRoute) {
        this.router = router;
        this.location = location;
        this.elementRef = elementRef;
        this.activatedRoute = activatedRoute;
        this.subscriptions = [];
        this.observer = new MutationObserver(() => {
            this.observer?.disconnect();
            this.build();
        });
        this.anchors = [];
        this.subscriptions.push(this.router.events.subscribe((event) => {
            if (event instanceof Scroll && event.anchor) {
                this.scroll(event.anchor);
            }
        }));
    }
    ngOnDestroy() {
        this.intersection?.disconnect();
        this.subscriptions.forEach((s) => s.unsubscribe());
    }
    ngOnChanges() {
        this.build();
    }
    build() {
        this.clear();
        if (!this.component) {
            return;
        }
        const componentNode = this.component.injector.get(ElementRef).nativeElement;
        const tocContainer = this.elementRef.nativeElement;
        const h2Nodes = Array.from(componentNode.children).filter((node) => {
            return node.tagName === 'H2' && node.parentNode?.isSameNode(componentNode);
        });
        this.detectIntersection();
        const ul = document.createElement('ul');
        h2Nodes.forEach((h2) => {
            const id = this.dashify(h2.textContent || '');
            const target = document.createElement('span');
            target.id = id;
            h2.insertAdjacentElement('afterend', target);
            const li = document.createElement('li');
            const anchor = document.createElement('a');
            anchor.innerHTML = h2.innerHTML;
            // .substring(1) will remove the leading / (prevent errors when baseHref is defined in index.html)
            anchor.href = this.location.path().substring(1) + '#' + id;
            li.appendChild(anchor);
            ul.appendChild(li);
            h2.setAttribute('data-toc-id', id);
            li.setAttribute('data-toc-id', id);
            this.anchors.push(li);
            this.intersection?.observe(h2);
        });
        tocContainer.appendChild(ul);
        const { fragment } = this.activatedRoute.snapshot;
        if (fragment) {
            this.scroll(fragment);
        }
        this.observer.observe(componentNode, {
            childList: true,
            subtree: true,
        });
    }
    dashify(input) {
        return input
            .trim()
            .replace(/([a-z])([A-Z])/g, '$1-$2')
            .replace(/\W/g, (m) => (/[À-ž]/.test(m) ? m : '-'))
            .replace(/^-+|-+$/g, '')
            .replace(/-{2,}/g, (m) => '-') // Condense multiple consecutive dashes to one.
            .toLowerCase();
    }
    detectIntersection() {
        const tocContainer = this.elementRef.nativeElement;
        const rect = tocContainer.getBoundingClientRect();
        const bottom = -window.innerHeight + rect.y + 200;
        this.intersection?.disconnect();
        this.intersection = new IntersectionObserver((entries) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting) {
                    this.anchors.forEach((anchor) => {
                        anchor.classList.remove('active');
                        const a = anchor.getAttribute('data-toc-id');
                        const b = entry.target.getAttribute('data-toc-id');
                        if (a === b) {
                            anchor.classList.add('active');
                        }
                    });
                }
            });
        }, {
            // A BOX OF 200px STARTING AT THE POSITION OF THE TOC ELEMENT
            rootMargin: `0px 0px ${bottom}px 0px`,
        });
    }
    clear() {
        const tocContainer = this.elementRef.nativeElement;
        tocContainer.innerHTML = '';
        this.observer.disconnect();
        this.intersection?.disconnect();
        this.anchors = [];
    }
    scroll(query) {
        const targetElement = document.querySelector(`h2[data-toc-id="${query}"]`);
        if (!targetElement) {
            window.scrollTo(0, 0);
        }
        else if (!this.isInViewport(targetElement)) {
            targetElement.scrollIntoView();
        }
    }
    isInViewport(elem) {
        const bounding = elem.getBoundingClientRect();
        return (bounding.top >= 0 &&
            bounding.left >= 0 &&
            bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            bounding.right <= (window.innerWidth || document.documentElement.clientWidth));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocTocDirective, deps: [{ token: i1.Router }, { token: i2.Location }, { token: i0.ElementRef }, { token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.1", type: NgeDocTocDirective, selector: "[ngeDocToc]", inputs: { component: ["ngeDocToc", "component"] }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocTocDirective, decorators: [{
            type: Directive,
            args: [{ selector: '[ngeDocToc]' }]
        }], ctorParameters: () => [{ type: i1.Router }, { type: i2.Location }, { type: i0.ElementRef }, { type: i1.ActivatedRoute }], propDecorators: { component: [{
                type: Input,
                args: ['ngeDocToc']
            }] } });

class FooterComponent {
    constructor(docService) {
        this.docService = docService;
        this.state$ = this.docService.stateChanges;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: FooterComponent, deps: [{ token: NgeDocService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: FooterComponent, selector: "nge-doc-footer", ngImport: i0, template: "<footer *ngIf=\"state$|async as state\">\n  <div>\n    <ng-container *ngIf=\"state.prevLink\">\n      <a class=\"icon-button\" [routerLink]=\"state.prevLink.href\">\n        <img src=\"https://icongr.am/octicons/chevron-left.svg?size=36&color=FFFFFF\" alt=\"Previous page\">\n        {{ state.prevLink.title }}\n      </a>\n    </ng-container>\n    <div class=\"spacer\"></div>\n    <ng-container *ngIf=\"state.nextLink\">\n      <a class=\"icon-button\" [routerLink]=\"state.nextLink.href\">\n        {{ state.nextLink.title }}\n        <img src=\"https://icongr.am/octicons/chevron-right.svg?size=36&color=FFFFFF\" alt=\"Next page\">\n      </a>\n    </ng-container>\n  </div>\n  <div>\n    <div class=\"powered-by\">\n      Powered by\n      <a href=\"https://cisstech.github.io/nge/docs/nge-doc/\" target=\"_blank\">Ngedoc</a>\n    </div>\n    <div class=\"spacer\"></div>\n    <ng-container *ngIf=\"state.meta.links\">\n      <ng-container *ngFor=\"let item of state.meta.links\">\n        <a class=\"icon-button\" [href]=\"item.href\" target=\"_blank\">\n          <img [src]=\"item.icon\">\n        </a>\n      </ng-container>\n    </ng-container>\n    <ng-container *ngIf=\"state.meta.repo\">\n      <a class=\"icon-button\" [href]=\"state.meta.repo.url\" target=\"_blank\" title=\"GitHub's repository\">\n        <img src=\"https://icongr.am/octicons/mark-github.svg?size=24&color=FFFFFF\" >\n      </a>\n    </ng-container>\n  </div>\n</footer>\n", styles: [":host{display:block;background-color:#000;color:#fff;box-sizing:border-box;overflow:hidden}footer{display:block;width:100%;padding:1rem 0;box-sizing:border-box}footer>div{display:flex;align-items:center;padding:.2rem .4rem}footer>:first-child{padding:.2rem 0rem;font-size:1.4em}.spacer{flex:1}.icon-button{background-color:transparent;color:currentColor;text-decoration:none;display:flex;align-items:center;width:auto;padding:.2rem}.icon-button img{width:24px;height:24px;object-fit:cover}.powered-by{color:#ffffffb3}.powered-by a{color:#fff;text-decoration:none}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: FooterComponent, decorators: [{
            type: Component,
            args: [{ selector: 'nge-doc-footer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<footer *ngIf=\"state$|async as state\">\n  <div>\n    <ng-container *ngIf=\"state.prevLink\">\n      <a class=\"icon-button\" [routerLink]=\"state.prevLink.href\">\n        <img src=\"https://icongr.am/octicons/chevron-left.svg?size=36&color=FFFFFF\" alt=\"Previous page\">\n        {{ state.prevLink.title }}\n      </a>\n    </ng-container>\n    <div class=\"spacer\"></div>\n    <ng-container *ngIf=\"state.nextLink\">\n      <a class=\"icon-button\" [routerLink]=\"state.nextLink.href\">\n        {{ state.nextLink.title }}\n        <img src=\"https://icongr.am/octicons/chevron-right.svg?size=36&color=FFFFFF\" alt=\"Next page\">\n      </a>\n    </ng-container>\n  </div>\n  <div>\n    <div class=\"powered-by\">\n      Powered by\n      <a href=\"https://cisstech.github.io/nge/docs/nge-doc/\" target=\"_blank\">Ngedoc</a>\n    </div>\n    <div class=\"spacer\"></div>\n    <ng-container *ngIf=\"state.meta.links\">\n      <ng-container *ngFor=\"let item of state.meta.links\">\n        <a class=\"icon-button\" [href]=\"item.href\" target=\"_blank\">\n          <img [src]=\"item.icon\">\n        </a>\n      </ng-container>\n    </ng-container>\n    <ng-container *ngIf=\"state.meta.repo\">\n      <a class=\"icon-button\" [href]=\"state.meta.repo.url\" target=\"_blank\" title=\"GitHub's repository\">\n        <img src=\"https://icongr.am/octicons/mark-github.svg?size=24&color=FFFFFF\" >\n      </a>\n    </ng-container>\n  </div>\n</footer>\n", styles: [":host{display:block;background-color:#000;color:#fff;box-sizing:border-box;overflow:hidden}footer{display:block;width:100%;padding:1rem 0;box-sizing:border-box}footer>div{display:flex;align-items:center;padding:.2rem .4rem}footer>:first-child{padding:.2rem 0rem;font-size:1.4em}.spacer{flex:1}.icon-button{background-color:transparent;color:currentColor;text-decoration:none;display:flex;align-items:center;width:auto;padding:.2rem}.icon-button img{width:24px;height:24px;object-fit:cover}.powered-by{color:#ffffffb3}.powered-by a{color:#fff;text-decoration:none}\n"] }]
        }], ctorParameters: () => [{ type: NgeDocService }] });

class HeaderComponent {
    constructor(injector, docService) {
        this.injector = injector;
        this.docService = docService;
        this.toggle = new EventEmitter();
        this.state$ = this.docService.stateChanges;
    }
    async invoke(handler) {
        if (typeof handler === 'string') {
            window.open(handler, '_blank');
        }
        else {
            await handler(this.injector);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: HeaderComponent, deps: [{ token: i0.Injector }, { token: NgeDocService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: HeaderComponent, selector: "nge-doc-header", outputs: { toggle: "toggle" }, ngImport: i0, template: "<header *ngIf=\"state$|async as state\">\n  <div class=\"action\" aria-label=\"Menu\" (click)=\"toggle.emit()\">\n    <img src=\"https://icongr.am/octicons/three-bars.svg?size=24&color=currentColor\">\n  </div>\n  <ng-container *ngIf=\"state.meta.backUrl\">\n    <a class=\"action\" aria-label=\"Back\" [routerLink]=\"state.meta.backUrl\">\n      <img [src]=\"state.meta.backIconUrl ?? 'https://icongr.am/octicons/home.svg?size=24&color=currentColor'\">\n    </a>\n  </ng-container>\n  <ng-container *ngIf=\"state.meta.backUrlHref\">\n    <a class=\"action\" aria-label=\"Back\" [href]=\"state.meta.backUrlHref\">\n      <img [src]=\"state.meta.backIconUrl ?? 'https://icongr.am/octicons/home.svg?size=24&color=currentColor'\">\n    </a>\n  </ng-container>\n  <div class=\"spacer\"></div>\n  <ng-container *ngIf=\"state.currLink?.actions\">\n    <ng-container *ngFor=\"let action of state.currLink?.actions || []\">\n      <div class=\"action\" [attr.aria-label]=\"action.title\" [title]=\"action.tooltip\" (click)=\"invoke(action.run)\">\n        <ng-container *ngIf=\"action.title\">\n          <span>{{action.title}}</span>\n        </ng-container>\n        <ng-container *ngIf=\"action.icon\">\n          <img [src]=\"action.icon\">\n        </ng-container>\n      </div>\n    </ng-container>\n  </ng-container>\n</header>\n", styles: [":host{display:flex;align-items:center;margin:0;padding:2rem 0;width:100%;height:var(--header-height)}header{display:flex;align-items:center;width:100%;cursor:pointer}header .action{display:flex;align-items:center;font-size:1em;text-rendering:optimizeLegibility;color:#000;text-decoration:none;margin-right:8px}header .action span{padding:0 8px}header .action:hover{font-weight:700}header img{width:24px;height:24px;object-fit:cover}.spacer{flex:1}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: HeaderComponent, decorators: [{
            type: Component,
            args: [{ selector: 'nge-doc-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header *ngIf=\"state$|async as state\">\n  <div class=\"action\" aria-label=\"Menu\" (click)=\"toggle.emit()\">\n    <img src=\"https://icongr.am/octicons/three-bars.svg?size=24&color=currentColor\">\n  </div>\n  <ng-container *ngIf=\"state.meta.backUrl\">\n    <a class=\"action\" aria-label=\"Back\" [routerLink]=\"state.meta.backUrl\">\n      <img [src]=\"state.meta.backIconUrl ?? 'https://icongr.am/octicons/home.svg?size=24&color=currentColor'\">\n    </a>\n  </ng-container>\n  <ng-container *ngIf=\"state.meta.backUrlHref\">\n    <a class=\"action\" aria-label=\"Back\" [href]=\"state.meta.backUrlHref\">\n      <img [src]=\"state.meta.backIconUrl ?? 'https://icongr.am/octicons/home.svg?size=24&color=currentColor'\">\n    </a>\n  </ng-container>\n  <div class=\"spacer\"></div>\n  <ng-container *ngIf=\"state.currLink?.actions\">\n    <ng-container *ngFor=\"let action of state.currLink?.actions || []\">\n      <div class=\"action\" [attr.aria-label]=\"action.title\" [title]=\"action.tooltip\" (click)=\"invoke(action.run)\">\n        <ng-container *ngIf=\"action.title\">\n          <span>{{action.title}}</span>\n        </ng-container>\n        <ng-container *ngIf=\"action.icon\">\n          <img [src]=\"action.icon\">\n        </ng-container>\n      </div>\n    </ng-container>\n  </ng-container>\n</header>\n", styles: [":host{display:flex;align-items:center;margin:0;padding:2rem 0;width:100%;height:var(--header-height)}header{display:flex;align-items:center;width:100%;cursor:pointer}header .action{display:flex;align-items:center;font-size:1em;text-rendering:optimizeLegibility;color:#000;text-decoration:none;margin-right:8px}header .action span{padding:0 8px}header .action:hover{font-weight:700}header img{width:24px;height:24px;object-fit:cover}.spacer{flex:1}\n"] }]
        }], ctorParameters: () => [{ type: i0.Injector }, { type: NgeDocService }], propDecorators: { toggle: [{
                type: Output
            }] } });

class SidenavComponent {
    constructor(docService) {
        this.docService = docService;
        this.state$ = this.docService.stateChanges;
    }
    trackBy(_, item) {
        return item.href;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: SidenavComponent, deps: [{ token: NgeDocService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: SidenavComponent, selector: "nge-doc-sidenav", ngImport: i0, template: "<ng-container *ngIf=\"state$|async as state\">\n  <header>\n    <ng-container *ngIf=\"state.meta.logo; else: nologo\">\n      <img [src]=\"state.meta.logo\" alt=\"Documentation Logo\">\n    </ng-container>\n    <ng-template #nologo>\n      <img src=\"https://icongr.am/octicons/book.svg?size=48&color=34495e\">\n    </ng-template>\n    <h1>{{ state.meta.name }}</h1>\n  </header>\n  <nav *ngIf=\"state.links.length\">\n    <ng-container *ngTemplateOutlet=\"template; context: { $implicit: state.links }\"></ng-container>\n  </nav>\n</ng-container>\n<ng-template #template let-links>\n  <ul>\n    <ng-container *ngFor=\"let link of links; trackBy: trackBy\">\n      <li [class.caption]=\"docService.isExpandable(link)\">\n        <a [routerLink]=\"link.href\" [class.active]=\"docService.isActive(link)\">\n          <img *ngIf=\"link.icon\" [src]=\"link.icon\">\n          {{ link.title }}\n        </a>\n      </li>\n      <ng-container *ngIf=\"docService.isExpandable(link)\">\n        <ng-container\n          *ngTemplateOutlet=\"template; context: { $implicit: link.children }\">\n        </ng-container>\n      </ng-container>\n    </ng-container>\n  </ul>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;overflow:auto;line-height:2.3em;padding:1rem}header{display:block}header h1{font-size:1.5rem;font-weight:300;margin:0 auto 1rem}header img{height:48px;width:48px;box-sizing:border-box;object-fit:contain}nav{margin:0;padding:0;box-sizing:border-box;flex:1}ul,li,a{margin:0;padding:0;list-style:none;text-decoration:none}a{display:inline-flex;align-items:center;font-size:1em;text-rendering:optimizeLegibility;position:relative;color:currentColor;text-decoration:none}a:hover,a.active{font-weight:700}a:before{content:\"\";position:absolute;width:100%;height:1px;bottom:-2px;left:0;background-color:var(--nge-doc-primary-color);visibility:hidden;transform:scaleX(0);transition:all .3s ease-in-out 0s}a:hover:before,a.active:before{visibility:visible;transform:scaleX(1)}a img{width:24px;height:24px;margin-right:4px;object-fit:cover}li{margin-bottom:4px}.caption{margin-top:.2rem;font-weight:700;display:flex;align-items:center}.caption+ul{padding-left:1.3em}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: SidenavComponent, decorators: [{
            type: Component,
            args: [{ selector: 'nge-doc-sidenav', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"state$|async as state\">\n  <header>\n    <ng-container *ngIf=\"state.meta.logo; else: nologo\">\n      <img [src]=\"state.meta.logo\" alt=\"Documentation Logo\">\n    </ng-container>\n    <ng-template #nologo>\n      <img src=\"https://icongr.am/octicons/book.svg?size=48&color=34495e\">\n    </ng-template>\n    <h1>{{ state.meta.name }}</h1>\n  </header>\n  <nav *ngIf=\"state.links.length\">\n    <ng-container *ngTemplateOutlet=\"template; context: { $implicit: state.links }\"></ng-container>\n  </nav>\n</ng-container>\n<ng-template #template let-links>\n  <ul>\n    <ng-container *ngFor=\"let link of links; trackBy: trackBy\">\n      <li [class.caption]=\"docService.isExpandable(link)\">\n        <a [routerLink]=\"link.href\" [class.active]=\"docService.isActive(link)\">\n          <img *ngIf=\"link.icon\" [src]=\"link.icon\">\n          {{ link.title }}\n        </a>\n      </li>\n      <ng-container *ngIf=\"docService.isExpandable(link)\">\n        <ng-container\n          *ngTemplateOutlet=\"template; context: { $implicit: link.children }\">\n        </ng-container>\n      </ng-container>\n    </ng-container>\n  </ul>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;overflow:auto;line-height:2.3em;padding:1rem}header{display:block}header h1{font-size:1.5rem;font-weight:300;margin:0 auto 1rem}header img{height:48px;width:48px;box-sizing:border-box;object-fit:contain}nav{margin:0;padding:0;box-sizing:border-box;flex:1}ul,li,a{margin:0;padding:0;list-style:none;text-decoration:none}a{display:inline-flex;align-items:center;font-size:1em;text-rendering:optimizeLegibility;position:relative;color:currentColor;text-decoration:none}a:hover,a.active{font-weight:700}a:before{content:\"\";position:absolute;width:100%;height:1px;bottom:-2px;left:0;background-color:var(--nge-doc-primary-color);visibility:hidden;transform:scaleX(0);transition:all .3s ease-in-out 0s}a:hover:before,a.active:before{visibility:visible;transform:scaleX(1)}a img{width:24px;height:24px;margin-right:4px;object-fit:cover}li{margin-bottom:4px}.caption{margin-top:.2rem;font-weight:700;display:flex;align-items:center}.caption+ul{padding-left:1.3em}\n"] }]
        }], ctorParameters: () => [{ type: NgeDocService }] });

class DefaultLayoutComponent {
    constructor(observer, changeDetectorRef) {
        this.observer = observer;
        this.changeDetectorRef = changeDetectorRef;
        this.sidebarOpened = true;
        this.showTableOfContents = true;
    }
    ngOnInit() {
        this.observer.observe([Breakpoints.XSmall, Breakpoints.Small]).subscribe((result) => {
            this.sidebarOpened = true;
            this.showTableOfContents = true;
            if (result.matches) {
                this.sidebarOpened = false;
                this.showTableOfContents = false;
            }
            this.changeDetectorRef.markForCheck();
        });
    }
    ngOnDestroy() {
        this.subscription?.unsubscribe();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: DefaultLayoutComponent, deps: [{ token: i1$1.BreakpointObserver }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: DefaultLayoutComponent, selector: "nge-doc-default-layout", ngImport: i0, template: "<main>\n  <aside class=\"sidebar\" [class.opened]=\"sidebarOpened\">\n    <nge-doc-sidenav />\n  </aside>\n  <section>\n    <nge-doc-header (toggle)=\"sidebarOpened = !sidebarOpened\" />\n    <article>\n      <nge-doc-renderer #renderer />\n      <aside\n        *ngIf=\"showTableOfContents\"\n        [ngeDocToc]=\"renderer.componentRef\">\n      </aside>\n    </article>\n  </section>\n</main>\n<nge-doc-footer />\n", styles: [":host{--sidebar-width: 20rem;--footer-height: 100px;--header-height: 64px;--nge-doc-primary-color: #f50057;--nge-doc-sidebar-border-color: rgba(0, 0, 0, .07);display:block;width:100vw;height:100vh;overflow:hidden}main{display:flex;height:calc(100vh - var(--footer-height));overflow:hidden}aside.sidebar{display:block;width:0px;border-right:1px solid var(--nge-doc-sidebar-border-color);background-color:#fafbfc;opacity:0;pointer-events:none;transition:all .5s}aside.sidebar.opened{opacity:1;pointer-events:initial;width:var(--sidebar-width)}aside.sidebar,nge-doc-sidenav{height:calc(100vh - var(--footer-height))}section{flex:1;height:calc(100vh - var(--footer-height));margin:0;padding:0 2rem;overflow-x:hidden;overflow-y:auto;box-sizing:border-box}section aside{height:calc(100vh - var(--header-height) - var(--footer-height));position:-webkit-sticky;position:sticky;overflow-x:hidden;top:0}section aside::ng-deep ul{list-style-type:none;border-left:1px solid #f5f5f5}section aside::ng-deep ul,section aside::ng-deep li{width:100%;margin:0;padding:0}section aside::ng-deep li{padding:0 0 4px 16px;line-height:1.5}section aside::ng-deep a{color:currentColor;text-decoration:none;white-space:nowrap;text-overflow:ellipsis;display:block;width:90%;overflow:hidden}section aside::ng-deep a:hover{text-decoration:underline}section aside::ng-deep li.active{color:currentColor;font-weight:700;border-left:2px solid var(--nge-doc-primary-color);box-sizing:border-box}section article{position:relative;display:grid;grid-template-columns:80% auto;padding-bottom:1rem}nge-doc-footer{height:var(--footer-height);padding:0 16rem}@media (max-width: 959.99px){section{padding:0 16px}section article{display:block}nge-doc-footer{padding:0 2rem}}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgeDocRendererComponent, selector: "nge-doc-renderer" }, { kind: "directive", type: NgeDocTocDirective, selector: "[ngeDocToc]", inputs: ["ngeDocToc"] }, { kind: "component", type: FooterComponent, selector: "nge-doc-footer" }, { kind: "component", type: HeaderComponent, selector: "nge-doc-header", outputs: ["toggle"] }, { kind: "component", type: SidenavComponent, selector: "nge-doc-sidenav" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: DefaultLayoutComponent, decorators: [{
            type: Component,
            args: [{ selector: 'nge-doc-default-layout', changeDetection: ChangeDetectionStrategy.OnPush, template: "<main>\n  <aside class=\"sidebar\" [class.opened]=\"sidebarOpened\">\n    <nge-doc-sidenav />\n  </aside>\n  <section>\n    <nge-doc-header (toggle)=\"sidebarOpened = !sidebarOpened\" />\n    <article>\n      <nge-doc-renderer #renderer />\n      <aside\n        *ngIf=\"showTableOfContents\"\n        [ngeDocToc]=\"renderer.componentRef\">\n      </aside>\n    </article>\n  </section>\n</main>\n<nge-doc-footer />\n", styles: [":host{--sidebar-width: 20rem;--footer-height: 100px;--header-height: 64px;--nge-doc-primary-color: #f50057;--nge-doc-sidebar-border-color: rgba(0, 0, 0, .07);display:block;width:100vw;height:100vh;overflow:hidden}main{display:flex;height:calc(100vh - var(--footer-height));overflow:hidden}aside.sidebar{display:block;width:0px;border-right:1px solid var(--nge-doc-sidebar-border-color);background-color:#fafbfc;opacity:0;pointer-events:none;transition:all .5s}aside.sidebar.opened{opacity:1;pointer-events:initial;width:var(--sidebar-width)}aside.sidebar,nge-doc-sidenav{height:calc(100vh - var(--footer-height))}section{flex:1;height:calc(100vh - var(--footer-height));margin:0;padding:0 2rem;overflow-x:hidden;overflow-y:auto;box-sizing:border-box}section aside{height:calc(100vh - var(--header-height) - var(--footer-height));position:-webkit-sticky;position:sticky;overflow-x:hidden;top:0}section aside::ng-deep ul{list-style-type:none;border-left:1px solid #f5f5f5}section aside::ng-deep ul,section aside::ng-deep li{width:100%;margin:0;padding:0}section aside::ng-deep li{padding:0 0 4px 16px;line-height:1.5}section aside::ng-deep a{color:currentColor;text-decoration:none;white-space:nowrap;text-overflow:ellipsis;display:block;width:90%;overflow:hidden}section aside::ng-deep a:hover{text-decoration:underline}section aside::ng-deep li.active{color:currentColor;font-weight:700;border-left:2px solid var(--nge-doc-primary-color);box-sizing:border-box}section article{position:relative;display:grid;grid-template-columns:80% auto;padding-bottom:1rem}nge-doc-footer{height:var(--footer-height);padding:0 16rem}@media (max-width: 959.99px){section{padding:0 16px}section article{display:block}nge-doc-footer{padding:0 2rem}}\n"] }]
        }], ctorParameters: () => [{ type: i1$1.BreakpointObserver }, { type: i0.ChangeDetectorRef }] });

class NgeDocComponent {
    constructor(docService) {
        this.docService = docService;
    }
    async ngOnInit() {
        await this.docService.setup();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocComponent, deps: [{ token: NgeDocService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: NgeDocComponent, selector: "nge-doc", providers: [NgeDocService], ngImport: i0, template: "<nge-doc-default-layout />\n", styles: [":host::ng-deep{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;letter-spacing:0;margin:0}:host::ng-deep *{-webkit-font-smoothing:antialiased;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;box-sizing:border-box}\n"], dependencies: [{ kind: "component", type: DefaultLayoutComponent, selector: "nge-doc-default-layout" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocComponent, decorators: [{
            type: Component,
            args: [{ selector: 'nge-doc', providers: [NgeDocService], template: "<nge-doc-default-layout />\n", styles: [":host::ng-deep{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;letter-spacing:0;margin:0}:host::ng-deep *{-webkit-font-smoothing:antialiased;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;box-sizing:border-box}\n"] }]
        }], ctorParameters: () => [{ type: NgeDocService }] });

const declarations = [NgeDocRendererComponent, NgeDocTocDirective];
class NgeDocRendererModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererModule, declarations: [NgeDocRendererComponent, NgeDocTocDirective], imports: [CommonModule], exports: [NgeDocRendererComponent, NgeDocTocDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererModule, imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CommonModule],
                    exports: declarations,
                    declarations,
                }]
        }] });

class DefaultLayoutModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: DefaultLayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.1", ngImport: i0, type: DefaultLayoutModule, declarations: [FooterComponent, HeaderComponent, SidenavComponent, DefaultLayoutComponent], imports: [CommonModule, RouterModule, NgeDocRendererModule], exports: [DefaultLayoutComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: DefaultLayoutModule, imports: [CommonModule, RouterModule, NgeDocRendererModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: DefaultLayoutModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [FooterComponent, HeaderComponent, SidenavComponent, DefaultLayoutComponent],
                    exports: [DefaultLayoutComponent],
                    imports: [CommonModule, RouterModule, NgeDocRendererModule],
                }]
        }] });

// ANGULAR
class NgeDocModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.1", ngImport: i0, type: NgeDocModule, declarations: [NgeDocComponent], imports: [CommonModule, i1.RouterModule, DefaultLayoutModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocModule, imports: [CommonModule,
            RouterModule.forChild([{ path: '**', pathMatch: 'full', component: NgeDocComponent }]),
            DefaultLayoutModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [NgeDocComponent],
                    imports: [
                        CommonModule,
                        RouterModule.forChild([{ path: '**', pathMatch: 'full', component: NgeDocComponent }]),
                        DefaultLayoutModule,
                    ],
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { NGE_DOC_RENDERERS, NgeDocModule, extractNgeDocSettings, isNgeDocSettings };
//# sourceMappingURL=cisstech-nge-doc.mjs.map