carbon-components-angular
Version:
Next generation components
657 lines • 62 kB
JavaScript
import { Component, Input, Output, EventEmitter, HostListener, HostBinding, ViewChild, ContentChildren, ViewChildren } from "@angular/core";
import { BaseTabHeader } from "./base-tab-header.component";
import { Tab } from "./tab.component";
import * as i0 from "@angular/core";
import * as i1 from "carbon-components-angular/utils";
import * as i2 from "carbon-components-angular/i18n";
import * as i3 from "@angular/common";
import * as i4 from "carbon-components-angular/tooltip";
/**
* The `TabHeaders` component contains the `Tab` items and controls scroll functionality
* if content has overflow.
*/
export class TabHeaders extends BaseTabHeader {
constructor(elementRef, changeDetectorRef, eventService, renderer, i18n) {
super(elementRef, changeDetectorRef, eventService, renderer);
this.elementRef = elementRef;
this.changeDetectorRef = changeDetectorRef;
this.eventService = eventService;
this.renderer = renderer;
this.i18n = i18n;
/**
* i18n strings for overflow controls and the tab list `aria-label` fallback.
*/
this.translations = this.i18n.get().TABS;
/**
* Emits when a tab close control is used (with `dismissable`).
* The emitted value is the tab index.
*/
this.tabClose = new EventEmitter();
/**
* The index of the first visible tab.
*/
this.firstVisibleTab = 0;
/**
* Focused tab index when `followFocus` is false (manual activation).
*/
this.activeIndex = null;
}
get tallClass() {
return this.hasSecondaryLabelTabs;
}
get fullWidthClass() {
return this.distributeWidth;
}
get hasSecondaryLabelTabs() {
if (!this.tabs || this.type !== "contained") {
return false;
}
return this.tabs.toArray().some(tab => typeof tab.secondaryLabel !== "undefined" && tab.secondaryLabel !== null);
}
/**
* True when `fullWidth` applies (contained, fewer than 9 tabs).
*/
get distributeWidth() {
return (this.fullWidth &&
this.type === "contained" &&
(this.tabs ? this.tabs.length < 9 : false));
}
// keyboard accessibility
/**
* Controls the keydown events used for tabbing through the headings.
*/
keyboardInput(event) {
const tabsArray = this.tabs.toArray();
const enabledTabs = tabsArray.filter(tab => !tab.disabled);
if (enabledTabs.length === 0) {
return;
}
const referenceIndex = this.followFocus ?
this.currentSelectedTab :
(this.activeIndex !== null ? this.activeIndex : this.currentSelectedTab);
const currentEnabledIndex = Math.max(0, enabledTabs.indexOf(tabsArray[referenceIndex]));
let nextEnabledIndex = currentEnabledIndex;
let handled = false;
if (event.key === "ArrowRight") {
nextEnabledIndex = (currentEnabledIndex + 1) % enabledTabs.length;
handled = true;
}
else if (event.key === "ArrowLeft") {
nextEnabledIndex = (enabledTabs.length + currentEnabledIndex - 1) % enabledTabs.length;
handled = true;
}
else if (event.key === "Home") {
nextEnabledIndex = 0;
handled = true;
}
else if (event.key === "End") {
nextEnabledIndex = enabledTabs.length - 1;
handled = true;
}
if (handled) {
event.preventDefault();
const nextTab = enabledTabs[nextEnabledIndex];
const nextIndex = tabsArray.indexOf(nextTab);
if (this.followFocus) {
this.selectTab(this.allTabHeaders.toArray()[nextIndex].nativeElement, nextTab, nextIndex);
}
else {
this.activeIndex = nextIndex;
}
this.allTabHeaders.toArray()[nextIndex].nativeElement.focus();
return;
}
if ((event.key === " " || event.key === "Spacebar") && !this.followFocus) {
const focusIndex = this.activeIndex !== null ? this.activeIndex : this.currentSelectedTab;
this.selectTab(this.allTabHeaders.toArray()[focusIndex].nativeElement, tabsArray[focusIndex], focusIndex);
}
}
handleBlur(event) {
const relatedTarget = event.relatedTarget;
const container = this.headerContainer?.nativeElement;
if (container && relatedTarget && container.contains(relatedTarget)) {
return;
}
// Reset active index to selected tab index when followFocus is false
if (!this.followFocus) {
this.activeIndex = this.currentSelectedTab;
}
}
/**
* `Delete` closes dismissable tabs.
*/
handleTabKeyDown(event, tab, index) {
if (this.dismissable && event.key === "Delete") {
this.handleClose(event, tab, index);
}
}
ngOnInit() {
// Update scroll on resize
this.resizeObserver = new ResizeObserver(() => {
// Need to explicitly trigger change detection since this runs outside Angular zone
this.changeDetectorRef.detectChanges();
});
this.resizeObserver.observe(this.headerContainer.nativeElement);
}
ngOnDestroy() {
this.resizeObserver?.unobserve(this.headerContainer.nativeElement);
clearTimeout(this.scrollDebounceTimer);
}
ngAfterContentInit() {
if (!this.tabInput) {
this.tabs = this.tabQuery;
}
else {
this.tabs = this.tabInput;
}
this.tabs.forEach(tab => tab.cacheActive = this.cacheActive);
this.tabs.changes.subscribe(() => {
this.setFirstTab();
this.changeDetectorRef.markForCheck();
});
this.setFirstTab();
}
ngOnChanges(changes) {
if (this.tabs && changes.cacheActive) {
this.tabs.forEach(tab => tab.cacheActive = this.cacheActive);
}
}
/**
* Controls manually focusing tabs.
*/
onTabFocus(ref, index) {
if (this.followFocus) {
this.currentSelectedTab = index;
}
else {
this.activeIndex = index;
}
// reset scroll left because we're already handling it
this.headerContainer.nativeElement.parentElement.scrollLeft = 0;
if (this.scrollIntoView) {
this.scrollTabIntoView(this.allTabHeaders.toArray()[index]?.nativeElement);
}
}
getSelectedTab() {
const selected = this.tabs.find(tab => tab.active);
if (selected) {
return selected;
}
return { headingIsTemplate: false, heading: "" };
}
/**
* Selects `Tab` 'tab' and moves it into view on the view DOM if it is not already.
*/
selectTab(ref, tab, tabIndex) {
if (tab.disabled) {
return;
}
this.currentSelectedTab = tabIndex;
this.activeIndex = tabIndex;
this.tabs.forEach(_tab => _tab.active = false);
tab.active = true;
tab.doSelect();
if (this.scrollIntoView) {
this.scrollTabIntoView(this.allTabHeaders.toArray()[tabIndex]?.nativeElement);
}
}
/**
* Emit close index and move focus to a nearby enabled tab.
*/
handleClose(event, tab, tabIndex) {
event.stopPropagation();
if (tab.disabled) {
return;
}
tab.tabClose.emit();
this.tabClose.emit(tabIndex);
// Move focus to a neighboring enabled tab (next-then-previous).
const headers = this.allTabHeaders?.toArray() ?? [];
const findNextEnabled = (start, step) => {
let i = start;
while (i >= 0 && i < headers.length) {
const candidate = this.tabs.toArray()[i];
if (candidate && !candidate.disabled && i !== tabIndex) {
return headers[i]?.nativeElement;
}
i += step;
}
return null;
};
const nextEl = findNextEnabled(tabIndex + 1, 1) || findNextEnabled(tabIndex - 1, -1);
if (nextEl) {
nextEl.focus();
}
}
getCloseTitle(tab) {
const label = !tab.headingIsTemplate && typeof tab.heading === "string" ? ` ${tab.heading}` : "";
return `Remove${label} tab`;
}
/**
* Scroll the given tab element into view if it is not already visible.
*/
scrollTabIntoView(tabEl) {
if (!tabEl || !this.headerContainer?.nativeElement) {
return;
}
const container = this.headerContainer.nativeElement;
if (container.scrollWidth <= container.clientWidth) {
return;
}
const buttonWidth = this.OVERFLOW_BUTTON_OFFSET;
const tabWidth = tabEl.getBoundingClientRect().width;
const start = tabEl.offsetLeft;
const end = start + tabWidth;
const visibleStart = container.scrollLeft + buttonWidth;
const visibleEnd = container.scrollLeft + container.clientWidth - buttonWidth;
if (start < visibleStart) {
container.scrollLeft = start - buttonWidth;
}
else if (end > visibleEnd) {
container.scrollLeft = end + buttonWidth - container.clientWidth;
}
}
/**
* Determines which `Tab` is initially selected.
*/
setFirstTab() {
setTimeout(() => {
let firstTab = this.tabs.find(tab => tab.active);
if (!firstTab && this.tabs.first) {
firstTab = this.tabs.first;
firstTab.active = true;
}
if (firstTab) {
this.currentSelectedTab = this.tabs.toArray().indexOf(firstTab);
this.activeIndex = this.currentSelectedTab;
firstTab.doSelect();
}
});
}
}
TabHeaders.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TabHeaders, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.EventService }, { token: i0.Renderer2 }, { token: i2.I18n }], target: i0.ɵɵFactoryTarget.Component });
TabHeaders.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TabHeaders, selector: "cds-tab-headers, ibm-tab-headers", inputs: { tabInput: ["tabs", "tabInput"], translations: "translations" }, outputs: { tabClose: "tabClose" }, host: { listeners: { "keydown": "keyboardInput($event)", "blur": "handleBlur($event)" }, properties: { "class.cds--tabs--tall": "this.tallClass", "class.cds--tabs--full-width": "this.fullWidthClass" } }, queries: [{ propertyName: "tabQuery", predicate: Tab }], viewQueries: [{ propertyName: "headerContainer", first: true, predicate: ["tabList"], descendants: true, static: true }, { propertyName: "allTabHeaders", predicate: ["tabItem"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
<button
type="button"
(click)="handleOverflowNavClick(-1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(-1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--previous"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': leftOverflowNavButtonHidden
}"
[attr.aria-hidden]="leftOverflowNavButtonHidden"
[attr.tabindex]="-1"
[attr.aria-label]="translations.BUTTON_ARIA_LEFT"
[attr.title]="translations.BUTTON_ARIA_LEFT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M5 8L10 3 10.7 3.7 6.4 8 10.7 12.3 10 13z"></path>
</svg>
</button>
<div
#tabList
class="cds--tab--list"
role="tablist"
[attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL"
[attr.aria-labelledby]="ariaLabelledby || null"
(scroll)="handleScroll()">
<ng-container [ngTemplateOutlet]="contentBefore"></ng-container>
<ng-container *ngFor="let tab of tabs; let i = index;">
<cds-tooltip
*ngIf="tab.iconOnly; else inlineTabItem"
align="bottom"
[autoAlign]="true"
class="cds--icon-tooltip"
[description]="tab.iconLabel"
[enterDelayMs]="tab.enterDelayMs ?? 100"
[leaveDelayMs]="tab.leaveDelayMs ?? 300"
[isOpen]="tab.isTooltipOpen"
[disabled]="tab.disabled">
<ng-container *ngTemplateOutlet="tabItemTpl; context: { tab: tab, i: i }"></ng-container>
</cds-tooltip>
<ng-template #inlineTabItem>
<ng-container *ngTemplateOutlet="tabItemTpl; context: { tab: tab, i: i }"></ng-container>
</ng-template>
<div
*ngIf="dismissable"
class="cds--tabs__nav-item--close">
<button
type="button"
[attr.tabindex]="-1"
[attr.aria-disabled]="tab.disabled"
[attr.aria-hidden]="!(tab.active && !tab.disabled)"
[disabled]="tab.disabled"
class="cds--tabs__nav-item--close-icon"
[ngClass]="{
'cds--tabs__nav-item--close-icon--selected': tab.active,
'cds--tabs__nav-item--close-icon--disabled': tab.disabled
}"
[attr.title]="getCloseTitle(tab)"
(click)="handleClose($event, tab, i)">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 32 32"
[attr.aria-label]="tab.closeButtonAriaLabel"
[attr.aria-hidden]="!(tab.active && !tab.disabled)">
<path d="M17.4141 16L24 9.4141 22.5859 8 16 14.5859 9.4143 8 8 9.4141 14.5859 16 8 22.5859 9.4143 24 16 17.4141 22.5859 24 24 22.5859 17.4141 16z"></path>
</svg>
</button>
</div>
</ng-container>
<ng-container [ngTemplateOutlet]="contentAfter"></ng-container>
</div>
<ng-template #tabItemTpl let-tab="tab" let-i="i">
<button
#tabItem
role="tab"
[attr.aria-selected]="tab.active"
[attr.tabindex]="(tab.active?0:-1)"
[attr.aria-controls]="tab.id"
[attr.aria-disabled]="tab.disabled"
[attr.aria-label]="tab.iconOnly ? tab.iconLabel : null"
[disabled]="tab.disabled"
[ngClass]="{
'cds--tabs__nav-item--selected': tab.active,
'cds--tabs__nav-item--disabled': tab.disabled,
'cds--tabs__nav-item--icon-only': tab.iconOnly,
'cds--tabs__nav-item--icon-only__20': tab.iconOnly && iconSize === 'lg'
}"
class="cds--tabs__nav-item cds--tabs__nav-link"
type="button"
draggable="false"
id="{{tab.id}}-header"
[attr.title]="tab.iconOnly ? tab.iconLabel : (tab.title || (!tab.headingIsTemplate ? tab.heading : null))"
(focus)="onTabFocus(tabItem, i)"
(keydown)="handleTabKeyDown($event, tab, i)"
(click)="selectTab(tabItem, tab, i)">
<ng-container *ngIf="tab.iconOnly; else labeledTab">
<ng-container [ngTemplateOutlet]="tab.icon"></ng-container>
<span
*ngIf="!tab.disabled && tab.badgeIndicator"
class="cds--badge-indicator"
aria-hidden="true">
</span>
</ng-container>
<ng-template #labeledTab>
<div class="cds--tabs__nav-item-label-wrapper">
<div *ngIf="dismissable && tab.icon" class="cds--tabs__nav-item--icon-left">
<ng-container [ngTemplateOutlet]="tab.icon"></ng-container>
</div>
<span class="cds--tabs__nav-item-label">
<ng-container *ngIf="!tab.headingIsTemplate">
{{ tab.heading }}
</ng-container>
<ng-template
*ngIf="tab.headingIsTemplate"
[ngTemplateOutlet]="tab.heading"
[ngTemplateOutletContext]="{$implicit: tab.context}">
</ng-template>
</span>
<div
*ngIf="!dismissable && tab.icon"
class="cds--tabs__nav-item--icon">
<ng-container [ngTemplateOutlet]="tab.icon"></ng-container>
</div>
</div>
<div
*ngIf="hasSecondaryLabelTabs && tab.secondaryLabel"
class="cds--tabs__nav-item-secondary-label"
[attr.title]="tab.secondaryLabel">
{{ tab.secondaryLabel }}
</div>
</ng-template>
</button>
</ng-template>
<button
type="button"
(click)="handleOverflowNavClick(1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--next"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': rightOverflowNavButtonHidden
}"
[attr.aria-hidden]="rightOverflowNavButtonHidden"
[attr.tabindex]="-1"
[attr.aria-label]="translations.BUTTON_ARIA_RIGHT"
[attr.title]="translations.BUTTON_ARIA_RIGHT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M11 8L6 13 5.3 12.3 9.6 8 5.3 3.7 6 3z"></path>
</svg>
</button>
`, isInline: true, dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.Tooltip, selector: "cds-tooltip, ibm-tooltip", inputs: ["id", "enterDelayMs", "leaveDelayMs", "disabled", "description", "templateContext"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TabHeaders, decorators: [{
type: Component,
args: [{
selector: "cds-tab-headers, ibm-tab-headers",
template: `
<button
type="button"
(click)="handleOverflowNavClick(-1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(-1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--previous"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': leftOverflowNavButtonHidden
}"
[attr.aria-hidden]="leftOverflowNavButtonHidden"
[attr.tabindex]="-1"
[attr.aria-label]="translations.BUTTON_ARIA_LEFT"
[attr.title]="translations.BUTTON_ARIA_LEFT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M5 8L10 3 10.7 3.7 6.4 8 10.7 12.3 10 13z"></path>
</svg>
</button>
<div
#tabList
class="cds--tab--list"
role="tablist"
[attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL"
[attr.aria-labelledby]="ariaLabelledby || null"
(scroll)="handleScroll()">
<ng-container [ngTemplateOutlet]="contentBefore"></ng-container>
<ng-container *ngFor="let tab of tabs; let i = index;">
<cds-tooltip
*ngIf="tab.iconOnly; else inlineTabItem"
align="bottom"
[autoAlign]="true"
class="cds--icon-tooltip"
[description]="tab.iconLabel"
[enterDelayMs]="tab.enterDelayMs ?? 100"
[leaveDelayMs]="tab.leaveDelayMs ?? 300"
[isOpen]="tab.isTooltipOpen"
[disabled]="tab.disabled">
<ng-container *ngTemplateOutlet="tabItemTpl; context: { tab: tab, i: i }"></ng-container>
</cds-tooltip>
<ng-template #inlineTabItem>
<ng-container *ngTemplateOutlet="tabItemTpl; context: { tab: tab, i: i }"></ng-container>
</ng-template>
<div
*ngIf="dismissable"
class="cds--tabs__nav-item--close">
<button
type="button"
[attr.tabindex]="-1"
[attr.aria-disabled]="tab.disabled"
[attr.aria-hidden]="!(tab.active && !tab.disabled)"
[disabled]="tab.disabled"
class="cds--tabs__nav-item--close-icon"
[ngClass]="{
'cds--tabs__nav-item--close-icon--selected': tab.active,
'cds--tabs__nav-item--close-icon--disabled': tab.disabled
}"
[attr.title]="getCloseTitle(tab)"
(click)="handleClose($event, tab, i)">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 32 32"
[attr.aria-label]="tab.closeButtonAriaLabel"
[attr.aria-hidden]="!(tab.active && !tab.disabled)">
<path d="M17.4141 16L24 9.4141 22.5859 8 16 14.5859 9.4143 8 8 9.4141 14.5859 16 8 22.5859 9.4143 24 16 17.4141 22.5859 24 24 22.5859 17.4141 16z"></path>
</svg>
</button>
</div>
</ng-container>
<ng-container [ngTemplateOutlet]="contentAfter"></ng-container>
</div>
<ng-template #tabItemTpl let-tab="tab" let-i="i">
<button
#tabItem
role="tab"
[attr.aria-selected]="tab.active"
[attr.tabindex]="(tab.active?0:-1)"
[attr.aria-controls]="tab.id"
[attr.aria-disabled]="tab.disabled"
[attr.aria-label]="tab.iconOnly ? tab.iconLabel : null"
[disabled]="tab.disabled"
[ngClass]="{
'cds--tabs__nav-item--selected': tab.active,
'cds--tabs__nav-item--disabled': tab.disabled,
'cds--tabs__nav-item--icon-only': tab.iconOnly,
'cds--tabs__nav-item--icon-only__20': tab.iconOnly && iconSize === 'lg'
}"
class="cds--tabs__nav-item cds--tabs__nav-link"
type="button"
draggable="false"
id="{{tab.id}}-header"
[attr.title]="tab.iconOnly ? tab.iconLabel : (tab.title || (!tab.headingIsTemplate ? tab.heading : null))"
(focus)="onTabFocus(tabItem, i)"
(keydown)="handleTabKeyDown($event, tab, i)"
(click)="selectTab(tabItem, tab, i)">
<ng-container *ngIf="tab.iconOnly; else labeledTab">
<ng-container [ngTemplateOutlet]="tab.icon"></ng-container>
<span
*ngIf="!tab.disabled && tab.badgeIndicator"
class="cds--badge-indicator"
aria-hidden="true">
</span>
</ng-container>
<ng-template #labeledTab>
<div class="cds--tabs__nav-item-label-wrapper">
<div *ngIf="dismissable && tab.icon" class="cds--tabs__nav-item--icon-left">
<ng-container [ngTemplateOutlet]="tab.icon"></ng-container>
</div>
<span class="cds--tabs__nav-item-label">
<ng-container *ngIf="!tab.headingIsTemplate">
{{ tab.heading }}
</ng-container>
<ng-template
*ngIf="tab.headingIsTemplate"
[ngTemplateOutlet]="tab.heading"
[ngTemplateOutletContext]="{$implicit: tab.context}">
</ng-template>
</span>
<div
*ngIf="!dismissable && tab.icon"
class="cds--tabs__nav-item--icon">
<ng-container [ngTemplateOutlet]="tab.icon"></ng-container>
</div>
</div>
<div
*ngIf="hasSecondaryLabelTabs && tab.secondaryLabel"
class="cds--tabs__nav-item-secondary-label"
[attr.title]="tab.secondaryLabel">
{{ tab.secondaryLabel }}
</div>
</ng-template>
</button>
</ng-template>
<button
type="button"
(click)="handleOverflowNavClick(1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--next"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': rightOverflowNavButtonHidden
}"
[attr.aria-hidden]="rightOverflowNavButtonHidden"
[attr.tabindex]="-1"
[attr.aria-label]="translations.BUTTON_ARIA_RIGHT"
[attr.title]="translations.BUTTON_ARIA_RIGHT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M11 8L6 13 5.3 12.3 9.6 8 5.3 3.7 6 3z"></path>
</svg>
</button>
`
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.EventService }, { type: i0.Renderer2 }, { type: i2.I18n }]; }, propDecorators: { tabInput: [{
type: Input,
args: ["tabs"]
}], translations: [{
type: Input
}], tabClose: [{
type: Output
}], headerContainer: [{
type: ViewChild,
args: ["tabList", { static: true }]
}], tabQuery: [{
type: ContentChildren,
args: [Tab]
}], allTabHeaders: [{
type: ViewChildren,
args: ["tabItem"]
}], tallClass: [{
type: HostBinding,
args: ["class.cds--tabs--tall"]
}], fullWidthClass: [{
type: HostBinding,
args: ["class.cds--tabs--full-width"]
}], keyboardInput: [{
type: HostListener,
args: ["keydown", ["$event"]]
}], handleBlur: [{
type: HostListener,
args: ["blur", ["$event"]]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWhlYWRlcnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3RhYnMvdGFiLWhlYWRlcnMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTixTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osWUFBWSxFQUNaLFdBQVcsRUFDWCxTQUFTLEVBQ1QsZUFBZSxFQUVmLFlBQVksRUFRWixNQUFNLGVBQWUsQ0FBQztBQUl2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDNUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7QUFFdEM7OztHQUdHO0FBb0xILE1BQU0sT0FBTyxVQUFXLFNBQVEsYUFBYTtJQXVENUMsWUFDVyxVQUFzQixFQUN0QixpQkFBb0MsRUFDcEMsWUFBMEIsRUFDMUIsUUFBbUIsRUFDbkIsSUFBVTtRQUVwQixLQUFLLENBQUMsVUFBVSxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztRQU5uRCxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixTQUFJLEdBQUosSUFBSSxDQUFNO1FBcERyQjs7V0FFRztRQUNNLGlCQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFFN0M7OztXQUdHO1FBQ08sYUFBUSxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBY3RFOztXQUVHO1FBQ0gsb0JBQWUsR0FBRyxDQUFDLENBQUM7UUFNcEI7O1dBRUc7UUFDSCxnQkFBVyxHQUFrQixJQUFJLENBQUM7SUFvQmxDLENBQUM7SUFsQkQsSUFBMEMsU0FBUztRQUNsRCxP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QVM7Z0JBT21CLFNBQVM7c0JBQWxELFdBQVc7dUJBQUMsdUJBQXVCO2dCQUlZLGNBQWM7c0JBQTdELFdBQVc7dUJBQUMsNkJBQTZCO2dCQXVDMUMsYUFBYTtzQkFEWixZQUFZO3VCQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFtRG5DLFVBQVU7c0JBRFQsWUFBWTt1QkFBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHRDb21wb25lbnQsXG5cdFF1ZXJ5TGlzdCxcblx0SW5wdXQsXG5cdE91dHB1dCxcblx0RXZlbnRFbWl0dGVyLFxuXHRIb3N0TGlzdGVuZXIsXG5cdEhvc3RCaW5kaW5nLFxuXHRWaWV3Q2hpbGQsXG5cdENvbnRlbnRDaGlsZHJlbixcblx0QWZ0ZXJDb250ZW50SW5pdCxcblx0Vmlld0NoaWxkcmVuLFxuXHRFbGVtZW50UmVmLFxuXHRPbkNoYW5nZXMsXG5cdFNpbXBsZUNoYW5nZXMsXG5cdE9uRGVzdHJveSxcblx0T25Jbml0LFxuXHRDaGFuZ2VEZXRlY3RvclJlZixcblx0UmVuZGVyZXIyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBFdmVudFNlcnZpY2UgfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci91dGlsc1wiO1xuaW1wb3J0IHsgSTE4biB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL2kxOG5cIjtcblxuaW1wb3J0IHsgQmFzZVRhYkhlYWRlciB9IGZyb20gXCIuL2Jhc2UtdGFiLWhlYWRlci5jb21wb25lbnRcIjtcbmltcG9ydCB7IFRhYiB9IGZyb20gXCIuL3RhYi5jb21wb25lbnRcIjtcblxuLyoqXG4gKiBUaGUgYFRhYkhlYWRlcnNgIGNvbXBvbmVudCBjb250YWlucyB0aGUgYFRhYmAgaXRlbXMgYW5kIGNvbnRyb2xzIHNjcm9sbCBmdW5jdGlvbmFsaXR5XG4gKiBpZiBjb250ZW50IGhhcyBvdmVyZmxvdy5cbiAqL1xuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiBcImNkcy10YWItaGVhZGVycywgaWJtLXRhYi1oZWFkZXJzXCIsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PGJ1dHRvblxuXHRcdFx0dHlwZT1cImJ1dHRvblwiXG5cdFx0XHQoY2xpY2spPVwiaGFuZGxlT3ZlcmZsb3dOYXZDbGljaygtMSwgdGFicy5sZW5ndGgpXCJcblx0XHRcdChwb2ludGVyZG93bik9XCJoYW5kbGVPdmVyZmxvd05hdk1vdXNlRG93bigtMSlcIlxuXHRcdFx0KHBvaW50ZXJ1cCk9XCJoYW5kbGVPdmVyZmxvd05hdk1vdXNlVXAoKVwiXG5cdFx0XHQocG9pbnRlcmxlYXZlKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVyb3V0KT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdGNsYXNzPVwiY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24gY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24tLXByZXZpb3VzXCJcblx0XHRcdFtuZ0NsYXNzXT1cIntcblx0XHRcdFx0J2Nkcy0tdGFiLS1vdmVyZmxvdy1uYXYtYnV0dG9uLS1oaWRkZW4nOiBsZWZ0T3ZlcmZsb3dOYXZCdXR0b25IaWRkZW5cblx0XHRcdH1cIlxuXHRcdFx0W2F0dHIuYXJpYS1oaWRkZW5dPVwibGVmdE92ZXJmbG93TmF2QnV0dG9uSGlkZGVuXCJcblx0XHRcdFthdHRyLnRhYmluZGV4XT1cIi0xXCJcblx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwidHJhbnNsYXRpb25zLkJVVFRPTl9BUklBX0xFRlRcIlxuXHRcdFx0W2F0dHIudGl0bGVdPVwidHJhbnNsYXRpb25zLkJVVFRPTl9BUklBX0xFRlRcIj5cblx0XHRcdDxzdmdcblx0XHRcdFx0Zm9jdXNhYmxlPVwiZmFsc2VcIlxuXHRcdFx0XHRwcmVzZXJ2ZUFzcGVjdFJhdGlvPVwieE1pZFlNaWQgbWVldFwiXG5cdFx0XHRcdHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuXHRcdFx0XHRmaWxsPVwiY3VycmVudENvbG9yXCJcblx0XHRcdFx0d2lkdGg9XCIxNlwiXG5cdFx0XHRcdGhlaWdodD1cIjE2XCJcblx0XHRcdFx0dmlld0JveD1cIjAgMCAxNiAxNlwiXG5cdFx0XHRcdGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuXHRcdFx0XHQ8cGF0aCBkPVwiTTUgOEwxMCAzIDEwLjcgMy43IDYuNCA4IDEwLjcgMTIuMyAxMCAxM3pcIj48L3BhdGg+XG5cdFx0XHQ8L3N2Zz5cblx0XHQ8L2J1dHRvbj5cblx0XHQ8ZGl2XG5cdFx0XHQjdGFiTGlzdFxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRhYi0tbGlzdFwiXG5cdFx0XHRyb2xlPVwidGFibGlzdFwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbCB8fCB0cmFuc2xhdGlvbnMuSEVBREVSX0FSSUFfTEFCRUxcIlxuXHRcdFx0W2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cImFyaWFMYWJlbGxlZGJ5IHx8IG51bGxcIlxuXHRcdFx0KHNjcm9sbCk9XCJoYW5kbGVTY3JvbGwoKVwiPlxuXHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50QmVmb3JlXCI+PC9uZy1jb250YWluZXI+XG5cdFx0XHQ8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB0YWIgb2YgdGFiczsgbGV0IGkgPSBpbmRleDtcIj5cblx0XHRcdFx0PGNkcy10b29sdGlwXG5cdFx0XHRcdFx0Km5nSWY9XCJ0YWIuaWNvbk9ubHk7IGVsc2UgaW5saW5lVGFiSXRlbVwiXG5cdFx0XHRcdFx0YWxpZ249XCJib3R0b21cIlxuXHRcdFx0XHRcdFthdXRvQWxpZ25dPVwidHJ1ZVwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLWljb24tdG9vbHRpcFwiXG5cdFx0XHRcdFx0W2Rlc2NyaXB0aW9uXT1cInRhYi5pY29uTGFiZWxcIlxuXHRcdFx0XHRcdFtlbnRlckRlbGF5TXNdPVwidGFiLmVudGVyRGVsYXlNcyA/PyAxMDBcIlxuXHRcdFx0XHRcdFtsZWF2ZURlbGF5TXNdPVwidGFiLmxlYXZlRGVsYXlNcyA/PyAzMDBcIlxuXHRcdFx0XHRcdFtpc09wZW5dPVwidGFiLmlzVG9vbHRpcE9wZW5cIlxuXHRcdFx0XHRcdFtkaXNhYmxlZF09XCJ0YWIuZGlzYWJsZWRcIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGFiSXRlbVRwbDsgY29udGV4dDogeyB0YWI6IHRhYiwgaTogaSB9XCI+PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDwvY2RzLXRvb2x0aXA+XG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSAjaW5saW5lVGFiSXRlbT5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGFiSXRlbVRwbDsgY29udGV4dDogeyB0YWI6IHRhYiwgaTogaSB9XCI+PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdDxkaXZcblx0XHRcdFx0XHQqbmdJZj1cImRpc21pc3NhYmxlXCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tdGFic19fbmF2LWl0ZW0tLWNsb3NlXCI+XG5cdFx0XHRcdFx0PGJ1dHRvblxuXHRcdFx0XHRcdFx0dHlwZT1cImJ1dHRvblwiXG5cdFx0XHRcdFx0XHRbYXR0ci50YWJpbmRleF09XCItMVwiXG5cdFx0XHRcdFx0XHRbYXR0ci5hcmlhLWRpc2FibGVkXT1cInRhYi5kaXNhYmxlZFwiXG5cdFx0XHRcdFx0XHRbYXR0ci5hcmlhLWhpZGRlbl09XCIhKHRhYi5hY3RpdmUgJiYgIXRhYi5kaXNhYmxlZClcIlxuXHRcdFx0XHRcdFx0W2Rpc2FibGVkXT1cInRhYi5kaXNhYmxlZFwiXG5cdFx0XHRcdFx0XHRjbGFzcz1cImNkcy0tdGFic19fbmF2LWl0ZW0tLWNsb3NlLWljb25cIlxuXHRcdFx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdFx0XHQnY2RzLS10YWJzX19uYXYtaXRlbS0tY2xvc2UtaWNvbi0tc2VsZWN0ZWQnOiB0YWIuYWN0aXZlLFxuXHRcdFx0XHRcdFx0XHQnY2RzLS10YWJzX19uYXYtaXRlbS0tY2xvc2UtaWNvbi0tZGlzYWJsZWQnOiB0YWIuZGlzYWJsZWRcblx0XHRcdFx0XHRcdH1cIlxuXHRcdFx0XHRcdFx0W2F0dHIudGl0bGVdPVwiZ2V0Q2xvc2VUaXRsZSh0YWIpXCJcblx0XHRcdFx0XHRcdChjbGljayk9XCJoYW5kbGVDbG9zZSgkZXZlbnQsIHRhYiwgaSlcIj5cblx0XHRcdFx0XHRcdDxzdmdcblx0XHRcdFx0XHRcdFx0Zm9jdXNhYmxlPVwiZmFsc2VcIlxuXHRcdFx0XHRcdFx0XHRwcmVzZXJ2ZUFzcGVjdFJhdGlvPVwieE1pZFlNaWQgbWVldFwiXG5cdFx0XHRcdFx0XHRcdHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuXHRcdFx0XHRcdFx0XHRmaWxsPVwiY3VycmVudENvbG9yXCJcblx0XHRcdFx0XHRcdFx0d2lkdGg9XCIxNlwiXG5cdFx0XHRcdFx0XHRcdGhlaWdodD1cIjE2XCJcblx0XHRcdFx0XHRcdFx0dmlld0JveD1cIjAgMCAzMiAzMlwiXG5cdFx0XHRcdFx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwidGFiLmNsb3NlQnV0dG9uQXJpYUxhYmVsXCJcblx0XHRcdFx0XHRcdFx0W2F0dHIuYXJpYS1oaWRkZW5dPVwiISh0YWIuYWN0aXZlICYmICF0YWIuZGlzYWJsZWQpXCI+XG5cdFx0XHRcdFx0XHRcdDxwYXRoIGQ9XCJNMTcuNDE0MSAxNkwyNCA5LjQxNDEgMjIuNTg1OSA4IDE2IDE0LjU4NTkgOS40MTQzIDggOCA5LjQxNDEgMTQuNTg1OSAxNiA4IDIyLjU4NTkgOS40MTQzIDI0IDE2IDE3LjQxNDEgMjIuNTg1OSAyNCAyNCAyMi41ODU5IDE3LjQxNDEgMTZ6XCI+PC9wYXRoPlxuXHRcdFx0XHRcdFx0PC9zdmc+XG5cdFx0XHRcdFx0PC9idXR0b24+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9uZy1jb250YWluZXI+XG5cdFx0XHQ8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRlbnRBZnRlclwiPjwvbmctY29udGFpbmVyPlxuXHRcdDwvZGl2PlxuXHRcdDxuZy10ZW1wbGF0ZSAjdGFiSXRlbVRwbCBsZXQtdGFiPVwidGFiXCIgbGV0LWk9XCJpXCI+XG5cdFx0XHQ8YnV0dG9uXG5cdFx0XHRcdCN0YWJJdGVtXG5cdFx0XHRcdHJvbGU9XCJ0YWJcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLXNlbGVjdGVkXT1cInRhYi5hY3RpdmVcIlxuXHRcdFx0XHRbYXR0ci50YWJpbmRleF09XCIodGFiLmFjdGl2ZT8wOi0xKVwiXG5cdFx0XHRcdFthdHRyLmFyaWEtY29udHJvbHNdPVwidGFiLmlkXCJcblx0XHRcdFx0W2F0dHIuYXJpYS1kaXNhYmxlZF09XCJ0YWIuZGlzYWJsZWRcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cInRhYi5pY29uT25seSA/IHRhYi5pY29uTGFiZWwgOiBudWxsXCJcblx0XHRcdFx0W2Rpc2FibGVkXT1cInRhYi5kaXNhYmxlZFwiXG5cdFx0XHRcdFtuZ0NsYXNzXT1cIntcblx0XHRcdFx0XHQnY2RzLS10YWJzX19uYXYtaXRlbS0tc2VsZWN0ZWQnOiB0YWIuYWN0aXZlLFxuXHRcdFx0XHRcdCdjZHMtLXRhYnNfX25hdi1pdGVtLS1kaXNhYmxlZCc6IHRhYi5kaXNhYmxlZCxcblx0XHRcdFx0XHQnY2RzLS10YWJzX19uYXYtaXRlbS0taWNvbi1vbmx5JzogdGFiLmljb25Pbmx5LFxuXHRcdFx0XHRcdCdjZHMtLXRhYnNfX25hdi1pdGVtLS1pY29uLW9ubHlfXzIwJzogdGFiLmljb25Pbmx5ICYmIGljb25TaXplID09PSAnbGcnXG5cdFx0XHRcdH1cIlxuXHRcdFx0XHRjbGFzcz1cImNkcy0tdGFic19fbmF2LWl0ZW0gY2RzLS10YWJzX19uYXYtbGlua1wiXG5cdFx0XHRcdHR5cGU9XCJidXR0b25cIlxuXHRcdFx0XHRkcmFnZ2FibGU9XCJmYWxzZVwiXG5cdFx0XHRcdGlkPVwie3t0YWIuaWR9fS1oZWFkZXJcIlxuXHRcdFx0XHRbYXR0ci50aXRsZV09XCJ0YWIuaWNvbk9ubHkgPyB0YWIuaWNvbkxhYmVsIDogKHRhYi50aXRsZSB8fCAoIXRhYi5oZWFkaW5nSXNUZW1wbGF0ZSA/IHRhYi5oZWFkaW5nIDogbnVsbCkpXCJcblx0XHRcdFx0KGZvY3VzKT1cIm9uVGFiRm9jdXModGFiSXRlbSwgaSlcIlxuXHRcdFx0XHQoa2V5ZG93bik9XCJoYW5kbGVUYWJLZXlEb3duKCRldmVudCwgdGFiLCBpKVwiXG5cdFx0XHRcdChjbGljayk9XCJzZWxlY3RUYWIodGFiSXRlbSwgdGFiLCBpKVwiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwidGFiLmljb25Pbmx5OyBlbHNlIGxhYmVsZWRUYWJcIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInRhYi5pY29uXCI+PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdFx0PHNwYW5cblx0XHRcdFx0XHRcdCpuZ0lmPVwiIXRhYi5kaXNhYmxlZCAmJiB0YWIuYmFkZ2VJbmRpY2F0b3JcIlxuXHRcdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLWJhZGdlLWluZGljYXRvclwiXG5cdFx0XHRcdFx0XHRhcmlhLWhpZGRlbj1cInRydWVcIj5cblx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgI2xhYmVsZWRUYWI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzcz1cImNkcy0tdGFic19fbmF2LWl0ZW0tbGFiZWwtd3JhcHBlclwiPlxuXHRcdFx0XHRcdFx0PGRpdiAqbmdJZj1cImRpc21pc3NhYmxlICYmIHRhYi5pY29uXCIgY2xhc3M9XCJjZHMtLXRhYnNfX25hdi1pdGVtLS1pY29uLWxlZnRcIj5cblx0XHRcdFx0XHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJ0YWIuaWNvblwiPjwvbmctY29udGFpbmVyPlxuXHRcdFx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cImNkcy0tdGFic19fbmF2LWl0ZW0tbGFiZWxcIj5cblx0XHRcdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiF0YWIuaGVhZGluZ0lzVGVtcGxhdGVcIj5cblx0XHRcdFx0XHRcdFx0XHR7eyB0YWIuaGVhZGluZyB9fVxuXHRcdFx0XHRcdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHRcdFx0PG5nLXRlbXBsYXRlXG5cdFx0XHRcdFx0XHRcdFx0Km5nSWY9XCJ0YWIuaGVhZGluZ0lzVGVtcGxhdGVcIlxuXHRcdFx0XHRcdFx0XHRcdFtuZ1RlbXBsYXRlT3V0bGV0XT1cInRhYi5oZWFkaW5nXCJcblx0XHRcdFx0XHRcdFx0XHRbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogdGFiLmNvbnRleHR9XCI+XG5cdFx0XHRcdFx0XHRcdDwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdFx0XHQ8ZGl2XG5cdFx0XHRcdFx0XHRcdCpuZ0lmPVwiIWRpc21pc3NhYmxlICYmIHRhYi5pY29uXCJcblx0XHRcdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXRhYnNfX25hdi1pdGVtLS1pY29uXCI+XG5cdFx0XHRcdFx0XHRcdDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwidGFiLmljb25cIj48L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxkaXZcblx0XHRcdFx0XHRcdCpuZ0lmPVwiaGFzU2Vjb25kYXJ5TGFiZWxUYWJzICYmIHRhYi5zZWNvbmRhcnlMYWJlbFwiXG5cdFx0XHRcdFx0XHRjbGFzcz1cImNkcy0tdGFic19fbmF2LWl0ZW0tc2Vjb25kYXJ5LWxhYmVsXCJcblx0XHRcdFx0XHRcdFthdHRyLnRpdGxlXT1cInRhYi5zZWNvbmRhcnlMYWJlbFwiPlxuXHRcdFx0XHRcdFx0e3sgdGFiLnNlY29uZGFyeUxhYmVsIH19XG5cdFx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L2J1dHRvbj5cblx0XHQ8L25nLXRlbXBsYXRlPlxuXHRcdDxidXR0b25cblx0XHRcdHR5cGU9XCJidXR0b25cIlxuXHRcdFx0KGNsaWNrKT1cImhhbmRsZU92ZXJmbG93TmF2Q2xpY2soMSwgdGFicy5sZW5ndGgpXCJcblx0XHRcdChwb2ludGVyZG93bik9XCJoYW5kbGVPdmVyZmxvd05hdk1vdXNlRG93bigxKVwiXG5cdFx0XHQocG9pbnRlcnVwKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVybGVhdmUpPVwiaGFuZGxlT3ZlcmZsb3dOYXZNb3VzZVVwKClcIlxuXHRcdFx0KHBvaW50ZXJvdXQpPVwiaGFuZGxlT3ZlcmZsb3dOYXZNb3VzZVVwKClcIlxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRhYi0tb3ZlcmZsb3ctbmF2LWJ1dHRvbiBjZHMtLXRhYi0tb3ZlcmZsb3ctbmF2LWJ1dHRvbi0tbmV4dFwiXG5cdFx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHRcdCdjZHMtLXRhYi0tb3ZlcmZsb3ctbmF2LWJ1dHRvbi0taGlkZGVuJzogcmlnaHRPdmVyZmxvd05hdkJ1dHRvbkhpZGRlblxuXHRcdFx0fVwiXG5cdFx0XHRbYXR0ci5hcmlhLWhpZGRlbl09XCJyaWdodE92ZXJmbG93TmF2QnV0dG9uSGlkZGVuXCJcblx0XHRcdFthdHRyLnRhYmluZGV4XT1cIi0xXCJcblx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwidHJhbnNsYXRpb25zLkJVVFRPTl9BUklBX1JJR0hUXCJcblx0XHRcdFthdHRyLnRpdGxlXT1cInRyYW5zbGF0aW9ucy5CVVRUT05fQVJJQV9SSUdIVFwiPlxuXHRcdFx0PHN2Z1xuXHRcdFx0XHRmb2N1c2FibGU9XCJmYWxzZVwiXG5cdFx0XHRcdHByZXNlcnZlQXNwZWN0UmF0aW89XCJ4TWlkWU1pZCBtZWV0XCJcblx0XHRcdFx0eG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG5cdFx0XHRcdGZpbGw9XCJjdXJyZW50Q29sb3JcIlxuXHRcdFx0XHR3aWR0aD1cIjE2XCJcblx0XHRcdFx0aGVpZ2h0PVwiMTZcIlxuXHRcdFx0XHR2aWV3Qm94PVwiMCAwIDE2IDE2XCJcblx0XHRcdFx0YXJpYS1oaWRkZW49XCJ0cnVlXCI+XG5cdFx0XHRcdDxwYXRoIGQ9XCJNMTEgOEw2IDEzIDUuMyAxMi4zIDkuNiA4IDUuMyAzLjcgNiAzelwiPjwvcGF0aD5cblx0XHRcdDwvc3ZnPlxuXHRcdDwvYnV0dG9uPlxuXHRgXG59KVxuXG5leHBvcnQgY2xhc3MgVGFiSGVhZGVycyBleHRlbmRzIEJhc2VUYWJIZWFkZXIgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0IHtcblx0LyoqXG5cdCAqIExpc3Qgb2YgYFRhYmAgY29tcG9uZW50cy5cblx0ICovXG5cdC8vIGRpc2FibGUgdGhlIG5leHQgbGluZSBiZWNhdXNlIHdlIG5lZWQgdG8gcmVuYW1lIHRoZSBpbnB1dFxuXHQvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmVcblx0QElucHV0KFwidGFic1wiKSB0YWJJbnB1dDogUXVlcnlMaXN0PFRhYj47XG5cblx0LyoqXG5cdCAqIGkxOG4gc3RyaW5ncyBmb3Igb3ZlcmZsb3cgY29udHJvbHMgYW5kIHRoZSB0YWIgbGlzdCBgYXJpYS1sYWJlbGAgZmFsbGJhY2suXG5cdCAqL1xuXHRASW5wdXQoKSB0cmFuc2xhdGlvbnMgPSB0aGlzLmkxOG4uZ2V0KCkuVEFCUztcblxuXHQvKipcblx0ICogRW1pdHMgd2hlbiBhIHRhYiBjbG9zZSBjb250cm9sIGlzIHVzZWQgKHdpdGggYGRpc21pc3NhYmxlYCkuXG5cdCAqIFRoZSBlbWl0dGVkIHZhbHVlIGlzIHRoZSB0YWIgaW5kZXguXG5cdCAqL1xuXHRAT3V0cHV0KCkgdGFiQ2xvc2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIFVub3JkZXJlZCBMaXN0IGVsZW1lbnQgdGhhdCBob2xkcyB0aGUgYFRhYmAgaGVhZGluZ3MgZnJvbSB0aGUgdmlldyBET00uXG5cdCAqL1xuXHRAVmlld0NoaWxkKFwidGFiTGlzdFwiLCB7IHN0YXRpYzogdHJ1ZSB9KSBoZWFkZXJDb250YWluZXI6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXHQvKipcblx0ICogQ29udGVudENoaWxkIG9mIGFsbCB0aGUgdGFic1xuX