UNPKG

ngx-menubar

Version:

Simple basic menubar with step-into view display menu items(not tree view display) for angular14+.

211 lines 44.6 kB
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CommonModule } from "@angular/common"; import { BehaviorSubject, debounceTime, distinctUntilChanged, map } from "rxjs"; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; import * as i2 from "@angular/common"; /** * Simple basic menubar with step-into view display menu items(not tree view display). * @usageNotes * ```html * <style> * .container { * width: 350px; * height: 500px; * box-shadow: 1px 2px 8px rgba(0, 0, 0, .45); * } * </style> * * <div class="container"> * <cyx-menubar #menubar [datasource]="navs"></cyx-menubar> * </div> * ``` * @see IMenuItem */ export class CyxMenubarComponent { constructor(sanitizer) { this.sanitizer = sanitizer; /** * Default Top menu title. */ this.title = 'Menu'; /** * Menu items. */ this.datasource = []; /** * Theme color, 'dark' or 'light'. */ this.color = 'dark'; /** * Show bottom doc panel. */ this.showDocPanel = false; /** * Show menu icon. */ this.showMenuIcon = true; /** * Parse icon which from menu item data field {@link IMenuItem#icon}, e.g. * ```javascript * // menu item data. * {id: 1, title: '...', icon: 'deployed_code'} * * // font icon. * icon => `<span class="material-symbols-sharp">${icon}</span>` * * // svg icon. * icon => `<svg viewBox="...">...</svg>` * ``` * @param icon icon name. */ this.iconParser = (icon) => icon; /** * Global menu item search configuration. */ this.searchConfig = { placeHolder: 'search', predicate: (keyword, item) => item.title.toLowerCase().includes(keyword.toLowerCase()) }; /** * Menu item click event. */ this.itemClick = new EventEmitter(); this.indices = []; this.currentTitle = null; this.currentChildren = []; this.flattenItems = []; /** * Selected item. */ this.selectedItem = null; this._displayItems = []; this.searchTerms = new BehaviorSubject(''); } get displayItems() { return this._displayItems; } /** * Is menu top level. */ get isTopMenu() { return this.indices.length === 0; } ngOnChanges(changes) { if (changes['datasource']) { this.doFlatDatasource(this.datasource); } if (changes['active'] && this.active) { this.doActiveItemById(this.active); } } ngOnInit() { this.doFlatDatasource(this.datasource); if (this.active) { this.doActiveItemById(this.active); } else { this.currentChildren = this.datasource; this._displayItems = this.currentChildren; } this.searchPredicate = this.searchConfig.predicate || (() => true); this.searchTerms.pipe(debounceTime(300), distinctUntilChanged(), map(term => term.trim())).subscribe(term => { if (term) { this._displayItems = this.flattenItems.filter(item => this.searchPredicate(term, item)); return; } this._displayItems = this.currentChildren; }); } doActiveItemById(id) { const activeItem = this.flattenItems.find(i => i.id === id); if (activeItem) { this.currentChildren = [activeItem]; this._displayItems = this.currentChildren; } } doFlatDatasource(datasource) { const flatting = (items) => { return items.reduce((acc, curr) => { if (curr.children && curr.children.length > 0) { acc.push({ id: curr.id, title: curr.title, icon: curr.icon, data: curr.data, children: curr.children, }); return acc.concat(flatting(curr.children)); } acc.push(curr); return acc; }, []); }; this.flattenItems = flatting(datasource); } iconHTML(icon) { const iconHTMLString = this.iconParser(icon); return this.sanitizer.bypassSecurityTrustHtml(iconHTMLString); } clickItem(item, index) { this.selectedItem = item; if (item.children && item.children.length > 0) { this.indices.push(index); this.currentTitle = item.title; this.currentChildren = item.children; this._displayItems = this.currentChildren; } this.itemClick.emit(item); } backward() { this.indices.pop(); if (this.isTopMenu) { this.currentTitle = null; this.currentChildren = this.datasource; this._displayItems = this.currentChildren; return; } let prevItem = null; let prevItems = this.datasource; for (const index of this.indices) { prevItem = prevItems[index]; prevItems = prevItem.children || []; } this.currentTitle = prevItem?.title; this.currentChildren = prevItems; this._displayItems = this.currentChildren; } trackById(_, item) { return item.id; } searchItems(value) { this.searchTerms.next(value); } } CyxMenubarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CyxMenubarComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); CyxMenubarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CyxMenubarComponent, isStandalone: true, selector: "cyx-menubar", inputs: { title: "title", datasource: "datasource", color: "color", showDocPanel: "showDocPanel", showMenuIcon: "showMenuIcon", iconParser: "iconParser", searchConfig: "searchConfig", active: "active" }, outputs: { itemClick: "itemClick" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"menubar\" [ngClass]=\"color\">\n <header>\n <div class=\"backrow\" (click)=\"backward()\">\n <svg viewBox=\"0 0 542.187 461.8\" class=\"icon\" *ngIf=\"isTopMenu && showMenuIcon\">\n <g>\n <path\n d=\"M184.508 112.461V1.656h357.677v110.805H184.508M184.508 287.127V176.329h357.679v110.798H184.508M184.508 461.8V351h357.681v110.8H184.508M116.022 58.001c0 32.044-25.974 58.011-58.012 58.011C25.973 116.012 0 90.045 0 58.002 0 25.961 25.973-.005 58.01-.005c32.038 0 58.012 25.967 58.012 58.005M116.022 224.827c0 32.037-25.974 58.01-58.012 58.01-32.037 0-58.01-25.973-58.01-58.01 0-32.036 25.973-58.011 58.01-58.011 32.038 0 58.012 25.975 58.012 58.01M116.022 403.357c0 32.038-25.974 58.011-58.012 58.011-32.037 0-58.01-25.973-58.01-58.01 0-32.04 25.973-58.01 58.01-58.01 32.038 0 58.012 25.97 58.012 58.01\"></path>\n </g>\n </svg>\n <svg viewBox=\"0 0 14.2 21\" class=\"icon\" *ngIf=\"!isTopMenu\">\n <path d=\"M10.5 21l3.7-3.7-6.8-6.8 6.8-6.8L10.5 0 0 10.5z\"></path>\n </svg>\n <h1 class=\"label\" [class.no-icon-title]=\"!showMenuIcon && isTopMenu\">\n <ng-container *ngIf=\"currentTitle else defaultMenu\">{{ currentTitle }}</ng-container>\n <ng-template #defaultMenu>\n {{ title }}\n </ng-template>\n </h1>\n </div>\n </header>\n\n <header class=\"search\">\n <input type=\"text\" #searchBox [placeholder]=\"searchConfig.placeHolder || ''\"\n [value]=\"searchTerms.getValue()\"\n (input)=\"searchItems(searchBox.value)\"\n (keydown.enter)=\"searchItems(searchBox.value)\">\n\n <svg *ngIf=\"searchBox.value else queryIcon\" viewBox=\"0 0 18 18\" class=\"icon small\"\n (click)=\"searchBox.value = '';searchBox.focus();searchTerms.next('');\">\n <path\n d=\"M12.2 9l5.6-5.6c.2-.2.2-.6 0-.8L15.4.2c-.2-.2-.6-.2-.8 0L9 5.8 3.4.2c-.2-.2-.6-.2-.8 0L.2 2.5c-.2.2-.2.6 0 .8L5.8 9 .2 14.6c-.2.2-.2.6 0 .8l2.4 2.4c.2.2.6.2.8 0L9 12.2l5.6 5.6c.2.2.6.2.8 0l2.4-2.4c.2-.2.2-.6 0-.8L12.2 9z\"></path>\n </svg>\n <ng-template #queryIcon>\n <svg viewBox=\"0 0 594.573 594.107\" class=\"icon small\" (click)=\"searchBox.focus()\">\n <path\n d=\"M234.513 411.179c-96.785-.622-175.027-79.878-174.416-176.67.62-96.172 79.352-174.416 175.5-174.421l1.174.003c46.889.294 90.857 18.832 123.8 52.198 32.94 33.367 50.918 77.57 50.616 124.468-.296 46.687-18.703 90.524-51.823 123.42-33.112 32.894-77.04 51.003-123.69 51.003zm351.942 89.513l-3.588-3.585.008-.003-143.352-143.363c19.917-34.312 31.488-74.086 31.76-116.601C472.117 106.987 367.296.816 237.152-.003c-.525-.002-1.035-.002-1.557-.002C106.18 0 .838 104.516.005 234.125-.82 364.271 104.003 470.44 234.133 471.271c.519.002 1.022.005 1.54.005 43.258 0 83.795-11.72 118.664-32.1l143.226 143.241.013-.012 3.581 3.58c10.834 10.832 28.391 10.823 39.219 0l46.079-46.072c10.822-10.822 10.829-28.39 0-39.22\"></path>\n </svg>\n </ng-template>\n </header>\n\n <ul class=\"list\">\n <li *ngFor=\"let item of displayItems;index as i;trackBy:trackById\" (click)=\"clickItem(item,i)\"\n [class.selected]=\"item === selectedItem\">\n <div class=\"title\">\n <ng-container *ngIf=\"item.icon else defaultItemIcon\">\n <div class=\"icon\" [innerHTML]=\"iconHTML(item.icon)\"></div>\n </ng-container>\n <ng-template #defaultItemIcon>\n <svg class=\"icon\" viewBox=\"0 -960 960 960\">\n <path\n d=\"M480.276-96Q401-96 331-126q-70-30-122.5-82.5T126-330.958q-30-69.959-30-149.5Q96-560 126-629.5t82.5-122Q261-804 330.958-834q69.959-30 149.5-30Q560-864 629.5-834t122 82.5Q804-699 834-629.276q30 69.725 30 149Q864-401 834-331q-30 70-82.5 122.5T629.276-126q-69.725 30-149 30Z\"/>\n </svg>\n </ng-template>\n <span class=\"label\">{{ item.title }}</span>\n </div>\n <svg class=\"small icon\" viewBox=\"0 0 14.2 21\"\n *ngIf=\"(item.children && item.children.length > 0)\">\n <path d=\"M14.2 10.5L3.7 0 0 3.7l6.8 6.8L0 17.3 3.7 21z\"></path>\n </svg>\n </li>\n </ul>\n\n <div class=\"doc\" *ngIf=\"showDocPanel\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: ["h1,h2{font-size:1rem;font-weight:700;margin:0}.label{flex:1;font-size:1rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.icon{width:1.125em;height:1.125em;display:inline-block;fill:currentColor;vertical-align:middle;box-sizing:content-box}.icon.small{width:.75em;height:.75em}.menubar{min-width:50px;width:100%;height:100%;background:var(--bg-color);flex:1;display:flex;flex-direction:column;color:var(--text-color);border-right:1px solid var(--list-ui-color);z-index:100}.menubar>header{flex:0 0 2.5rem;padding:0;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border-bottom-color);transition:background .2s;color:var(--text-color)}.menubar>header h1{color:var(--header-fg-higlight)}.menubar>header .backrow{display:flex;flex:1 0 auto;align-items:center;cursor:pointer;margin:0;padding:.5rem 0;width:1px}.menubar>header .backrow:hover{color:var(--header-fg-higlight)}.menubar>header .backrow:hover .icon{color:currentColor}.menubar>header .backrow .icon{flex:0 0 auto;margin:0 1rem}.menubar>header .backrow .no-icon-title{padding-left:1rem}.menubar>header .icon{color:var(--li-icon-color);transition:color .2s}.menubar>header .icon:not(.inactive){cursor:pointer}.menubar>header .icon:not(.inactive):hover{color:var(--header-fg-higlight)}.menubar .search{position:relative;justify-content:flex-end}.menubar .search input{position:absolute;inset:0;padding:0 2.5rem 0 1rem;color:currentColor;font-size:14px;border:none;outline:none;background:transparent;z-index:10}.menubar .search input:hover,.menubar .search input:focus{outline:none}.menubar .search .icon{padding:.75rem 1rem;margin:0;z-index:11}.menubar .list{flex:1 1 0;display:flex;align-items:stretch;flex-direction:column;margin:0;padding:0;overflow-y:auto;background:var(--list-ui-color);border-bottom:2px solid var(--list-ui-color)}.menubar .list li{display:flex;flex:0 0 auto;padding:.5rem;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border-bottom-color);transition:background .2s,color .2s;color:var(--text-color)}.menubar .list li:not(.inactive){cursor:pointer}.menubar .list li:not(.inactive):hover{color:var(--icon-color-hover)}.menubar .list li:not(.inactive):hover .icon{color:var(--icon-color-hover)}.menubar .list li:hover:not(.inactive){background:var(--li-bg-color-hover)}.menubar .list li>*{margin:0 .5rem}.menubar .list li .icon{color:var(--li-icon-color);padding:.2rem 0;transition:fill .2s}.menubar .list li .title{display:flex;flex:1 0 auto;align-items:center;cursor:pointer;width:1px}.menubar .list li .title .icon{flex:0 0 auto;display:flex;justify-content:center;align-items:center;text-align:center}.menubar .list li .title .icon svg{width:1.125em;height:1.125em;display:inline-block;fill:currentColor;vertical-align:middle;box-sizing:content-box}.menubar .list li .title .label{margin-left:1rem}.menubar .list li.selected,.menubar .list li.selected .icon{color:var(--li-selected-color)}.menubar .doc{flex:1 1 0;overflow-y:auto;overflow-x:hidden;padding:1rem;-webkit-user-select:text;user-select:text;overflow-wrap:break-word;border-top:2px solid var(--doc-top-color);line-height:1.4em}\n", ".menubar.light{--bg-color: #f9f9f9;--header-fg-higlight: #5e5f61;--border-bottom-color: rgba(28, 28, 28, .08);--text-color: #616161;--list-ui-color: #ededed;--icon-color-hover: #e7e9ea;--li-icon-color: #797d81;--li-bg-color-hover: #4a4f53;--li-selected-color: #187cee;--doc-top-color: #e8e8e8}\n", ".menubar.dark{--bg-color: #282b2d;--header-fg-higlight: #f0f1f2;--border-bottom-color: rgba(240, 241, 242, .06);--text-color: #b7bcc0;--list-ui-color: #3a3e41;--icon-color-hover: #e7e9ea;--li-icon-color: #797d81;--li-bg-color-hover: #4a4f53;--li-selected-color: #7fc9ff;--doc-top-color: #282b2d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CyxMenubarComponent, decorators: [{ type: Component, args: [{ standalone: true, selector: 'cyx-menubar', imports: [ CommonModule ], template: "<div class=\"menubar\" [ngClass]=\"color\">\n <header>\n <div class=\"backrow\" (click)=\"backward()\">\n <svg viewBox=\"0 0 542.187 461.8\" class=\"icon\" *ngIf=\"isTopMenu && showMenuIcon\">\n <g>\n <path\n d=\"M184.508 112.461V1.656h357.677v110.805H184.508M184.508 287.127V176.329h357.679v110.798H184.508M184.508 461.8V351h357.681v110.8H184.508M116.022 58.001c0 32.044-25.974 58.011-58.012 58.011C25.973 116.012 0 90.045 0 58.002 0 25.961 25.973-.005 58.01-.005c32.038 0 58.012 25.967 58.012 58.005M116.022 224.827c0 32.037-25.974 58.01-58.012 58.01-32.037 0-58.01-25.973-58.01-58.01 0-32.036 25.973-58.011 58.01-58.011 32.038 0 58.012 25.975 58.012 58.01M116.022 403.357c0 32.038-25.974 58.011-58.012 58.011-32.037 0-58.01-25.973-58.01-58.01 0-32.04 25.973-58.01 58.01-58.01 32.038 0 58.012 25.97 58.012 58.01\"></path>\n </g>\n </svg>\n <svg viewBox=\"0 0 14.2 21\" class=\"icon\" *ngIf=\"!isTopMenu\">\n <path d=\"M10.5 21l3.7-3.7-6.8-6.8 6.8-6.8L10.5 0 0 10.5z\"></path>\n </svg>\n <h1 class=\"label\" [class.no-icon-title]=\"!showMenuIcon && isTopMenu\">\n <ng-container *ngIf=\"currentTitle else defaultMenu\">{{ currentTitle }}</ng-container>\n <ng-template #defaultMenu>\n {{ title }}\n </ng-template>\n </h1>\n </div>\n </header>\n\n <header class=\"search\">\n <input type=\"text\" #searchBox [placeholder]=\"searchConfig.placeHolder || ''\"\n [value]=\"searchTerms.getValue()\"\n (input)=\"searchItems(searchBox.value)\"\n (keydown.enter)=\"searchItems(searchBox.value)\">\n\n <svg *ngIf=\"searchBox.value else queryIcon\" viewBox=\"0 0 18 18\" class=\"icon small\"\n (click)=\"searchBox.value = '';searchBox.focus();searchTerms.next('');\">\n <path\n d=\"M12.2 9l5.6-5.6c.2-.2.2-.6 0-.8L15.4.2c-.2-.2-.6-.2-.8 0L9 5.8 3.4.2c-.2-.2-.6-.2-.8 0L.2 2.5c-.2.2-.2.6 0 .8L5.8 9 .2 14.6c-.2.2-.2.6 0 .8l2.4 2.4c.2.2.6.2.8 0L9 12.2l5.6 5.6c.2.2.6.2.8 0l2.4-2.4c.2-.2.2-.6 0-.8L12.2 9z\"></path>\n </svg>\n <ng-template #queryIcon>\n <svg viewBox=\"0 0 594.573 594.107\" class=\"icon small\" (click)=\"searchBox.focus()\">\n <path\n d=\"M234.513 411.179c-96.785-.622-175.027-79.878-174.416-176.67.62-96.172 79.352-174.416 175.5-174.421l1.174.003c46.889.294 90.857 18.832 123.8 52.198 32.94 33.367 50.918 77.57 50.616 124.468-.296 46.687-18.703 90.524-51.823 123.42-33.112 32.894-77.04 51.003-123.69 51.003zm351.942 89.513l-3.588-3.585.008-.003-143.352-143.363c19.917-34.312 31.488-74.086 31.76-116.601C472.117 106.987 367.296.816 237.152-.003c-.525-.002-1.035-.002-1.557-.002C106.18 0 .838 104.516.005 234.125-.82 364.271 104.003 470.44 234.133 471.271c.519.002 1.022.005 1.54.005 43.258 0 83.795-11.72 118.664-32.1l143.226 143.241.013-.012 3.581 3.58c10.834 10.832 28.391 10.823 39.219 0l46.079-46.072c10.822-10.822 10.829-28.39 0-39.22\"></path>\n </svg>\n </ng-template>\n </header>\n\n <ul class=\"list\">\n <li *ngFor=\"let item of displayItems;index as i;trackBy:trackById\" (click)=\"clickItem(item,i)\"\n [class.selected]=\"item === selectedItem\">\n <div class=\"title\">\n <ng-container *ngIf=\"item.icon else defaultItemIcon\">\n <div class=\"icon\" [innerHTML]=\"iconHTML(item.icon)\"></div>\n </ng-container>\n <ng-template #defaultItemIcon>\n <svg class=\"icon\" viewBox=\"0 -960 960 960\">\n <path\n d=\"M480.276-96Q401-96 331-126q-70-30-122.5-82.5T126-330.958q-30-69.959-30-149.5Q96-560 126-629.5t82.5-122Q261-804 330.958-834q69.959-30 149.5-30Q560-864 629.5-834t122 82.5Q804-699 834-629.276q30 69.725 30 149Q864-401 834-331q-30 70-82.5 122.5T629.276-126q-69.725 30-149 30Z\"/>\n </svg>\n </ng-template>\n <span class=\"label\">{{ item.title }}</span>\n </div>\n <svg class=\"small icon\" viewBox=\"0 0 14.2 21\"\n *ngIf=\"(item.children && item.children.length > 0)\">\n <path d=\"M14.2 10.5L3.7 0 0 3.7l6.8 6.8L0 17.3 3.7 21z\"></path>\n </svg>\n </li>\n </ul>\n\n <div class=\"doc\" *ngIf=\"showDocPanel\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: ["h1,h2{font-size:1rem;font-weight:700;margin:0}.label{flex:1;font-size:1rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.icon{width:1.125em;height:1.125em;display:inline-block;fill:currentColor;vertical-align:middle;box-sizing:content-box}.icon.small{width:.75em;height:.75em}.menubar{min-width:50px;width:100%;height:100%;background:var(--bg-color);flex:1;display:flex;flex-direction:column;color:var(--text-color);border-right:1px solid var(--list-ui-color);z-index:100}.menubar>header{flex:0 0 2.5rem;padding:0;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border-bottom-color);transition:background .2s;color:var(--text-color)}.menubar>header h1{color:var(--header-fg-higlight)}.menubar>header .backrow{display:flex;flex:1 0 auto;align-items:center;cursor:pointer;margin:0;padding:.5rem 0;width:1px}.menubar>header .backrow:hover{color:var(--header-fg-higlight)}.menubar>header .backrow:hover .icon{color:currentColor}.menubar>header .backrow .icon{flex:0 0 auto;margin:0 1rem}.menubar>header .backrow .no-icon-title{padding-left:1rem}.menubar>header .icon{color:var(--li-icon-color);transition:color .2s}.menubar>header .icon:not(.inactive){cursor:pointer}.menubar>header .icon:not(.inactive):hover{color:var(--header-fg-higlight)}.menubar .search{position:relative;justify-content:flex-end}.menubar .search input{position:absolute;inset:0;padding:0 2.5rem 0 1rem;color:currentColor;font-size:14px;border:none;outline:none;background:transparent;z-index:10}.menubar .search input:hover,.menubar .search input:focus{outline:none}.menubar .search .icon{padding:.75rem 1rem;margin:0;z-index:11}.menubar .list{flex:1 1 0;display:flex;align-items:stretch;flex-direction:column;margin:0;padding:0;overflow-y:auto;background:var(--list-ui-color);border-bottom:2px solid var(--list-ui-color)}.menubar .list li{display:flex;flex:0 0 auto;padding:.5rem;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border-bottom-color);transition:background .2s,color .2s;color:var(--text-color)}.menubar .list li:not(.inactive){cursor:pointer}.menubar .list li:not(.inactive):hover{color:var(--icon-color-hover)}.menubar .list li:not(.inactive):hover .icon{color:var(--icon-color-hover)}.menubar .list li:hover:not(.inactive){background:var(--li-bg-color-hover)}.menubar .list li>*{margin:0 .5rem}.menubar .list li .icon{color:var(--li-icon-color);padding:.2rem 0;transition:fill .2s}.menubar .list li .title{display:flex;flex:1 0 auto;align-items:center;cursor:pointer;width:1px}.menubar .list li .title .icon{flex:0 0 auto;display:flex;justify-content:center;align-items:center;text-align:center}.menubar .list li .title .icon svg{width:1.125em;height:1.125em;display:inline-block;fill:currentColor;vertical-align:middle;box-sizing:content-box}.menubar .list li .title .label{margin-left:1rem}.menubar .list li.selected,.menubar .list li.selected .icon{color:var(--li-selected-color)}.menubar .doc{flex:1 1 0;overflow-y:auto;overflow-x:hidden;padding:1rem;-webkit-user-select:text;user-select:text;overflow-wrap:break-word;border-top:2px solid var(--doc-top-color);line-height:1.4em}\n", ".menubar.light{--bg-color: #f9f9f9;--header-fg-higlight: #5e5f61;--border-bottom-color: rgba(28, 28, 28, .08);--text-color: #616161;--list-ui-color: #ededed;--icon-color-hover: #e7e9ea;--li-icon-color: #797d81;--li-bg-color-hover: #4a4f53;--li-selected-color: #187cee;--doc-top-color: #e8e8e8}\n", ".menubar.dark{--bg-color: #282b2d;--header-fg-higlight: #f0f1f2;--border-bottom-color: rgba(240, 241, 242, .06);--text-color: #b7bcc0;--list-ui-color: #3a3e41;--icon-color-hover: #e7e9ea;--li-icon-color: #797d81;--li-bg-color-hover: #4a4f53;--li-selected-color: #7fc9ff;--doc-top-color: #282b2d}\n"] }] }], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; }, propDecorators: { title: [{ type: Input }], datasource: [{ type: Input }], color: [{ type: Input }], showDocPanel: [{ type: Input }], showMenuIcon: [{ type: Input }], iconParser: [{ type: Input }], searchConfig: [{ type: Input }], active: [{ type: Input }], itemClick: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3l4LW1lbnViYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW1lbnViYXIvc3JjL2xpYi9jeXgtbWVudWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbWVudWJhci9zcmMvbGliL2N5eC1tZW51YmFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFnQixNQUFNLGVBQWUsQ0FBQztBQUN2RyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFN0MsT0FBTyxFQUFDLGVBQWUsRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFDLE1BQU0sTUFBTSxDQUFDOzs7O0FBcUI5RTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFZSCxNQUFNLE9BQU8sbUJBQW1CO0lBOEU5QixZQUFvQixTQUF1QjtRQUF2QixjQUFTLEdBQVQsU0FBUyxDQUFjO1FBN0UzQzs7V0FFRztRQUNNLFVBQUssR0FBVyxNQUFNLENBQUM7UUFDaEM7O1dBRUc7UUFDTSxlQUFVLEdBQWdCLEVBQUUsQ0FBQztRQUN0Qzs7V0FFRztRQUNNLFVBQUssR0FBVyxNQUFNLENBQUM7UUFDaEM7O1dBRUc7UUFDTSxpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUN2Qzs7V0FFRztRQUNNLGlCQUFZLEdBQVksSUFBSSxDQUFDO1FBQ3RDOzs7Ozs7Ozs7Ozs7O1dBYUc7UUFDTSxlQUFVLEdBQTZCLENBQUMsSUFBWSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFDdkU7O1dBRUc7UUFDTSxpQkFBWSxHQUFpQjtZQUNwQyxXQUFXLEVBQUUsUUFBUTtZQUNyQixTQUFTLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDdkYsQ0FBQTtRQUtEOztXQUVHO1FBQ08sY0FBUyxHQUE0QixJQUFJLFlBQVksRUFBYSxDQUFDO1FBRW5FLFlBQU8sR0FBYSxFQUFFLENBQUM7UUFDdkIsaUJBQVksR0FBbUIsSUFBSSxDQUFDO1FBQ3BDLG9CQUFlLEdBQWdCLEVBQUUsQ0FBQztRQUNsQyxpQkFBWSxHQUFnQixFQUFFLENBQUM7UUFFekM7O1dBRUc7UUFDSCxpQkFBWSxHQUFxQixJQUFJLENBQUM7UUFJOUIsa0JBQWEsR0FBZ0IsRUFBRSxDQUFDO1FBWXJCLGdCQUFXLEdBQUcsSUFBSSxlQUFlLENBQVMsRUFBRSxDQUFDLENBQUM7SUFHakUsQ0FBQztJQWRELElBQWMsWUFBWTtRQUN4QixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQU9ELFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRTtZQUN6QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQ3hDO1FBQ0QsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNwQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3BDO0lBQ0gsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDcEM7YUFBTTtZQUNMLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUN2QyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7U0FDM0M7UUFDRCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbkUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQ25CLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFDakIsb0JBQW9CLEVBQUUsRUFDdEIsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQ3pCLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ2pCLElBQUksSUFBSSxFQUFFO2dCQUNSLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUN4RixPQUFPO2FBQ1I7WUFDRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMsZ0JBQWdCLENBQUMsRUFBbUI7UUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzVELElBQUksVUFBVSxFQUFFO1lBQ2QsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztTQUMzQztJQUNILENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxVQUF1QjtRQUM5QyxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQWtCLEVBQWUsRUFBRTtZQUNuRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFnQixFQUFFLElBQUksRUFBRSxFQUFFO2dCQUM3QyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29CQUM3QyxHQUFHLENBQUMsSUFBSSxDQUFDO3dCQUNQLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTt3QkFDWCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7d0JBQ2pCLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTt3QkFDZixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7d0JBQ2YsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO3FCQUN4QixDQUFDLENBQUM7b0JBQ0gsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztpQkFDNUM7Z0JBQ0QsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDZixPQUFPLEdBQUcsQ0FBQztZQUNiLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNULENBQUMsQ0FBQTtRQUNELElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFUyxRQUFRLENBQUMsSUFBWTtRQUM3QixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRVMsU0FBUyxDQUFDLElBQWUsRUFBRSxLQUFhO1FBQ2hELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQy9CLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztZQUNyQyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7U0FDM0M7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRVMsUUFBUTtRQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ25CLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUN6QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDdkMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQzFDLE9BQU87U0FDUjtRQUNELElBQUksUUFBUSxHQUFxQixJQUFJLENBQUM7UUFDdEMsSUFBSSxTQUFTLEdBQWdCLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDN0MsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hDLFFBQVEsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUIsU0FBUyxHQUFHLFFBQVEsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO1NBQ3JDO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFRLEVBQUUsS0FBSyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUM1QyxDQUFDO0lBRVMsU0FBUyxDQUFDLENBQVMsRUFBRSxJQUFlO1FBQzVDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRVMsV0FBVyxDQUFDLEtBQWE7UUFDakMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQzs7Z0hBdExVLG1CQUFtQjtvR0FBbkIsbUJBQW1CLDZVQ3JEaEMsZ29JQWtFQSx3dUhEbkJJLFlBQVk7MkZBTUgsbUJBQW1CO2tCQVgvQixTQUFTO2lDQUNJLElBQUksWUFDTixhQUFhLFdBRWQ7d0JBQ1AsWUFBWTtxQkFDYjttR0FTUSxLQUFLO3NCQUFiLEtBQUs7Z0JBSUcsVUFBVTtzQkFBbEIsS0FBSztnQkFJRyxLQUFLO3NCQUFiLEtBQUs7Z0JBSUcsWUFBWTtzQkFBcEIsS0FBSztnQkFJRyxZQUFZO3NCQUFwQixLQUFLO2dCQWVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBSUcsWUFBWTtzQkFBcEIsS0FBSztnQkFPRyxNQUFNO3NCQUFkLEtBQUs7Z0JBSUksU0FBUztzQkFBbEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uSW5pdCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q29tbW9uTW9kdWxlfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge0RvbVNhbml0aXplciwgU2FmZUh0bWx9IGZyb20gXCJAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyXCI7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwfSBmcm9tIFwicnhqc1wiO1xuXG4vKipcbiAqIE1lbnViYXIgbWVudSBpdGVtIHR5cGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSU1lbnVJdGVtIHtcbiAgaWQ6IG51bWJlciB8IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgaWNvbj86IHN0cmluZztcbiAgY2hpbGRyZW4/OiBJTWVudUl0ZW1bXTtcbiAgZGF0YT86IHsgW2tleTogc3RyaW5nXTogYW55IH1cbn1cblxuLyoqXG4gKiBHbG9iYWwgbWVudSBpdGVtIFNlYXJjaCBjb25maWd1cmF0aW9uIHR5cGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoQ29uZmlnIHtcbiAgcGxhY2VIb2xkZXI/OiBzdHJpbmc7XG4gIHByZWRpY2F0ZT86IChrZXl3b3JkOiBzdHJpbmcsIGl0ZW06IElNZW51SXRlbSkgPT4gYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBTaW1wbGUgYmFzaWMgbWVudWJhciB3aXRoIHN0ZXAtaW50byB2aWV3IGRpc3BsYXkgbWVudSBpdGVtcyhub3QgdHJlZSB2aWV3IGRpc3BsYXkpLlxuICogQHVzYWdlTm90ZXNcbiAqIGBgYGh0bWxcbiAqIDxzdHlsZT5cbiAqICAgLmNvbnRhaW5lciB7XG4gKiAgICAgIHdpZHRoOiAzNTBweDtcbiAqICAgICAgaGVpZ2h0OiA1MDBweDtcbiAqICAgICAgYm94LXNoYWRvdzogMXB4IDJweCA4cHggcmdiYSgwLCAwLCAwLCAuNDUpO1xuICogICB9XG4gKiA8L3N0eWxlPlxuICpcbiAqIDxkaXYgY2xhc3M9XCJjb250YWluZXJcIj5cbiAqICA8Y3l4LW1lbnViYXIgI21lbnViYXIgW2RhdGFzb3VyY2VdPVwibmF2c1wiPjwvY3l4LW1lbnViYXI+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICogQHNlZSBJTWVudUl0ZW1cbiAqL1xuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnY3l4LW1lbnViYXInLFxuICB0ZW1wbGF0ZVVybDogJ2N5eC1tZW51YmFyLmNvbXBvbmVudC5odG1sJyxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZVxuICBdLFxuICBzdHlsZVVybHM6IFsnY3l4LW1lbnViYXIuY29tcG9uZW50LnNjc3MnLFxuICAgICdjeXgtbWVudWJhci5saWdodC5jb21wb25lbnQuc2NzcycsXG4gICAgJ2N5eC1tZW51YmFyLmRhcmsuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBDeXhNZW51YmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICAvKipcbiAgICogRGVmYXVsdCBUb3AgbWVudSB0aXRsZS5cbiAgICovXG4gIEBJbnB1dCgpIHRpdGxlOiBzdHJpbmcgPSAnTWVudSc7XG4gIC8qKlxuICAgKiBNZW51IGl0ZW1zLlxuICAgKi9cbiAgQElucHV0KCkgZGF0YXNvdXJjZTogSU1lbnVJdGVtW10gPSBbXTtcbiAgLyoqXG4gICAqIFRoZW1lIGNvbG9yLCAnZGFyaycgb3IgJ2xpZ2h0Jy5cbiAgICovXG4gIEBJbnB1dCgpIGNvbG9yOiBzdHJpbmcgPSAnZGFyayc7XG4gIC8qKlxuICAgKiBTaG93IGJvdHRvbSBkb2MgcGFuZWwuXG4gICAqL1xuICBASW5wdXQoKSBzaG93RG9jUGFuZWw6IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqXG4gICAqIFNob3cgbWVudSBpY29uLlxuICAgKi9cbiAgQElucHV0KCkgc2hvd01lbnVJY29uOiBib29sZWFuID0gdHJ1ZTtcbiAgLyoqXG4gICAqIFBhcnNlIGljb24gd2hpY2ggZnJvbSBtZW51IGl0ZW0gZGF0YSBmaWVsZCB7QGxpbmsgSU1lbnVJdGVtI2ljb259LCBlLmcuXG4gICAqIGBgYGphdmFzY3JpcHRcbiAgICogIC8vIG1lbnUgaXRlbSBkYXRhLlxuICAgKiAge2lkOiAxLCB0aXRsZTogJy4uLicsIGljb246ICdkZXBsb3llZF9jb2RlJ31cbiAgICpcbiAgICogIC8vIGZvbnQgaWNvbi5cbiAgICogIGljb24gPT4gYDxzcGFuIGNsYXNzPVwibWF0ZXJpYWwtc3ltYm9scy1zaGFycFwiPiR7aWNvbn08L3NwYW4+YFxuICAgKlxuICAgKiAgLy8gc3ZnIGljb24uXG4gICAqICBpY29uID0+IGA8c3ZnIHZpZXdCb3g9XCIuLi5cIj4uLi48L3N2Zz5gXG4gICAqIGBgYFxuICAgKiBAcGFyYW0gaWNvbiBpY29uIG5hbWUuXG4gICAqL1xuICBASW5wdXQoKSBpY29uUGFyc2VyOiAoaWNvbjogc3RyaW5nKSA9PiBzdHJpbmcgPSAoaWNvbjogc3RyaW5nKSA9PiBpY29uO1xuICAvKipcbiAgICogR2xvYmFsIG1lbnUgaXRlbSBzZWFyY2ggY29uZmlndXJhdGlvbi5cbiAgICovXG4gIEBJbnB1dCgpIHNlYXJjaENvbmZpZzogU2VhcmNoQ29uZmlnID0ge1xuICAgIHBsYWNlSG9sZGVyOiAnc2VhcmNoJyxcbiAgICBwcmVkaWNhdGU6IChrZXl3b3JkLCBpdGVtKSA9PiBpdGVtLnRpdGxlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoa2V5d29yZC50b0xvd2VyQ2FzZSgpKVxuICB9XG4gIC8qKlxuICAgKiBBY3RpdmUgaXRlbSBpZC5cbiAgICovXG4gIEBJbnB1dCgpIGFjdGl2ZT86IG51bWJlciB8IHN0cmluZztcbiAgLyoqXG4gICAqIE1lbnUgaXRlbSBjbGljayBldmVudC5cbiAgICovXG4gIEBPdXRwdXQoKSBpdGVtQ2xpY2s6IEV2ZW50RW1pdHRlcjxJTWVudUl0ZW0+ID0gbmV3IEV2ZW50RW1pdHRlcjxJTWVudUl0ZW0+KCk7XG5cbiAgcHJvdGVjdGVkIGluZGljZXM6IG51bWJlcltdID0gW107XG4gIHByb3RlY3RlZCBjdXJyZW50VGl0bGU/OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIGN1cnJlbnRDaGlsZHJlbjogSU1lbnVJdGVtW10gPSBbXTtcbiAgcHJvdGVjdGVkIGZsYXR0ZW5JdGVtczogSU1lbnVJdGVtW10gPSBbXTtcblxuICAvKipcbiAgICogU2VsZWN0ZWQgaXRlbS5cbiAgICovXG4gIHNlbGVjdGVkSXRlbTogSU1lbnVJdGVtIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBzZWFyY2hQcmVkaWNhdGUhOiAoa2V5d29yZDogc3RyaW5nLCBpdGVtOiBJTWVudUl0ZW0pID0+IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBfZGlzcGxheUl0ZW1zOiBJTWVudUl0ZW1bXSA9IFtdO1xuICBwcm90ZWN0ZWQgZ2V0IGRpc3BsYXlJdGVtcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZGlzcGxheUl0ZW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIElzIG1lbnUgdG9wIGxldmVsLlxuICAgKi9cbiAgZ2V0IGlzVG9wTWVudSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pbmRpY2VzLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIHByb3RlY3RlZCByZWFkb25seSBzZWFyY2hUZXJtcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcikge1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydkYXRhc291cmNlJ10pIHtcbiAgICAgIHRoaXMuZG9GbGF0RGF0YXNvdXJjZSh0aGlzLmRhdGFzb3VyY2UpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snYWN0aXZlJ10gJiYgdGhpcy5hY3RpdmUpIHtcbiAgICAgIHRoaXMuZG9BY3RpdmVJdGVtQnlJZCh0aGlzLmFjdGl2ZSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5kb0ZsYXREYXRhc291cmNlKHRoaXMuZGF0YXNvdXJjZSk7XG4gICAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgICB0aGlzLmRvQWN0aXZlSXRlbUJ5SWQodGhpcy5hY3RpdmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmN1cnJlbnRDaGlsZHJlbiA9IHRoaXMuZGF0YXNvdXJjZTtcbiAgICAgIHRoaXMuX2Rpc3BsYXlJdGVtcyA9IHRoaXMuY3VycmVudENoaWxkcmVuO1xuICAgIH1cbiAgICB0aGlzLnNlYXJjaFByZWRpY2F0ZSA9IHRoaXMuc2VhcmNoQ29uZmlnLnByZWRpY2F0ZSB8fCAoKCkgPT4gdHJ1ZSk7XG5cbiAgICB0aGlzLnNlYXJjaFRlcm1zLnBpcGUoXG4gICAgICBkZWJvdW5jZVRpbWUoMzAwKSxcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBtYXAodGVybSA9PiB0ZXJtLnRyaW0oKSlcbiAgICApLnN1YnNjcmliZSh0ZXJtID0+IHtcbiAgICAgIGlmICh0ZXJtKSB7XG4gICAgICAgIHRoaXMuX2Rpc3BsYXlJdGVtcyA9IHRoaXMuZmxhdHRlbkl0ZW1zLmZpbHRlcihpdGVtID0+IHRoaXMuc2VhcmNoUHJlZGljYXRlKHRlcm0sIGl0ZW0pKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5fZGlzcGxheUl0ZW1zID0gdGhpcy5jdXJyZW50Q2hpbGRyZW47XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZG9BY3RpdmVJdGVtQnlJZChpZDogbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgY29uc3QgYWN0aXZlSXRlbSA9IHRoaXMuZmxhdHRlbkl0ZW1zLmZpbmQoaSA9PiBpLmlkID09PSBpZCk7XG4gICAgaWYgKGFjdGl2ZUl0ZW0pIHtcbiAgICAgIHRoaXMuY3VycmVudENoaWxkcmVuID0gW2FjdGl2ZUl0ZW1dO1xuICAgICAgdGhpcy5fZGlzcGxheUl0ZW1zID0gdGhpcy5jdXJyZW50Q2hpbGRyZW47XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkb0ZsYXREYXRhc291cmNlKGRhdGFzb3VyY2U6IElNZW51SXRlbVtdKSB7XG4gICAgY29uc3QgZmxhdHRpbmcgPSAoaXRlbXM6IElNZW51SXRlbVtdKTogSU1lbnVJdGVtW10gPT4ge1xuICAgICAgcmV0dXJuIGl0ZW1zLnJlZHVjZSgoYWNjOiBJTWVudUl0ZW1bXSwgY3VycikgPT4ge1xuICAgICAgICBpZiAoY3Vyci5jaGlsZHJlbiAmJiBjdXJyLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhY2MucHVzaCh7XG4gICAgICAgICAgICBpZDogY3Vyci5pZCxcbiAgICAgICAgICAgIHRpdGxlOiBjdXJyLnRpdGxlLFxuICAgICAgICAgICAgaWNvbjogY3Vyci5pY29uLFxuICAgICAgICAgICAgZGF0YTogY3Vyci5kYXRhLFxuICAgICAgICAgICAgY2hpbGRyZW46IGN1cnIuY2hpbGRyZW4sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIGFjYy5jb25jYXQoZmxhdHRpbmcoY3Vyci5jaGlsZHJlbikpO1xuICAgICAgICB9XG4gICAgICAgIGFjYy5wdXNoKGN1cnIpO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgW10pO1xuICAgIH1cbiAgICB0aGlzLmZsYXR0ZW5JdGVtcyA9IGZsYXR0aW5nKGRhdGFzb3VyY2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGljb25IVE1MKGljb246IHN0cmluZyk6IFNhZmVIdG1sIHtcbiAgICBjb25zdCBpY29uSFRNTFN0cmluZyA9IHRoaXMuaWNvblBhcnNlcihpY29uKTtcbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWwoaWNvbkhUTUxTdHJpbmcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNsaWNrSXRlbShpdGVtOiBJTWVudUl0ZW0sIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnNlbGVjdGVkSXRlbSA9IGl0ZW07XG4gICAgaWYgKGl0ZW0uY2hpbGRyZW4gJiYgaXRlbS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmluZGljZXMucHVzaChpbmRleCk7XG4gICAgICB0aGlzLmN1cnJlbnRUaXRsZSA9IGl0ZW0udGl0bGU7XG4gICAgICB0aGlzLmN1cnJlbnRDaGlsZHJlbiA9IGl0ZW0uY2hpbGRyZW47XG4gICAgICB0aGlzLl9kaXNwbGF5SXRlbXMgPSB0aGlzLmN1cnJlbnRDaGlsZHJlbjtcbiAgICB9XG4gICAgdGhpcy5pdGVtQ2xpY2suZW1pdChpdGVtKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBiYWNrd2FyZCgpIHtcbiAgICB0aGlzLmluZGljZXMucG9wKCk7XG4gICAgaWYgKHRoaXMuaXNUb3BNZW51KSB7XG4gICAgICB0aGlzLmN1cnJlbnRUaXRsZSA9IG51bGw7XG4gICAgICB0aGlzLmN1cnJlbnRDaGlsZHJlbiA9IHRoaXMuZGF0YXNvdXJjZTtcbiAgICAgIHRoaXMuX2Rpc3BsYXlJdGVtcyA9IHRoaXMuY3VycmVudENoaWxkcmVuO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcHJldkl0ZW06IElNZW51SXRlbSB8IG51bGwgPSBudWxsO1xuICAgIGxldCBwcmV2SXRlbXM6IElNZW51SXRlbVtdID0gdGhpcy5kYXRhc291cmNlO1xuICAgIGZvciAoY29uc3QgaW5kZXggb2YgdGhpcy5pbmRpY2VzKSB7XG4gICAgICBwcmV2SXRlbSA9IHByZXZJdGVtc1tpbmRleF07XG4gICAgICBwcmV2SXRlbXMgPSBwcmV2SXRlbS5jaGlsZHJlbiB8fCBbXTtcbiAgICB9XG4gICAgdGhpcy5jdXJyZW50VGl0bGUgPSBwcmV2SXRlbT8udGl0bGU7XG4gICAgdGhpcy5jdXJyZW50Q2hpbGRyZW4gPSBwcmV2SXRlbXM7XG4gICAgdGhpcy5fZGlzcGxheUl0ZW1zID0gdGhpcy5jdXJyZW50Q2hpbGRyZW47XG4gIH1cblxuICBwcm90ZWN0ZWQgdHJhY2tCeUlkKF86IG51bWJlciwgaXRlbTogSU1lbnVJdGVtKSB7XG4gICAgcmV0dXJuIGl0ZW0uaWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2VhcmNoSXRlbXModmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuc2VhcmNoVGVybXMubmV4dCh2YWx1ZSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtZW51YmFyXCIgW25nQ2xhc3NdPVwiY29sb3JcIj5cbiAgPGhlYWRlcj5cbiAgICA8ZGl2IGNsYXNzPVwiYmFja3Jvd1wiIChjbGljayk9XCJiYWNrd2FyZCgpXCI+XG4gICAgICA8c3ZnIHZpZXdCb3g9XCIwIDAgNTQyLjE4NyA0NjEuOFwiIGNsYXNzPVwiaWNvblwiICpuZ0lmPVwiaXNUb3BNZW51ICYmIHNob3dNZW51SWNvblwiPlxuICAgICAgICA8Zz5cbiAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgZD1cIk0xODQuNTA4IDExMi40NjFWMS42NTZoMzU3LjY3N3YxMTAuODA1SDE4NC41MDhNMTg0LjUwOCAyODcuMTI3VjE3Ni4zMjloMzU3LjY3OXYxMTAuNzk4SDE4NC41MDhNMTg0LjUwOCA0NjEuOFYzNTFoMzU3LjY4MXYxMTAuOEgxODQuNTA4TTExNi4wMjIgNTguMDAxYzAgMzIuMDQ0LTI1Ljk3NCA1OC4wMTEtNTguMDEyIDU4LjAxMUMyNS45NzMgMTE2LjAxMiAwIDkwLjA0NSAwIDU4LjAwMiAwIDI1Ljk2MSAyNS45NzMtLjAwNSA1OC4wMS0uMDA1YzMyLjAzOCAwIDU4LjAxMiAyNS45NjcgNTguMDEyIDU4LjAwNU0xMTYuMDIyIDIyNC44MjdjMCAzMi4wMzctMjUuOTc0IDU4LjAxLTU4LjAxMiA1OC4wMS0zMi4wMzcgMC01OC4wMS0yNS45NzMtNTguMDEtNTguMDEgMC0zMi4wMzYgMjUuOTczLTU4LjAxMSA1OC4wMS01OC4wMTEgMzIuMDM4IDAgNTguMDEyIDI1Ljk3NSA1OC4wMTIgNTguMDFNMTE2LjAyMiA0MDMuMzU3YzAgMzIuMDM4LTI1Ljk3NCA1OC4wMTEtNTguMDEyIDU4LjAxMS0zMi4wMzcgMC01OC4wMS0yNS45NzMtNTguMDEtNTguMDEgMC0zMi4wNCAyNS45NzMtNTguMDEgNTguMDEtNTguMDEgMzIuMDM4IDAgNTguMDEyIDI1Ljk3IDU4LjAxMiA1OC4wMVwiPjwvcGF0aD5cbiAgICAgICAgPC9nPlxuICAgICAgPC9zdmc+XG4gICAgICA8c3ZnIHZpZXdCb3g9XCIwIDAgMTQuMiAyMVwiIGNsYXNzPVwiaWNvblwiICpuZ0lmPVwiIWlzVG9wTWVudVwiPlxuICAgICAgICA8cGF0aCBkPVwiTTEwLjUgMjFsMy43LTMuNy02LjgtNi44IDYuOC02LjhMMTAuNSAwIDAgMTAuNXpcIj48L3BhdGg+XG4gICAgICA8L3N2Zz5cbiAgICAgIDxoMSBjbGFzcz1cImxhYmVsXCIgW2NsYXNzLm5vLWljb24tdGl0bGVdPVwiIXNob3dNZW51SWNvbiAmJiBpc1RvcE1lbnVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImN1cnJlbnRUaXRsZSBlbHNlIGRlZmF1bHRNZW51XCI+e3sgY3VycmVudFRpdGxlIH19PC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdE1lbnU+XG4gICAgICAgICAge3sgdGl0bGUgfX1cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvaDE+XG4gICAgPC9kaXY+XG4gIDwvaGVhZGVyPlxuXG4gIDxoZWFkZXIgY2xhc3M9XCJzZWFyY2hcIj5cbiAgICA8aW5wdXQgdHlwZT1cInRleHRcIiAjc2VhcmNoQm94IFtwbGFjZWhvbGRlcl09XCJzZWFyY2hDb25maWcucGxhY2VIb2xkZXIgfHwgJydcIlxuICAgICAgICAgICBbdmFsdWVdPVwic2VhcmNoVGVybXMuZ2V0VmFsdWUoKVwiXG4gICAgICAgICAgIChpbnB1dCk9XCJzZWFyY2hJdGVtcyhzZWFyY2hCb3gudmFsdWUpXCJcbiAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwic2VhcmNoSXRlbXMoc2VhcmNoQm94LnZhbHVlKVwiPlxuXG4gICAgPHN2ZyAqbmdJZj1cInNlYXJjaEJveC52YWx1ZSBlbHNlIHF1ZXJ5SWNvblwiIHZpZXdCb3g9XCIwIDAgMTggMThcIiBjbGFzcz1cImljb24gc21hbGxcIlxuICAgICAgICAgKGNsaWNrKT1cInNlYXJjaEJveC52YWx1ZSA9ICcnO3NlYXJjaEJveC5mb2N1cygpO3NlYXJjaFRlcm1zLm5leHQoJycpO1wiPlxuICAgICAgPHBhdGhcbiAgICAgICAgZD1cIk0xMi4yIDlsNS42LTUuNmMuMi0uMi4yLS42IDAtLjhMMTUuNC4yYy0uMi0uMi0uNi0uMi0uOCAwTDkgNS44IDMuNC4yYy0uMi0uMi0uNi0uMi0uOCAwTC4yIDIuNWMtLjIuMi0uMi42IDAgLjhMNS44IDkgLjIgMTQuNmMtLjIuMi0uMi42IDAgLjhsMi40IDIuNGMuMi4yLjYuMi44IDBMOSAxMi4ybDUuNiA1LjZjLjIuMi42LjIuOCAwbDIuNC0yLjRjLjItLjIuMi0uNiAwLS44TDEyLjIgOXpcIj48L3BhdGg+XG4gICAgPC9zdmc+XG4gICAgPG5nLXRlbXBsYXRlICNxdWVyeUljb24+XG4gICAgICA8c3ZnIHZpZXdCb3g9XCIwIDAgNTk0LjU3MyA1OTQuMTA3XCIgY2xhc3M9XCJpY29uIHNtYWxsXCIgKGNsaWNrKT1cInNlYXJjaEJveC5mb2N1cygpXCI+XG4gICAgICAgIDxwYXRoXG4gICAgICAgICAgZD1cIk0yMzQuNTEzIDQxMS4xNzljLTk2Ljc4NS0uNjIyLTE3NS4wMjctNzkuODc4LTE3NC40MTYtMTc2LjY3LjYyLTk2LjE3MiA3OS4zNTItMTc0LjQxNiAxNzUuNS0xNzQuNDIxbDEuMTc0LjAwM2M0Ni44ODkuMjk0IDkwLjg1NyAxOC44MzIgMTIzLjggNTIuMTk4IDMyLjk0IDMzLjM2NyA1MC45MTggNzcuNTcgNTAuNjE2IDEyNC40NjgtLjI5NiA0Ni42ODctMTguNzAzIDkwLjUyNC01MS44MjMgMTIzLjQyLTMzLjExMiAzMi44OTQtNzcuMDQgNTEuMDAzLTEyMy42OSA1MS4wMDN6bTM1MS45NDIgODkuNTEzbC0zLjU4OC0zLjU4NS4wMDgtLjAwMy0xNDMuMzUyLTE0My4zNjNjMTkuOTE3LTM0LjMxMiAzMS40ODgtNzQuMDg2IDMxLjc2LTExNi42MDFDNDcyLjExNyAxMDYuOTg3IDM2Ny4yOTYuODE2IDIzNy4xNTItLjAwM2MtLjUyNS0uMDAyLTEuMDM1LS4wMDItMS41NTctLjAwMkMxMDYuMTggMCAuODM4IDEwNC41MTYuMDA1IDIzNC4xMjUtLjgyIDM2NC4yNzEgMTA0LjAwMyA0NzAuNDQgMjM0LjEzMyA0NzEuMjcxYy41MTkuMDAyIDEuMDIyLjAwNSAxLjU0LjAwNSA0My4yNTggMCA4My43OTUtMTEuNzIgMTE4LjY2NC0zMi4xbDE0My4yMjYgMTQzLjI0MS4wMTMtLjAxMiAzLjU4MSAzLjU4YzEwLjgzNCAxMC44MzIgMjguMzkxIDEwLjgyMyAzOS4yMTkgMGw0Ni4wNzktNDYuMDcyYzEwLjgyMi0xMC44MjIgMTAuODI5LTI4LjM5IDAtMzkuMjJcIj48L3BhdGg+XG4gICAgICA8L3N2Zz5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L2hlYWRlcj5cblxuICA8dWwgY2xhc3M9XCJsaXN0XCI+XG4gICAgPGxpICpuZ0Zvcj1cImxldCBpdGVtIG9mIGRpc3BsYXlJdGVtcztpbmRleCBhcyBpO3RyYWNrQnk6dHJhY2tCeUlkXCIgKGNsaWNrKT1cImNsaWNrSXRlbShpdGVtLGkpXCJcbiAgICAgICAgW2NsYXNzLnNlbGVjdGVkXT1cIml0ZW0gPT09IHNlbGVjdGVkSXRlbVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInRpdGxlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLmljb24gZWxzZSBkZWZhdWx0SXRlbUljb25cIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaWNvblwiIFtpbm5lckhUTUxdPVwiaWNvbkhUTUwoaXRlbS5pY29uKVwiPjwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0SXRlbUljb24+XG4gICAgICAgICAgPHN2ZyBjbGFzcz1cImljb25cIiB2aWV3Qm94PVwiMCAtOTYwIDk2MCA5NjBcIj5cbiAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgIGQ9XCJNNDgwLjI3Ni05NlE0MDEtOTYgMzMxLTEyNnEtNzAtMzAtMTIyLjUtODIuNVQxMjYtMzMwLjk1OHEtMzAtNjkuOTU5LTMwLTE0OS41UTk2LTU2MCAxMjYtNjI5LjV0ODIuNS0xMjJRMjYxLTgwNCAzMzAuOTU4LTgzNHE2OS45NTktMzAgMTQ5LjUtMzBRNTYwLTg2NCA2MjkuNS04MzR0MTIyIDgyLjVRODA0LTY5OSA4MzQtNjI5LjI3NnEzMCA2OS43MjUgMzAgMTQ5UTg2NC00MDEgODM0LTMzMXEtMzAgNzAtODIuNSAxMjIuNVQ2MjkuMjc2LTEyNnEtNjkuNzI1IDMwLTE0OSAzMFpcIi8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj57eyBpdGVtLnRpdGxlIH19PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgICA8c3ZnIGNsYXNzPVwic21hbGwgaWNvblwiIHZpZXdCb3g9XCIwIDAgMTQuMiAyMVwiXG4gICAgICAgICAgICpuZ0lmPVwiKGl0ZW0uY2hpbGRyZW4gJiYgaXRlbS5jaGlsZHJlbi5sZW5ndGggPiAwKVwiPlxuICAgICAgICA8cGF0aCBkPVwiTTE0LjIgMTAuNUwzLjcgMCAwIDMuN2w2LjggNi44TDAgMTcuMyAzLjcgMjF6XCI+PC9wYXRoPlxuICAgICAgPC9zdmc+XG4gICAgPC9saT5cbiAgPC91bD5cblxuICA8ZGl2IGNsYXNzPVwiZG9jXCIgKm5nSWY9XCJzaG93RG9jUGFuZWxcIj5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=