UNPKG

@ionic/angular

Version:

Angular specific wrappers for @ionic/core

231 lines 25.9 kB
import { Directive, ElementRef, EventEmitter, HostListener, Output, ViewChild, } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "../../providers/nav-controller"; // eslint-disable-next-line @angular-eslint/directive-class-suffix export class IonTabs { navCtrl; tabsInner; /** * Emitted before the tab view is changed. */ ionTabsWillChange = new EventEmitter(); /** * Emitted after the tab view is changed. */ ionTabsDidChange = new EventEmitter(); tabBarSlot = 'bottom'; hasTab = false; selectedTab; leavingTab; constructor(navCtrl) { this.navCtrl = navCtrl; } ngAfterViewInit() { /** * Developers must pass at least one ion-tab * inside of ion-tabs if they want to use a * basic tab-based navigation without the * history stack or URL updates associated * with the router. */ const firstTab = this.tabs.length > 0 ? this.tabs.first : undefined; if (firstTab) { this.hasTab = true; this.setActiveTab(firstTab.tab); this.tabSwitch(); } } ngAfterContentInit() { this.detectSlotChanges(); } ngAfterContentChecked() { this.detectSlotChanges(); } /** * @internal */ onStackWillChange({ enteringView, tabSwitch }) { const stackId = enteringView.stackId; if (tabSwitch && stackId !== undefined) { this.ionTabsWillChange.emit({ tab: stackId }); } } /** * @internal */ onStackDidChange({ enteringView, tabSwitch }) { const stackId = enteringView.stackId; if (tabSwitch && stackId !== undefined) { if (this.tabBar) { this.tabBar.selectedTab = stackId; } this.ionTabsDidChange.emit({ tab: stackId }); } } /** * When a tab button is clicked, there are several scenarios: * 1. If the selected tab is currently active (the tab button has been clicked * again), then it should go to the root view for that tab. * * a. Get the saved root view from the router outlet. If the saved root view * matches the tabRootUrl, set the route view to this view including the * navigation extras. * b. If the saved root view from the router outlet does * not match, navigate to the tabRootUrl. No navigation extras are * included. * * 2. If the current tab tab is not currently selected, get the last route * view from the router outlet. * * a. If the last route view exists, navigate to that view including any * navigation extras * b. If the last route view doesn't exist, then navigate * to the default tabRootUrl */ select(tabOrEvent) { const isTabString = typeof tabOrEvent === 'string'; const tab = isTabString ? tabOrEvent : tabOrEvent.detail.tab; /** * If the tabs are not using the router, then * the tab switch logic is handled by the tabs * component itself. */ if (this.hasTab) { this.setActiveTab(tab); this.tabSwitch(); return; } const alreadySelected = this.outlet.getActiveStackId() === tab; const tabRootUrl = `${this.outlet.tabsPrefix}/${tab}`; /** * If this is a nested tab, prevent the event * from bubbling otherwise the outer tabs * will respond to this event too, causing * the app to get directed to the wrong place. */ if (!isTabString) { tabOrEvent.stopPropagation(); } if (alreadySelected) { const activeStackId = this.outlet.getActiveStackId(); const activeView = this.outlet.getLastRouteView(activeStackId); // If on root tab, do not navigate to root tab again if (activeView?.url === tabRootUrl) { return; } const rootView = this.outlet.getRootView(tab); const navigationExtras = rootView && tabRootUrl === rootView.url && rootView.savedExtras; return this.navCtrl.navigateRoot(tabRootUrl, { ...navigationExtras, animated: true, animationDirection: 'back', }); } else { const lastRoute = this.outlet.getLastRouteView(tab); /** * If there is a lastRoute, goto that, otherwise goto the fallback url of the * selected tab */ const url = lastRoute?.url || tabRootUrl; const navigationExtras = lastRoute?.savedExtras; return this.navCtrl.navigateRoot(url, { ...navigationExtras, animated: true, animationDirection: 'back', }); } } setActiveTab(tab) { const tabs = this.tabs; const selectedTab = tabs.find((t) => t.tab === tab); if (!selectedTab) { console.error(`[Ionic Error]: Tab with id: "${tab}" does not exist`); return; } this.leavingTab = this.selectedTab; this.selectedTab = selectedTab; this.ionTabsWillChange.emit({ tab }); selectedTab.el.active = true; } tabSwitch() { const { selectedTab, leavingTab } = this; if (this.tabBar && selectedTab) { this.tabBar.selectedTab = selectedTab.tab; } if (leavingTab?.tab !== selectedTab?.tab) { if (leavingTab?.el) { leavingTab.el.active = false; } } if (selectedTab) { this.ionTabsDidChange.emit({ tab: selectedTab.tab }); } } getSelected() { if (this.hasTab) { return this.selectedTab?.tab; } return this.outlet.getActiveStackId(); } /** * Detects changes to the slot attribute of the tab bar. * * If the slot attribute has changed, then the tab bar * should be relocated to the new slot position. */ detectSlotChanges() { this.tabBars.forEach((tabBar) => { // el is a protected attribute from the generated component wrapper const currentSlot = tabBar.el.getAttribute('slot'); if (currentSlot !== this.tabBarSlot) { this.tabBarSlot = currentSlot; this.relocateTabBar(); } }); } /** * Relocates the tab bar to the new slot position. */ relocateTabBar() { /** * `el` is a protected attribute from the generated component wrapper. * To avoid having to manually create the wrapper for tab bar, we * cast the tab bar to any and access the protected attribute. */ const tabBar = this.tabBar.el; if (this.tabBarSlot === 'top') { /** * A tab bar with a slot of "top" should be inserted * at the top of the container. */ this.tabsInner.nativeElement.before(tabBar); } else { /** * A tab bar with a slot of "bottom" or without a slot * should be inserted at the end of the container. */ this.tabsInner.nativeElement.after(tabBar); } } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IonTabs, deps: [{ token: i1.NavController }], target: i0.ɵɵFactoryTarget.Directive }); /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: IonTabs, selector: "ion-tabs", outputs: { ionTabsWillChange: "ionTabsWillChange", ionTabsDidChange: "ionTabsDidChange" }, host: { listeners: { "ionTabButtonClick": "select($event)" } }, viewQueries: [{ propertyName: "tabsInner", first: true, predicate: ["tabsInner"], descendants: true, read: ElementRef, static: true }], ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IonTabs, decorators: [{ type: Directive, args: [{ selector: 'ion-tabs', }] }], ctorParameters: function () { return [{ type: i1.NavController }]; }, propDecorators: { tabsInner: [{ type: ViewChild, args: ['tabsInner', { read: ElementRef, static: true }] }], ionTabsWillChange: [{ type: Output }], ionTabsDidChange: [{ type: Output }], select: [{ type: HostListener, args: ['ionTabButtonClick', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2NvbW1vbi9zcmMvZGlyZWN0aXZlcy9uYXZpZ2F0aW9uL3RhYnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixNQUFNLEVBQ04sU0FBUyxHQUdWLE1BQU0sZUFBZSxDQUFDOzs7QUFTdkIsa0VBQWtFO0FBQ2xFLE1BQU0sT0FBZ0IsT0FBTztJQTJCUDtJQWpCd0MsU0FBUyxDQUE2QjtJQUVsRzs7T0FFRztJQUNPLGlCQUFpQixHQUFHLElBQUksWUFBWSxFQUFtQixDQUFDO0lBQ2xFOztPQUVHO0lBQ08sZ0JBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQW1CLENBQUM7SUFFekQsVUFBVSxHQUFHLFFBQVEsQ0FBQztJQUV0QixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ2YsV0FBVyxDQUFtQjtJQUM5QixVQUFVLENBQU87SUFFekIsWUFBb0IsT0FBc0I7UUFBdEIsWUFBTyxHQUFQLE9BQU8sQ0FBZTtJQUFHLENBQUM7SUFFOUMsZUFBZTtRQUNiOzs7Ozs7V0FNRztRQUNILE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUVwRSxJQUFJLFFBQVEsRUFBRTtZQUNaLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQ25CLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUNsQjtJQUNILENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELHFCQUFxQjtRQUNu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VnRCLE9BQU87a0JBSjVCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLFVBQVU7aUJBQ3JCO29HQVk2RCxTQUFTO3NCQUFwRSxTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFLaEQsaUJBQWlCO3NCQUExQixNQUFNO2dCQUlHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkErRVAsTUFBTTtzQkFETCxZQUFZO3VCQUFDLG1CQUFtQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50Q2hlY2tlZCxcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG4gIEFmdGVyVmlld0luaXQsXG4gIFF1ZXJ5TGlzdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE5hdkNvbnRyb2xsZXIgfSBmcm9tICcuLi8uLi9wcm92aWRlcnMvbmF2LWNvbnRyb2xsZXInO1xuXG5pbXBvcnQgeyBTdGFja0RpZENoYW5nZUV2ZW50LCBTdGFja1dpbGxDaGFuZ2VFdmVudCB9IGZyb20gJy4vc3RhY2stdXRpbHMnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdpb24tdGFicycsXG59KVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtY2xhc3Mtc3VmZml4XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgSW9uVGFicyBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIEFmdGVyQ29udGVudEluaXQsIEFmdGVyQ29udGVudENoZWNrZWQge1xuICAvKipcbiAgICogTm90ZTogVGhlc2UgbXVzdCBiZSByZWRlY2xhcmVkIG9uIGVhY2ggY2hpbGQgY2xhc3Mgc2luY2UgaXQgbmVlZHNcbiAgICogYWNjZXNzIHRvIGdlbmVyYXRlZCBjb21wb25lbnRzIHN1Y2ggYXMgSW9uUm91dGVyT3V0bGV0IGFuZCBJb25UYWJCYXIuXG4gICAqL1xuICBhYnN0cmFjdCBvdXRsZXQ6IGFueTtcbiAgYWJzdHJhY3QgdGFiQmFyOiBhbnk7XG4gIGFic3RyYWN0IHRhYkJhcnM6IFF1ZXJ5TGlzdDxhbnk+O1xuICBhYnN0cmFjdCB0YWJzOiBRdWVyeUxpc3Q8YW55PjtcblxuICBAVmlld0NoaWxkKCd0YWJzSW5uZXInLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZSB9KSB0YWJzSW5uZXI6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIC8qKlxuICAgKiBFbWl0dGVkIGJlZm9yZSB0aGUgdGFiIHZpZXcgaXMgY2hhbmdlZC5cbiAgICovXG4gIEBPdXRwdXQoKSBpb25UYWJzV2lsbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyB0YWI6IHN0cmluZyB9PigpO1xuICAvKipcbiAgICogRW1pdHRlZCBhZnRlciB0aGUgdGFiIHZpZXcgaXMgY2hhbmdlZC5cbiAgICovXG4gIEBPdXRwdXQoKSBpb25UYWJzRGlkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx7IHRhYjogc3RyaW5nIH0+KCk7XG5cbiAgcHJpdmF0ZSB0YWJCYXJTbG90ID0gJ2JvdHRvbSc7XG5cbiAgcHJpdmF0ZSBoYXNUYWIgPSBmYWxzZTtcbiAgcHJpdmF0ZSBzZWxlY3RlZFRhYj86IHsgdGFiOiBzdHJpbmcgfTtcbiAgcHJpdmF0ZSBsZWF2aW5nVGFiPzogYW55O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmF2Q3RybDogTmF2Q29udHJvbGxlcikge31cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgLyoqXG4gICAgICogRGV2ZWxvcGVycyBtdXN0IHBhc3MgYXQgbGVhc3Qgb25lIGlvbi10YWJcbiAgICAgKiBpbnNpZGUgb2YgaW9uLXRhYnMgaWYgdGhleSB3YW50IHRvIHVzZSBhXG4gICAgICogYmFzaWMgdGFiLWJhc2VkIG5hdmlnYXRpb24gd2l0aG91dCB0aGVcbiAgICAgKiBoaXN0b3J5IHN0YWNrIG9yIFVSTCB1cGRhdGVzIGFzc29jaWF0ZWRcbiAgICAgKiB3aXRoIHRoZSByb3V0ZXIuXG4gICAgICovXG4gICAgY29uc3QgZmlyc3RUYWIgPSB0aGlzLnRhYnMubGVuZ3RoID4gMCA/IHRoaXMudGFicy5maXJzdCA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChmaXJzdFRhYikge1xuICAgICAgdGhpcy5oYXNUYWIgPSB0cnVlO1xuICAgICAgdGhpcy5zZXRBY3RpdmVUYWIoZmlyc3RUYWIudGFiKTtcbiAgICAgIHRoaXMudGFiU3dpdGNoKCk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZGV0ZWN0U2xvdENoYW5nZXMoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmRldGVjdFNsb3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBvblN0YWNrV2lsbENoYW5nZSh7IGVudGVyaW5nVmlldywgdGFiU3dpdGNoIH06IFN0YWNrV2lsbENoYW5nZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qgc3RhY2tJZCA9IGVudGVyaW5nVmlldy5zdGFja0lkO1xuICAgIGlmICh0YWJTd2l0Y2ggJiYgc3RhY2tJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmlvblRhYnNXaWxsQ2hhbmdlLmVtaXQoeyB0YWI6IHN0YWNrSWQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgb25TdGFja0RpZENoYW5nZSh7IGVudGVyaW5nVmlldywgdGFiU3dpdGNoIH06IFN0YWNrRGlkQ2hhbmdlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBzdGFja0lkID0gZW50ZXJpbmdWaWV3LnN0YWNrSWQ7XG4gICAgaWYgKHRhYlN3aXRjaCAmJiBzdGFja0lkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0aGlzLnRhYkJhcikge1xuICAgICAgICB0aGlzLnRhYkJhci5zZWxlY3RlZFRhYiA9IHN0YWNrSWQ7XG4gICAgICB9XG4gICAgICB0aGlzLmlvblRhYnNEaWRDaGFuZ2UuZW1pdCh7IHRhYjogc3RhY2tJZCB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV2hlbiBhIHRhYiBidXR0b24gaXMgY2xpY2tlZCwgdGhlcmUgYXJlIHNldmVyYWwgc2NlbmFyaW9zOlxuICAgKiAxLiBJZiB0aGUgc2VsZWN0ZWQgdGFiIGlzIGN1cnJlbnRseSBhY3RpdmUgKHRoZSB0YWIgYnV0dG9uIGhhcyBiZWVuIGNsaWNrZWRcbiAgICogICAgYWdhaW4pLCB0aGVuIGl0IHNob3VsZCBnbyB0byB0aGUgcm9vdCB2aWV3IGZvciB0aGF0IHRhYi5cbiAgICpcbiAgICogICBhLiBHZXQgdGhlIHNhdmVkIHJvb3QgdmlldyBmcm9tIHRoZSByb3V0ZXIgb3V0bGV0LiBJZiB0aGUgc2F2ZWQgcm9vdCB2aWV3XG4gICAqICAgICAgbWF0Y2hlcyB0aGUgdGFiUm9vdFVybCwgc2V0IHRoZSByb3V0ZSB2aWV3IHRvIHRoaXMgdmlldyBpbmNsdWRpbmcgdGhlXG4gICAqICAgICAgbmF2aWdhdGlvbiBleHRyYXMuXG4gICAqICAgYi4gSWYgdGhlIHNhdmVkIHJvb3QgdmlldyBmcm9tIHRoZSByb3V0ZXIgb3V0bGV0IGRvZXNcbiAgICogICAgICBub3QgbWF0Y2gsIG5hdmlnYXRlIHRvIHRoZSB0YWJSb290VXJsLiBObyBuYXZpZ2F0aW9uIGV4dHJhcyBhcmVcbiAgICogICAgICBpbmNsdWRlZC5cbiAgICpcbiAgICogMi4gSWYgdGhlIGN1cnJlbnQgdGFiIHRhYiBpcyBub3QgY3VycmVudGx5IHNlbGVjdGVkLCBnZXQgdGhlIGxhc3Qgcm91dGVcbiAgICogICAgdmlldyBmcm9tIHRoZSByb3V0ZXIgb3V0bGV0LlxuICAgKlxuICAgKiAgIGEuIElmIHRoZSBsYXN0IHJvdXRlIHZpZXcgZXhpc3RzLCBuYXZpZ2F0ZSB0byB0aGF0IHZpZXcgaW5jbHVkaW5nIGFueVxuICAgKiAgICAgIG5hdmlnYXRpb24gZXh0cmFzXG4gICAqICAgYi4gSWYgdGhlIGxhc3Qgcm91dGUgdmlldyBkb2Vzbid0IGV4aXN0LCB0aGVuIG5hdmlnYXRlXG4gICAqICAgICAgdG8gdGhlIGRlZmF1bHQgdGFiUm9vdFVybFxuICAgKi9cbiAgQEhvc3RMaXN0ZW5lcignaW9uVGFiQnV0dG9uQ2xpY2snLCBbJyRldmVudCddKVxuICBzZWxlY3QodGFiT3JFdmVudDogc3RyaW5nIHwgQ3VzdG9tRXZlbnQpOiBQcm9taXNlPGJvb2xlYW4+IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBpc1RhYlN0cmluZyA9IHR5cGVvZiB0YWJPckV2ZW50ID09PSAnc3RyaW5nJztcbiAgICBjb25zdCB0YWIgPSBpc1RhYlN0cmluZyA/IHRhYk9yRXZlbnQgOiAodGFiT3JFdmVudCBhcyBDdXN0b21FdmVudCkuZGV0YWlsLnRhYjtcblxuICAgIC8qKlxuICAgICAqIElmIHRoZSB0YWJzIGFyZSBub3QgdXNpbmcgdGhlIHJvdXRlciwgdGhlblxuICAgICAqIHRoZSB0YWIgc3dpdGNoIGxvZ2ljIGlzIGhhbmRsZWQgYnkgdGhlIHRhYnNcbiAgICAgKiBjb21wb25lbnQgaXRzZWxmLlxuICAgICAqL1xuICAgIGlmICh0aGlzLmhhc1RhYikge1xuICAgICAgdGhpcy5zZXRBY3RpdmVUYWIodGFiKTtcbiAgICAgIHRoaXMudGFiU3dpdGNoKCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhbHJlYWR5U2VsZWN0ZWQgPSB0aGlzLm91dGxldC5nZXRBY3RpdmVTdGFja0lkKCkgPT09IHRhYjtcbiAgICBjb25zdCB0YWJSb290VXJsID0gYCR7dGhpcy5vdXRsZXQudGFic1ByZWZpeH0vJHt0YWJ9YDtcblxuICAgIC8qKlxuICAgICAqIElmIHRoaXMgaXMgYSBuZXN0ZWQgdGFiLCBwcmV2ZW50IHRoZSBldmVudFxuICAgICAqIGZyb20gYnViYmxpbmcgb3RoZXJ3aXNlIHRoZSBvdXRlciB0YWJzXG4gICAgICogd2lsbCByZXNwb25kIHRvIHRoaXMgZXZlbnQgdG9vLCBjYXVzaW5nXG4gICAgICogdGhlIGFwcCB0byBnZXQgZGlyZWN0ZWQgdG8gdGhlIHdyb25nIHBsYWNlLlxuICAgICAqL1xuICAgIGlmICghaXNUYWJTdHJpbmcpIHtcbiAgICAgICh0YWJPckV2ZW50IGFzIEN1c3RvbUV2ZW50KS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICBpZiAoYWxyZWFkeVNlbGVjdGVkKSB7XG4gICAgICBjb25zdCBhY3RpdmVTdGFja0lkID0gdGhpcy5vdXRsZXQuZ2V0QWN0aXZlU3RhY2tJZCgpO1xuICAgICAgY29uc3QgYWN0aXZlVmlldyA9IHRoaXMub3V0bGV0LmdldExhc3RSb3V0ZVZpZXcoYWN0aXZlU3RhY2tJZCk7XG5cbiAgICAgIC8vIElmIG9uIHJvb3QgdGFiLCBkbyBub3QgbmF2aWdhdGUgdG8gcm9vdCB0YWIgYWdhaW5cbiAgICAgIGlmIChhY3RpdmVWaWV3Py51cmwgPT09IHRhYlJvb3RVcmwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByb290VmlldyA9IHRoaXMub3V0bGV0LmdldFJvb3RWaWV3KHRhYik7XG4gICAgICBjb25zdCBuYXZpZ2F0aW9uRXh0cmFzID0gcm9vdFZpZXcgJiYgdGFiUm9vdFVybCA9PT0gcm9vdFZpZXcudXJsICYmIHJvb3RWaWV3LnNhdmVkRXh0cmFzO1xuICAgICAgcmV0dXJuIHRoaXMubmF2Q3RybC5uYXZpZ2F0ZVJvb3QodGFiUm9vdFVybCwge1xuICAgICAgICAuLi5uYXZpZ2F0aW9uRXh0cmFzLFxuICAgICAgICBhbmltYXRlZDogdHJ1ZSxcbiAgICAgICAgYW5pbWF0aW9uRGlyZWN0aW9uOiAnYmFjaycsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbGFzdFJvdXRlID0gdGhpcy5vdXRsZXQuZ2V0TGFzdFJvdXRlVmlldyh0YWIpO1xuICAgICAgLyoqXG4gICAgICAgKiBJZiB0aGVyZSBpcyBhIGxhc3RSb3V0ZSwgZ290byB0aGF0LCBvdGhlcndpc2UgZ290byB0aGUgZmFsbGJhY2sgdXJsIG9mIHRoZVxuICAgICAgICogc2VsZWN0ZWQgdGFiXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHVybCA9IGxhc3RSb3V0ZT8udXJsIHx8IHRhYlJvb3RVcmw7XG4gICAgICBjb25zdCBuYXZpZ2F0aW9uRXh0cmFzID0gbGFzdFJvdXRlPy5zYXZlZEV4dHJhcztcblxuICAgICAgcmV0dXJuIHRoaXMubmF2Q3RybC5uYXZpZ2F0ZVJvb3QodXJsLCB7XG4gICAgICAgIC4uLm5hdmlnYXRpb25FeHRyYXMsXG4gICAgICAgIGFuaW1hdGVkOiB0cnVlLFxuICAgICAgICBhbmltYXRpb25EaXJlY3Rpb246ICdiYWNrJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0QWN0aXZlVGFiKHRhYjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdGFicyA9IHRoaXMudGFicztcbiAgICBjb25zdCBzZWxlY3RlZFRhYiA9IHRhYnMuZmluZCgodDogYW55KSA9PiB0LnRhYiA9PT0gdGFiKTtcblxuICAgIGlmICghc2VsZWN0ZWRUYWIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtJb25pYyBFcnJvcl06IFRhYiB3aXRoIGlkOiBcIiR7dGFifVwiIGRvZXMgbm90IGV4aXN0YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sZWF2aW5nVGFiID0gdGhpcy5zZWxlY3RlZFRhYjtcbiAgICB0aGlzLnNlbGVjdGVkVGFiID0gc2VsZWN0ZWRUYWI7XG5cbiAgICB0aGlzLmlvblRhYnNXaWxsQ2hhbmdlLmVtaXQoeyB0YWIgfSk7XG5cbiAgICBzZWxlY3RlZFRhYi5lbC5hY3RpdmUgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSB0YWJTd2l0Y2goKTogdm9pZCB7XG4gICAgY29uc3QgeyBzZWxlY3RlZFRhYiwgbGVhdmluZ1RhYiB9ID0gdGhpcztcblxuICAgIGlmICh0aGlzLnRhYkJhciAmJiBzZWxlY3RlZFRhYikge1xuICAgICAgdGhpcy50YWJCYXIuc2VsZWN0ZWRUYWIgPSBzZWxlY3RlZFRhYi50YWI7XG4gICAgfVxuXG4gICAgaWYgKGxlYXZpbmdUYWI/LnRhYiAhPT0gc2VsZWN0ZWRUYWI/LnRhYikge1xuICAgICAgaWYgKGxlYXZpbmdUYWI/LmVsKSB7XG4gICAgICAgIGxlYXZpbmdUYWIuZWwuYWN0aXZlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlbGVjdGVkVGFiKSB7XG4gICAgICB0aGlzLmlvblRhYnNEaWRDaGFuZ2UuZW1pdCh7IHRhYjogc2VsZWN0ZWRUYWIudGFiIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldFNlbGVjdGVkKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuaGFzVGFiKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFRhYj8udGFiO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm91dGxldC5nZXRBY3RpdmVTdGFja0lkKCk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZWN0cyBjaGFuZ2VzIHRvIHRoZSBzbG90IGF0dHJpYnV0ZSBvZiB0aGUgdGFiIGJhci5cbiAgICpcbiAgICogSWYgdGhlIHNsb3QgYXR0cmlidXRlIGhhcyBjaGFuZ2VkLCB0aGVuIHRoZSB0YWIgYmFyXG4gICAqIHNob3VsZCBiZSByZWxvY2F0ZWQgdG8gdGhlIG5ldyBzbG90IHBvc2l0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBkZXRlY3RTbG90Q2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLnRhYkJhcnMuZm9yRWFjaCgodGFiQmFyOiBhbnkpID0+IHtcbiAgICAgIC8vIGVsIGlzIGEgcHJvdGVjdGVkIGF0dHJpYnV0ZSBmcm9tIHRoZSBnZW5lcmF0ZWQgY29tcG9uZW50IHdyYXBwZXJcbiAgICAgIGNvbnN0IGN1cnJlbnRTbG90ID0gdGFiQmFyLmVsLmdldEF0dHJpYnV0ZSgnc2xvdCcpO1xuXG4gICAgICBpZiAoY3VycmVudFNsb3QgIT09IHRoaXMudGFiQmFyU2xvdCkge1xuICAgICAgICB0aGlzLnRhYkJhclNsb3QgPSBjdXJyZW50U2xvdDtcbiAgICAgICAgdGhpcy5yZWxvY2F0ZVRhYkJhcigpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbG9jYXRlcyB0aGUgdGFiIGJhciB0byB0aGUgbmV3IHNsb3QgcG9zaXRpb24uXG4gICAqL1xuICBwcml2YXRlIHJlbG9jYXRlVGFiQmFyKCk6IHZvaWQge1xuICAgIC8qKlxuICAgICAqIGBlbGAgaXMgYSBwcm90ZWN0ZWQgYXR0cmlidXRlIGZyb20gdGhlIGdlbmVyYXRlZCBjb21wb25lbnQgd3JhcHBlci5cbiAgICAgKiBUbyBhdm9pZCBoYXZpbmcgdG8gbWFudWFsbHkgY3JlYXRlIHRoZSB3cmFwcGVyIGZvciB0YWIgYmFyLCB3ZVxuICAgICAqIGNhc3QgdGhlIHRhYiBiYXIgdG8gYW55IGFuZCBhY2Nlc3MgdGhlIHByb3RlY3RlZCBhdHRyaWJ1dGUuXG4gICAgICovXG4gICAgY29uc3QgdGFiQmFyID0gKHRoaXMudGFiQmFyIGFzIGFueSkuZWwgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICBpZiAodGhpcy50YWJCYXJTbG90ID09PSAndG9wJykge1xuICAgICAgLyoqXG4gICAgICAgKiBBIHRhYiBiYXIgd2l0aCBhIHNsb3Qgb2YgXCJ0b3BcIiBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgICAqIGF0IHRoZSB0b3Agb2YgdGhlIGNvbnRhaW5lci5cbiAgICAgICAqL1xuICAgICAgdGhpcy50YWJzSW5uZXIubmF0aXZlRWxlbWVudC5iZWZvcmUodGFiQmFyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqXG4gICAgICAgKiBBIHRhYiBiYXIgd2l0aCBhIHNsb3Qgb2YgXCJib3R0b21cIiBvciB3aXRob3V0IGEgc2xvdFxuICAgICAgICogc2hvdWxkIGJlIGluc2VydGVkIGF0IHRoZSBlbmQgb2YgdGhlIGNvbnRhaW5lci5cbiAgICAgICAqL1xuICAgICAgdGhpcy50YWJzSW5uZXIubmF0aXZlRWxlbWVudC5hZnRlcih0YWJCYXIpO1xuICAgIH1cbiAgfVxufVxuIl19