UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

781 lines 104 kB
import { __decorate, __metadata } from "tslib"; import { Component, ContentChild, ElementRef, EventEmitter, forwardRef, HostBinding, Inject, Injector, Input, Optional, Output, SkipSelf, ViewChild } from '@angular/core'; import { Debounce } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators'; import { Yield } from '@microsoft/windows-admin-center-sdk/core/base/decorators/yield.decorator'; import { LogLevel } from '@microsoft/windows-admin-center-sdk/core/diagnostics/log-level'; import { Logging } from '@microsoft/windows-admin-center-sdk/core/diagnostics/logging'; import { CoreBaseComponent } from '../common/base.component'; import { SME_LAYOUT_PROVIDER } from '../common/layout'; import { SplitViewResponsiveWindowManager } from './split-view-responsive-window-manager'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "../resizer/resizer.component"; const _c0 = ["*"]; const _c1 = ["paneContainer"]; const _c2 = ["contentContainer"]; function SplitViewComponent_ng_container_0_ng_container_3_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementContainer(0); } } const _c3 = function (a0) { return [a0]; }; function SplitViewComponent_ng_container_0_sme_resizer_6_Template(rf, ctx) { if (rf & 1) { const _r12 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "sme-resizer", 9); i0.ɵɵlistener("resized", function SplitViewComponent_ng_container_0_sme_resizer_6_Template_sme_resizer_resized_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r11 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r11.onResized($event)); }); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r9 = i0.ɵɵnextContext(2); i0.ɵɵclassProp("sme-focus-zone", ctx_r9.isExpanded); i0.ɵɵproperty("tabindex", i0.ɵɵpureFunction1(4, _c3, ctx_r9.isExpanded ? 0 : null))("orientation", ctx_r9.orientationResponsiveWindow); } } function SplitViewComponent_ng_container_0_ng_container_7_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementContainer(0); } } function SplitViewComponent_ng_container_0_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementContainerStart(0); i0.ɵɵelementStart(1, "section", 3, 4); i0.ɵɵtemplate(3, SplitViewComponent_ng_container_0_ng_container_3_Template, 1, 0, "ng-container", 5); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "section", 6, 7); i0.ɵɵtemplate(6, SplitViewComponent_ng_container_0_sme_resizer_6_Template, 1, 6, "sme-resizer", 8); i0.ɵɵtemplate(7, SplitViewComponent_ng_container_0_ng_container_7_Template, 1, 0, "ng-container", 5); i0.ɵɵelementEnd(); i0.ɵɵelementContainerEnd(); } if (rf & 2) { const ctx_r0 = i0.ɵɵnextContext(); const _r2 = i0.ɵɵreference(3); const _r4 = i0.ɵɵreference(5); i0.ɵɵadvance(1); i0.ɵɵclassProp("sme-arrange-overflow-auto", ctx_r0.showScrollbar); i0.ɵɵadvance(2); i0.ɵɵproperty("ngTemplateOutlet", _r2); i0.ɵɵadvance(1); i0.ɵɵclassProp("sme-layout-none", ctx_r0.hideSplitViewPane)("sme-border-left-sm", ctx_r0.showSplitterBorder && ctx_r0.orientationResponsiveWindow === "right")("sme-border-top-sm", ctx_r0.showSplitterBorder && ctx_r0.orientationResponsiveWindow === "bottom")("sme-arrange-overflow-auto", ctx_r0.showScrollbar); i0.ɵɵadvance(2); i0.ɵɵproperty("ngIf", ctx_r0.isExpanded); i0.ɵɵadvance(1); i0.ɵɵproperty("ngTemplateOutlet", _r4); } } function SplitViewComponent_ng_container_1_ng_container_3_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementContainer(0); } } function SplitViewComponent_ng_container_1_sme_resizer_4_Template(rf, ctx) { if (rf & 1) { const _r19 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "sme-resizer", 9); i0.ɵɵlistener("resized", function SplitViewComponent_ng_container_1_sme_resizer_4_Template_sme_resizer_resized_0_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r18 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r18.onResized($event)); }); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r15 = i0.ɵɵnextContext(2); i0.ɵɵclassProp("sme-focus-zone", ctx_r15.isExpanded); i0.ɵɵproperty("tabindex", i0.ɵɵpureFunction1(5, _c3, ctx_r15.isExpanded ? 0 : null))("orientation", ctx_r15.orientationResponsiveWindow); i0.ɵɵattribute("aria-valuenow", ctx_r15.getAriaValueNow()); } } function SplitViewComponent_ng_container_1_ng_container_7_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementContainer(0); } } function SplitViewComponent_ng_container_1_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementContainerStart(0); i0.ɵɵelementStart(1, "section", 6, 7); i0.ɵɵtemplate(3, SplitViewComponent_ng_container_1_ng_container_3_Template, 1, 0, "ng-container", 5); i0.ɵɵtemplate(4, SplitViewComponent_ng_container_1_sme_resizer_4_Template, 1, 7, "sme-resizer", 8); i0.ɵɵelementEnd(); i0.ɵɵelementStart(5, "section", 3, 4); i0.ɵɵtemplate(7, SplitViewComponent_ng_container_1_ng_container_7_Template, 1, 0, "ng-container", 5); i0.ɵɵelementEnd(); i0.ɵɵelementContainerEnd(); } if (rf & 2) { const ctx_r1 = i0.ɵɵnextContext(); const _r4 = i0.ɵɵreference(5); const _r2 = i0.ɵɵreference(3); i0.ɵɵadvance(1); i0.ɵɵclassProp("sme-layout-none", ctx_r1.hideSplitViewPane)("sme-border-right-sm", ctx_r1.showSplitterBorder && ctx_r1.orientationResponsiveWindow === "left")("sme-border-bottom-sm", ctx_r1.showSplitterBorder && ctx_r1.orientationResponsiveWindow === "top")("sme-arrange-overflow-auto", ctx_r1.showScrollbar); i0.ɵɵadvance(2); i0.ɵɵproperty("ngTemplateOutlet", _r4); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx_r1.isExpanded); i0.ɵɵadvance(1); i0.ɵɵclassProp("sme-arrange-overflow-auto", ctx_r1.showScrollbar); i0.ɵɵadvance(2); i0.ɵɵproperty("ngTemplateOutlet", _r2); } } function SplitViewComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojection(0); } } function SplitViewComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojection(0, 1); } } const _c4 = [[["sme-split-view-content"]], [["sme-split-view-pane"]]]; const _c5 = ["sme-split-view-content", "sme-split-view-pane"]; /** * The component definition of the split view content. */ export class SplitViewContentComponent { } /** @nocollapse */ SplitViewContentComponent.ɵfac = function SplitViewContentComponent_Factory(t) { return new (t || SplitViewContentComponent)(); }; /** @nocollapse */ SplitViewContentComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SplitViewContentComponent, selectors: [["sme-split-view-content"]], ngContentSelectors: _c0, decls: 1, vars: 0, template: function SplitViewContentComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojectionDef(); i0.ɵɵprojection(0); } }, encapsulation: 2 }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SplitViewContentComponent, [{ type: Component, args: [{ selector: 'sme-split-view-content', template: '<ng-content></ng-content>' }] }], null, null); })(); /** * The component definition of the split view pane. */ export class SplitViewPaneComponent { } /** @nocollapse */ SplitViewPaneComponent.ɵfac = function SplitViewPaneComponent_Factory(t) { return new (t || SplitViewPaneComponent)(); }; /** @nocollapse */ SplitViewPaneComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SplitViewPaneComponent, selectors: [["sme-split-view-pane"]], ngContentSelectors: _c0, decls: 1, vars: 0, template: function SplitViewPaneComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojectionDef(); i0.ɵɵprojection(0); } }, encapsulation: 2 }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SplitViewPaneComponent, [{ type: Component, args: [{ selector: 'sme-split-view-pane', template: '<ng-content></ng-content>' }] }], null, null); })(); /** * The component definition of the split view. */ export class SplitViewComponent extends CoreBaseComponent { constructor(injector, elementReference, layout) { super(injector); this.elementReference = elementReference; /** * Container for active subscriptions that should be cleaned up in the OnDestroy call. */ this.subscriptions = []; /** * It defines whether the pane distance value is set. * It will not set it twice if set because only need to remember the initial value. */ this.isPaneDistanceSet = false; /** * It defines whether the split view has been expanded. */ this.internalIsExpanded = false; /** * Defines whether the split view component has been initialized. */ this.isComponentInitialized = false; /** * The orientation of the pane. */ this.internalOrientation = 'bottom'; /** * It implements the ILayout interface. It's triggered when the layout is changed. * It's used to tell the child components to coordinate with the layout change. */ this.layoutChanged = new EventEmitter(); /** * Implementation of the Layout interface */ this.windowBreakpointChanged = new EventEmitter(); /** * It indicates whether to show the scrollbar when it's needed. */ this.showScrollbar = false; /** * It indicates whether to show the border for the splitter. */ this.showSplitterBorder = true; /** * Set this to true means on smaller window, will respect the original pane value * It is not suggested to be used other than the shell side nav bar. */ this.disablePaneDistanceResponsiveWindow = false; /** * Set to true to disable the resize margin to go window responsive. */ this.disabledResizeMarginResponsiveWindow = false; /** * It indicates the min value of the pane size. */ this.resizeLowerMargin = 100; /** * It indicates the min value of the content size. */ this.resizeUpperMargin = 100; /** * Set this to true to disable the orientation change on window size change. */ this.disableOrientationResponsiveWindow = false; /** * Hides the split view pane */ this.hideSplitViewPane = false; /** * Remember the previous window responsive value for orientation for the on orientation changed event. */ this.previousOrientationResponsiveWindow = 'bottom'; /** * The event fired when the pane's expanded state is being toggled. */ this.paneToggling = new EventEmitter(); /** * The event fired when the pane's expanded state has been toggled. */ this.paneToggled = new EventEmitter(); if (layout) { this.splitViewResponsiveWindowManager = new SplitViewResponsiveWindowManager(layout); // on parent layout changes, re-emit the layout change to our event this.subscriptions.push(layout.layoutChanged.subscribe((() => this.onParentLayoutChanged()))); // on window break point changes, emit the event about critical classes and styling updates signal. this.subscriptions.push(layout.windowBreakpointChanged.subscribe(() => this.onWindowBreakpointChanged())); this.deferredOnLayoutChanged(); } } /** * The source name to use for logging */ get logSourceName() { return 'SplitViewComponent'; } /** * It indicates the distance between the start and end of the pane. * It is a hardcoded value, not fully working on window responsive design. * By design, this value will not be respected on smaller screen, phone down. */ get paneDistance() { return this.internalPaneDistance; } set paneDistance(value) { if (this.internalPaneDistance === value) { return; } this.internalPaneDistance = value; if (!this.isPaneDistanceSet) { this.defaultPaneDistance = value; } this.isPaneDistanceSet = true; } /** * It defines the orientation of the element which holds the resizer in the resizing layout. */ set orientation(input) { this.internalOrientation = input; if (!this.splitViewResponsiveWindowManager) { return; } const previousOrientation = this.splitViewResponsiveWindowManager.previousOrientation; if (previousOrientation !== this.internalOrientation) { this.splitViewResponsiveWindowManager.previousOrientation = this.internalOrientation; } } /** * Getter for orientation */ get orientation() { return this.internalOrientation; } /** * Getter for the window responsive value for the orientation */ get orientationResponsiveWindow() { // If opt-out, should use the original orientation if (this.disableOrientationResponsiveWindow) { return this.orientation; } if (!this.splitViewResponsiveWindowManager) { return this.orientation; } else { const cur = this.splitViewResponsiveWindowManager.orientation; if (cur !== this.previousOrientationResponsiveWindow) { this.onOrientationChanged(cur); this.previousOrientationResponsiveWindow = cur; } return this.splitViewResponsiveWindowManager.orientation; } } /** * Gets the CSS classes of the component. * * TODO: setting the class this way prevent any custom class from being applied. * Change to setting class in the constructor using Renderer2 and ElementRef * * On phone down, the layout for split view can only be top and bottom, in this case, we will allow y scroll. */ get hostClass() { return 'sme-layout-absolute sme-position-inset-none sme-arrange-stack-v sme-arrange-overflow-hide'; } /** * Gets the flex direction of the component. */ get flexDirection() { switch (this.orientationResponsiveWindow) { case 'left': return 'row'; case 'top': return 'column'; case 'right': return 'row'; case 'bottom': default: return 'column'; } } /** * Gets whether the pane has been expanded. */ get isExpanded() { return this.internalIsExpanded; } /** * Sets whether the pane has been expanded. */ set isExpanded(value) { if (value === this.internalIsExpanded) { return; } this.internalIsExpanded = value; this.paneToggling.emit({ isExpanded: this.internalIsExpanded }); this.refreshUI(); this.paneToggled.emit({ isExpanded: this.internalIsExpanded }); this.layoutChanged.emit(); } /** * The Angular ngOnInit function. */ ngOnInit() { this.isComponentInitialized = true; this.refreshUI(); } /** * The Angular ngOnDestroy function. */ ngOnDestroy() { this.subscriptions.forEach(sub => sub.unsubscribe()); } /** * The method called after content is initialized. */ ngAfterContentInit() { if (this.content == null) { Logging.log({ level: LogLevel.Error, message: `The value of 'content' is either null or undefined.`, params: { content: this.content }, source: 'SplitViewComponent.ngAfterContentInit' }); } if (this.pane == null) { Logging.log({ level: LogLevel.Error, message: `The value of 'pane' is either null or undefined.`, params: { pane: this.pane }, source: 'SplitViewComponent.ngAfterContentInit' }); } if (!this.isPaneDistanceSet) { this.resetPaneMaxSize(); } } /** * Gets the window responsive value for the pane distance. */ getPaneDistanceResponsiveWindow() { // If opt-out, should use the original pane distance. if (this.disablePaneDistanceResponsiveWindow || !this.splitViewResponsiveWindowManager) { return this.paneDistance; } return this.splitViewResponsiveWindowManager.paneDistance(this.paneDistance); } /** * Gets the window responsive value for the resizer margin. */ getSplitViewResizerMarginResponsiveWindow() { // If opt-out, should use the original margin size. if (this.disabledResizeMarginResponsiveWindow || !this.splitViewResponsiveWindowManager) { return { lower: this.resizeLowerMargin, upper: this.resizeUpperMargin }; } return this.splitViewResponsiveWindowManager.splitViewResizerMargin(this.resizeLowerMargin, this.resizeUpperMargin); } /** * The on window breakpoint changed handler. * Adding yield for component to get ElementRef after initialization. */ onWindowBreakpointChanged() { if (!this.contentContainerElement || !this.paneContainerElement) { return; } this.splitViewResponsiveWindowManager.onWindowSizeChanged(this.contentContainerElement, this.paneContainerElement); } /** * The deferred layout changed handler. */ deferredOnLayoutChanged() { this.onParentLayoutChanged(); } /** * Handles the change event coming from parent control from the layout component. */ onParentLayoutChanged() { if (!this.isComponentInitialized) { return; } if (this.isPaneDistanceSet) { this.resetPaneMaxSize(); const resizeMargin = this.getSplitViewResizerMarginResponsiveWindow(); const orientationResponsiveWindow = this.orientationResponsiveWindow; const paneContainer = this.paneContainerElement.nativeElement; if (resizeMargin.lower === undefined && resizeMargin.upper === undefined) { if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') { paneContainer.style.height = ''; paneContainer.style.width = '100%'; } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { paneContainer.style.width = ''; paneContainer.style.height = '100%'; } } else { if ((orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') && this.elementReference.nativeElement.offsetHeight) { this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetHeight - resizeMargin.upper); this.paneDistance = Math.max(this.paneDistance, resizeMargin.lower); paneContainer.style.height = this.isExpanded && this.paneDistance ? (this.paneDistance + 'px') : ''; paneContainer.style.width = '100%'; } else if ((orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') && this.elementReference.nativeElement.offsetWidth) { this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetWidth - resizeMargin.upper); this.paneDistance = Math.max(this.paneDistance, resizeMargin.lower); paneContainer.style.width = this.isExpanded && this.paneDistance ? (this.paneDistance + 'px') : ''; paneContainer.style.height = '100%'; } } } else { if (this.isExpanded) { this.setPaneMaxSize(); } } this.layoutChanged.emit(); } /** * Toggles the expanded state of the pane. */ togglePane() { this.isExpanded = !this.isExpanded; } /** * The implementation for after the control gets signal for confirmation for resize. * @param $event the event for resizing */ onResized($event) { this.resetPaneMaxSize(); const resizeMargin = this.getSplitViewResizerMarginResponsiveWindow(); const orientationResponsiveWindow = this.orientationResponsiveWindow; const paneContainer = this.paneContainerElement.nativeElement; this.isPaneDistanceSet = true; if (resizeMargin.lower === undefined && resizeMargin.upper === undefined) { if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') { paneContainer.style.height = ''; paneContainer.style.width = '100%'; } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { paneContainer.style.width = ''; paneContainer.style.height = '100%'; } } else { if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') { const resizedHeight = orientationResponsiveWindow === 'bottom' ? paneContainer.offsetHeight - $event.y : paneContainer.offsetHeight + $event.y; this.paneDistance = Math.max(resizedHeight, resizeMargin.lower); this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetHeight - resizeMargin.upper); paneContainer.style.height = this.paneDistance ? this.paneDistance + 'px' : ''; } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { const resizedWidth = orientationResponsiveWindow === 'right' ? paneContainer.offsetWidth - $event.x : paneContainer.offsetWidth + $event.x; this.paneDistance = Math.max(resizedWidth, resizeMargin.lower); this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetWidth - resizeMargin.upper); paneContainer.style.width = this.paneDistance ? this.paneDistance + 'px' : ''; } } this.layoutChanged.emit(); } /** * Gets the value for the pane's distance for accessibility purposes. * @returns number that indicates the pane's rendering value. */ getAriaValueNow() { return this.isExpanded && this.paneDistance ? Math.round(this.paneDistance) : null; } /** * Handles the orientation changed events. This usually happens on layout change behavior such as resizing the window. * This function has to be called with component initialized. * @param cur the current layout, could be top, bottom, left, right. * @returns void. */ onOrientationChanged(cur) { // Ignore if the container is not yet initialized. if (!this.isComponentInitialized || !this.paneContainerElement || !this.paneContainerElement.nativeElement) { return; } const container = this.paneContainerElement.nativeElement; if (cur === 'top' || cur === 'bottom') { container.style.width = '100%'; container.style.height = this.getPaneDistanceResponsiveWindow() + 'px'; this.paneDistance = this.defaultPaneDistance; } else if (cur === 'left' || cur === 'right') { container.style.width = this.getPaneDistanceResponsiveWindow() + 'px'; container.style.height = '100%'; } this.deferredRefreshUI(); } /** * It has to be a debounce value in between 0 - 250 to wait for children component. * Ideally should be promise implemented. */ deferredRefreshUI() { this.refreshUI(); } /** * The function to refresh the split view from UI. * @returns void */ refreshUI() { if (!this.isComponentInitialized || !this.paneContainerElement || !this.paneContainerElement.nativeElement) { return; } const paneDistanceResponsiveWindow = this.getPaneDistanceResponsiveWindow(); const orientationResponsiveWindow = this.orientationResponsiveWindow; const paneContainer = this.paneContainerElement.nativeElement; if (this.internalIsExpanded) { if (this.paneDistance) { let paneDistance = this.paneDistance > paneDistanceResponsiveWindow ? paneDistanceResponsiveWindow : this.paneDistance; // On phone-down, get rid of the scrollbar vertically. if (paneDistanceResponsiveWindow === undefined) { paneDistance = paneDistanceResponsiveWindow; } if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') { paneContainer.style.height = paneDistance ? paneDistance + 'px' : ''; paneContainer.style.width = '100%'; } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { paneContainer.style.width = paneDistance ? paneDistance + 'px' : ''; paneContainer.style.height = ''; } } } else { if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') { paneContainer.style.height = ''; } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { paneContainer.style.width = ''; } } this.setInternalPaneDistance(); } /** * Sets the pane distance that would be used for rendering the pane. * pane's height on top, bottom layout. * pane's width on left, right layout. * @returns void; */ setInternalPaneDistance() { if (!this.paneContainerElement || !this.paneContainerElement.nativeElement) { return; } if (!this.internalIsExpanded) { return; } const orientationResponsiveWindow = this.orientationResponsiveWindow; const paneContainer = this.paneContainerElement.nativeElement; if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') { this.paneDistance = paneContainer.offsetHeight; } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { this.paneDistance = paneContainer.offsetWidth; } } /** * Sets the max value that the pane can grow. * Sets pane's height value on top, bottom layout. * Sets pane's width value on left, right layout. * @returns void. */ setPaneMaxSize() { if (!this.paneContainerElement || !this.paneContainerElement.nativeElement) { return; } const resizeMargin = this.getSplitViewResizerMarginResponsiveWindow(); const orientationResponsiveWindow = this.orientationResponsiveWindow; const paneContainer = this.paneContainerElement.nativeElement; if (resizeMargin.lower === undefined && resizeMargin.upper === undefined) { if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') { paneContainer.style.minHeight = ''; paneContainer.style.maxHeight = '100%'; } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { paneContainer.style.minWidth = ''; paneContainer.style.maxWidth = '100%'; } } else { if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') { if (!this.disabledResizeMarginResponsiveWindow) { paneContainer.style.minHeight = resizeMargin.lower + 'px'; paneContainer.style.maxHeight = (this.elementReference.nativeElement.offsetHeight - resizeMargin.upper) + 'px'; } } else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') { paneContainer.style.minWidth = resizeMargin.lower + 'px'; paneContainer.style.maxWidth = (this.elementReference.nativeElement.offsetWidth - resizeMargin.upper) + 'px'; } } } /** * Resets the max value that the pane can grow. * @returns void. */ resetPaneMaxSize() { if (!this.paneContainerElement || !this.paneContainerElement.nativeElement) { return; } const paneContainer = this.paneContainerElement.nativeElement; paneContainer.style.maxWidth = ''; paneContainer.style.maxHeight = ''; } } /** @nocollapse */ SplitViewComponent.ɵfac = function SplitViewComponent_Factory(t) { return new (t || SplitViewComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(SME_LAYOUT_PROVIDER, 12)); }; /** @nocollapse */ SplitViewComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SplitViewComponent, selectors: [["sme-split-view"]], contentQueries: function SplitViewComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { i0.ɵɵcontentQuery(dirIndex, SplitViewContentComponent, 5); i0.ɵɵcontentQuery(dirIndex, SplitViewPaneComponent, 5); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.content = _t.first); i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pane = _t.first); } }, viewQuery: function SplitViewComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c1, 5); i0.ɵɵviewQuery(_c2, 5); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.paneContainerElement = _t.first); i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.contentContainerElement = _t.first); } }, hostVars: 4, hostBindings: function SplitViewComponent_HostBindings(rf, ctx) { if (rf & 2) { i0.ɵɵclassMap(ctx.hostClass); i0.ɵɵstyleProp("flex-direction", ctx.flexDirection); } }, inputs: { showScrollbar: "showScrollbar", showSplitterBorder: "showSplitterBorder", disablePaneDistanceResponsiveWindow: "disablePaneDistanceResponsiveWindow", paneDistance: "paneDistance", disabledResizeMarginResponsiveWindow: "disabledResizeMarginResponsiveWindow", resizeLowerMargin: "resizeLowerMargin", resizeUpperMargin: "resizeUpperMargin", orientation: "orientation", disableOrientationResponsiveWindow: "disableOrientationResponsiveWindow", hideSplitViewPane: "hideSplitViewPane", isExpanded: "isExpanded" }, outputs: { layoutChanged: "layoutChanged", windowBreakpointChanged: "windowBreakpointChanged", paneToggling: "paneToggling", paneToggled: "paneToggled" }, features: [i0.ɵɵProvidersFeature([ { provide: SME_LAYOUT_PROVIDER, useExisting: forwardRef((() => SplitViewComponent)) } ]), i0.ɵɵInheritDefinitionFeature], ngContentSelectors: _c5, decls: 6, vars: 2, consts: [[4, "ngIf"], ["content", ""], ["pane", ""], [1, "sme-layout-relative", "sme-position-flex-auto"], ["contentContainer", ""], [4, "ngTemplateOutlet"], [1, "sme-layout-relative", "sme-position-flex-none", "sme-border-color-base-80"], ["paneContainer", ""], ["class", "sme-layout-hide-phone-down", "resizerHostSelector", "sme-split-view", 3, "tabindex", "sme-focus-zone", "orientation", "resized", 4, "ngIf"], ["resizerHostSelector", "sme-split-view", 1, "sme-layout-hide-phone-down", 3, "tabindex", "orientation", "resized"]], template: function SplitViewComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojectionDef(_c4); i0.ɵɵtemplate(0, SplitViewComponent_ng_container_0_Template, 8, 13, "ng-container", 0); i0.ɵɵtemplate(1, SplitViewComponent_ng_container_1_Template, 8, 13, "ng-container", 0); i0.ɵɵtemplate(2, SplitViewComponent_ng_template_2_Template, 1, 0, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor); i0.ɵɵtemplate(4, SplitViewComponent_ng_template_4_Template, 1, 0, "ng-template", null, 2, i0.ɵɵtemplateRefExtractor); } if (rf & 2) { i0.ɵɵproperty("ngIf", ctx.orientationResponsiveWindow === "bottom" || ctx.orientationResponsiveWindow === "right"); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx.orientationResponsiveWindow === "top" || ctx.orientationResponsiveWindow === "left"); } }, dependencies: [i1.NgIf, i1.NgTemplateOutlet, i2.ResizerComponent], encapsulation: 2 }); __decorate([ Yield(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], SplitViewComponent.prototype, "onWindowBreakpointChanged", null); __decorate([ Debounce(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], SplitViewComponent.prototype, "deferredOnLayoutChanged", null); __decorate([ Debounce(10), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], SplitViewComponent.prototype, "deferredRefreshUI", null); __decorate([ Debounce(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], SplitViewComponent.prototype, "setInternalPaneDistance", null); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SplitViewComponent, [{ type: Component, args: [{ selector: 'sme-split-view', providers: [ { provide: SME_LAYOUT_PROVIDER, useExisting: forwardRef((() => SplitViewComponent)) } ], template: "<ng-container *ngIf=\"orientationResponsiveWindow==='bottom' || orientationResponsiveWindow==='right'\">\r\n <section #contentContainer class=\"sme-layout-relative sme-position-flex-auto\" [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n </section>\r\n <section #paneContainer [class.sme-layout-none]=\"hideSplitViewPane\"\r\n class=\"sme-layout-relative sme-position-flex-none sme-border-color-base-80\"\r\n [class.sme-border-left-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'right'\"\r\n [class.sme-border-top-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'bottom'\"\r\n [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <!-- TODO: hide resizer on phone down temporarily, needs special design -->\r\n <sme-resizer *ngIf=\"isExpanded\" class=\"sme-layout-hide-phone-down\" [tabindex]=\"[isExpanded?0:null]\"\r\n [class.sme-focus-zone]=\"isExpanded\" resizerHostSelector=\"sme-split-view\"\r\n (resized)=\"onResized($event)\" [orientation]=\"orientationResponsiveWindow\">\r\n </sme-resizer>\r\n <ng-container *ngTemplateOutlet=\"pane\"></ng-container>\r\n </section>\r\n</ng-container>\r\n<ng-container *ngIf=\"orientationResponsiveWindow==='top' || orientationResponsiveWindow==='left'\">\r\n <section #paneContainer [class.sme-layout-none]=\"hideSplitViewPane\"\r\n class=\"sme-layout-relative sme-position-flex-none sme-border-color-base-80\"\r\n [class.sme-border-right-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'left'\"\r\n [class.sme-border-bottom-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'top'\"\r\n [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <ng-container *ngTemplateOutlet=\"pane\"></ng-container>\r\n <!-- TODO: hide resizer on phone down temporarily, needs special design -->\r\n <sme-resizer *ngIf=\"isExpanded\" class=\"sme-layout-hide-phone-down\" [tabindex]=\"[isExpanded?0:null]\"\r\n [class.sme-focus-zone]=\"isExpanded\" resizerHostSelector=\"sme-split-view\"\r\n (resized)=\"onResized($event)\" [orientation]=\"orientationResponsiveWindow\" [attr.aria-valuenow]=\"getAriaValueNow()\">\r\n </sme-resizer>\r\n </section>\r\n <section #contentContainer class=\"sme-layout-relative sme-position-flex-auto\" [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n </section>\r\n</ng-container>\r\n\r\n<ng-template #content>\r\n <ng-content select=\"sme-split-view-content\"></ng-content>\r\n</ng-template>\r\n<ng-template #pane>\r\n <ng-content select=\"sme-split-view-pane\"></ng-content>\r\n</ng-template>\r\n<!-- The reason to use ng-template to wrap the ng-content element instead of directly to use ng-content in both two ng-containers above is:\r\nIf we use ng-content elements directly in both 2 ng-containers, there will be 2 ng-content elements with the same selector. But Angular will only\r\nresolve the first ng-content in multiple ng-content elements with same selector even the first one is in a ngIf false block.\r\nSo when the orientation is \"top\" or \"left\", no ng-content element will be resolved then nothing would render.\r\nIn order to solve this problem, we have to use ng-template to wrap the ng-content to make sure one selector maps to one ng-content.\r\nThen we use ng-container and ngTemplateOutlet to call the ng-template.\r\nThx for reading till here...... -->\r\n" }] }], function () { return [{ type: i0.Injector }, { type: i0.ElementRef }, { type: undefined, decorators: [{ type: SkipSelf }, { type: Optional }, { type: Inject, args: [SME_LAYOUT_PROVIDER] }] }]; }, { layoutChanged: [{ type: Output }], windowBreakpointChanged: [{ type: Output }], content: [{ type: ContentChild, args: [SplitViewContentComponent] }], pane: [{ type: ContentChild, args: [SplitViewPaneComponent] }], paneContainerElement: [{ type: ViewChild, args: ['paneContainer'] }], contentContainerElement: [{ type: ViewChild, args: ['contentContainer'] }], showScrollbar: [{ type: Input }], showSplitterBorder: [{ type: Input }], disablePaneDistanceResponsiveWindow: [{ type: Input }], paneDistance: [{ type: Input }], disabledResizeMarginResponsiveWindow: [{ type: Input }], resizeLowerMargin: [{ type: Input }], resizeUpperMargin: [{ type: Input }], orientation: [{ type: Input }], disableOrientationResponsiveWindow: [{ type: Input }], hideSplitViewPane: [{ type: Input }], paneToggling: [{ type: Output }], paneToggled: [{ type: Output }], hostClass: [{ type: HostBinding, args: ['class'] }], flexDirection: [{ type: HostBinding, args: ['style.flex-direction'] }], isExpanded: [{ type: Input }], onWindowBreakpointChanged: [], deferredOnLayoutChanged: [], deferredRefreshUI: [], setInternalPaneDistance: [] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BsaXQtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9jb250cm9scy9zcGxpdC12aWV3L3NwbGl0LXZpZXcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvc3BsaXQtdmlldy9zcGxpdC12aWV3LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBRUgsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsTUFBTSxFQUNOLFFBQVEsRUFDUixLQUFLLEVBR0wsUUFBUSxFQUNSLE1BQU0sRUFDTixRQUFRLEVBQ1IsU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw4RUFBOEUsQ0FBQztBQUN4RyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sMEVBQTBFLENBQUM7QUFDakcsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdFQUFnRSxDQUFDO0FBQzFGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSw4REFBOEQsQ0FBQztBQUV2RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RCxPQUFPLEVBQVUsbUJBQW1CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRCxPQUFPLEVBQTBCLGdDQUFnQyxFQUFFLE1BQU0sd0NBQXdDLENBQUM7Ozs7Ozs7O0lDdkI5Ryx3QkFBeUQ7Ozs7O0lBUXpELHNDQUU0RTtJQUExRSx3TUFBVyxlQUFBLHlCQUFpQixDQUFBLElBQUM7SUFDL0IsaUJBQWM7OztJQUZaLG1EQUFtQztJQUQ4QixtRkFBZ0MsbURBQUE7OztJQUluRyx3QkFBc0Q7OztJQWQxRCw2QkFBc0c7SUFDcEcscUNBQWdJO0lBQzlILG9HQUF5RDtJQUMzRCxpQkFBVTtJQUNWLHFDQUlvRDtJQUVsRCxrR0FHYztJQUNkLG9HQUFzRDtJQUN4RCxpQkFBVTtJQUNaLDBCQUFlOzs7OztJQWZpRSxlQUFpRDtJQUFqRCxpRUFBaUQ7SUFDOUcsZUFBeUI7SUFBekIsc0NBQXlCO0lBRWxCLGVBQTJDO0lBQTNDLDJEQUEyQyxtR0FBQSxtR0FBQSxtREFBQTtJQU1uRCxlQUFnQjtJQUFoQix3Q0FBZ0I7SUFJZixlQUFzQjtJQUF0QixzQ0FBc0I7OztJQVNyQyx3QkFBc0Q7Ozs7SUFFdEQsc0NBRXFIO0lBQW5ILHdNQUFXLGVBQUEseUJBQWlCLENBQUEsSUFBQztJQUMvQixpQkFBYzs7O0lBRlosb0RBQW1DO0lBRDhCLG9GQUFnQyxvREFBQTtJQUV2QiwwREFBd0M7OztJQUlwSCx3QkFBeUQ7OztJQWQ3RCw2QkFBa0c7SUFDaEcscUNBSW9EO0lBQ2xELG9HQUFzRDtJQUV0RCxrR0FHYztJQUNoQixpQkFBVTtJQUNWLHFDQUFnSTtJQUM5SCxvR0FBeUQ7SUFDM0QsaUJBQVU7SUFDWiwwQkFBZTs7Ozs7SUFmVyxlQUEyQztJQUEzQywyREFBMkMsbUdBQUEsbUdBQUEsbURBQUE7SUFLbEQsZUFBc0I7SUFBdEIsc0NBQXNCO0lBRXZCLGVBQWdCO0lBQWhCLHdDQUFnQjtJQUs4QyxlQUFpRDtJQUFqRCxpRUFBaUQ7SUFDOUcsZUFBeUI7SUFBekIsc0NBQXlCOzs7SUFLMUMsa0JBQXlEOzs7SUFHekQscUJBQXNEOzs7O0FEUHhEOztHQUVHO0FBS0gsTUFBTSxPQUFPLHlCQUF5Qjs7cUhBQXpCLHlCQUF5QjsyR0FBekIseUJBQXlCOztRQUZ2QixrQkFBeUI7O3VGQUUzQix5QkFBeUI7Y0FKckMsU0FBUztlQUFDO2dCQUNQLFFBQVEsRUFBRSx3QkFBd0I7Z0JBQ2xDLFFBQVEsRUFBRSwyQkFBMkI7YUFDeEM7O0FBR0Q7O0dBRUc7QUFLSCxNQUFNLE9BQU8sc0JBQXNCOzsrR0FBdEIsc0JBQXNCO3dHQUF0QixzQkFBc0I7O1FBRnBCLGtCQUF5Qjs7dUZBRTNCLHNCQUFzQjtjQUpsQyxTQUFTO2VBQUM7Z0JBQ1AsUUFBUSxFQUFFLHFCQUFxQjtnQkFDL0IsUUFBUSxFQUFFLDJCQUEyQjthQUN4Qzs7QUFHRDs7R0FFRztBQVFILE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxpQkFBaUI7SUE0TnJELFlBQWEsUUFBa0IsRUFDbkIsZ0JBQTRCLEVBQ2lCLE1BQWM7UUFFbkUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBSFIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFZO1FBck54Qzs7V0FFRztRQUNPLGtCQUFhLEdBQW1CLEVBQUUsQ0FBQztRQU83Qzs7O1dBR0c7UUFDSyxzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFRbEM7O1dBRUc7UUFDSyx1QkFBa0IsR0FBRyxLQUFLLENBQUM7UUFFbkM7O1dBRUc7UUFDSywyQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFPdkM7O1dBRUc7UUFDSyx3QkFBbUIsR0FBeUIsUUFBUSxDQUFDO1FBRTdEOzs7V0FHRztRQUVJLGtCQUFhLEdBQXVCLElBQUksWUFBWSxFQUFRLENBQUM7UUFFcEU7O1dBRUc7UUFFSSw0QkFBdUIsR0FBdUIsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQTBCOUU7O1dBRUc7UUFFSSxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUU3Qjs7V0FFRztRQUVJLHVCQUFrQixHQUFHLElBQUksQ0FBQztRQUVqQzs7O1dBR0c7UUFFSSx3Q0FBbUMsR0FBRyxLQUFLLENBQUM7UUF5Qm5EOztXQUVHO1FBRUkseUNBQW9DLEdBQUcsS0FBSyxDQUFDO1FBRXBEOztXQUVHO1FBRUksc0JBQWlCLEdBQUcsR0FBRyxDQUFDO1FBRS9COztXQUVHO1FBRUksc0JBQWlCLEdBQUcsR0FBRyxDQUFDO1FBa0IvQjs7V0FFRztRQUVJLHVDQUFrQyxHQUFHLEtBQUssQ0FBQztRQUVsRDs7V0FFRztRQUVJLHNCQUFpQixHQUFHLEtBQUssQ0FBQztRQVNqQzs7V0FFRztRQUNLLHdDQUFtQyxHQUFHLFFBQVEsQ0FBQztRQXVCdkQ7O1dBRUc7UUFFSSxpQkFBWSxHQUEwQyxJQUFJLFlBQVksRUFBMkIsQ0FBQztRQUV6Rzs7V0FFRztRQUVJLGdCQUFXLEdBQTBDLElBQUksWUFBWSxFQUEyQixDQUFDO1FBUXBHLElBQUksTUFBTSxFQUFFO1lBQ1IsSUFBSSxDQUFDLGdDQUFnQyxHQUFHLElBQUksZ0NBQWdDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDckYsbUVBQW1FO1lBQ25FLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUYsbUdBQW1HO1lBQ25HLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBRTFHLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1NBQ2xDO0lBQ0wsQ0FBQztJQTFPRDs7T0FFRztJQUNGLElBQWMsYUFBYTtRQUN4QixPQUFPLG9CQUFvQixDQUFDO0lBQ2hDLENBQUM7SUFvR0Q7Ozs7T0FJRztJQUNILElBQVcsWUFBWTtRQUNuQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztJQUNyQyxDQUFDO0lBRUQsSUFDVyxZQUFZLENBQUMsS0FBYTtRQUNqQyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxLQUFLLEVBQUU7WUFDckMsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQztRQUVsQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3pCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7U0FDcEM7UUFDRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0lBQ2xDLENBQUM7SUFvQkQ7O09BRUc7SUFDSCxJQUNXLFdBQVcsQ0FBQyxLQUEyQjtRQUM5QyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLEVBQUU7WUFDeEMsT0FBTztTQUNWO1FBRUQsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsbUJBQW1CLENBQUM7UUFDdEYsSUFBSSxtQkFBbUIsS0FBSyxJQUFJLENBQUMsbUJBQW1CLEVBQUU7WUFDbEQsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztTQUN4RjtJQUNMLENBQUM7SUFjRDs7T0FFRztJQUNILElBQVcsV0FBVztRQUNsQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztJQUNwQyxDQUFDO0lBT0Q7O09BRUc7SUFDSCxJQUFXLDJCQUEyQjtRQUNsQyxrREFBa0Q7UUFDbEQsSUFBSSxJQUFJLENBQUMsa0NBQWtDLEVBQUU7WUFDekMsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO1NBQzNCO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRTtZQUN4QyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7U0FDM0I7YUFBTTtZQUNILE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxXQUFXLENBQUM7WUFDOUQsSUFBSSxHQUFHLEtBQUssSUFBSSxDQUFDLG1DQUFtQyxFQUFFO2dCQUNsRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxtQ0FBbUMsR0FBRyxHQUFHLENBQUM7YUFDbEQ7WUFFRCxPQUFPLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxXQUFXLENBQUM7U0FDNUQ7SUFDTCxDQUFDO0lBK0JEOzs7Ozs7O09BT0c7SUFDSCxJQUNXLFNBQVM7UUFDaEIsT0FBTywyRkFBMkYsQ0FBQztJQUN2RyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUNXLGFBQWE7UUFDcEIsUUFBUSxJQUFJLENBQUMsMkJBQTJCLEVBQUU7WUFDdEMsS0FBSyxNQUFNO2dCQUNQLE9BQU8sS0FBSyxDQUFDO1lBQ2pCLEtBQUssS0FBSztnQkFDTixPQUFPLFFBQVEsQ0FBQztZQUNwQixLQUFLLE9BQU87Z0JBQ1IsT0FBTyxLQUFLLENBQUM7WUFDakIsS0FBSyxRQUFRLENBQUM7WUFDZDtnQkFDSSxPQUFPLFFBQVEsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNILElBQ1csVUFBVTtRQUNqQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFXLFVBQVUsQ0FBQyxLQUFjO1FBQ2hDLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUNuQyxPQUFPO1NBQ1Y7UUFFRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO1lBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUMsa0JBQWtCO1NBQ3RDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztZQUNsQixVQUFVLEVBQUUsSUFBSSxDQUFDLGtCQUFrQjtTQUN0QyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNJLFFBQVE7UUFDWCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxXQUFXO1FBQ2QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxrQkFBa0I7UUFDckIsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksRUFBRTtZQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDO2dCQUNSLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSztnQkFDckIsT0FBTyxFQUFFLHFEQUFxRDtnQkFDOUQsTUFBTSxFQUFFO29CQUNKLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztpQkFDeEI7Z0JBQ0QsTUFBTSxFQUFFLHVDQUF1QzthQUNsRCxDQUFDLENBQUM7U0FDTjtRQUVELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLEVBQUU7WUFDbkIsT0FBTyxDQUFDLEdBQUcsQ0FBQztnQkFDUixLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUs7Z0JBQ3JCLE9BQU8sRUFBRSxrREFBa0Q7Z0JBQzNELE1BQU0sRUFBRTtvQkFDSixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7aUJBQ2xCO2dCQUNELE1BQU0sRUFBRSx1Q0FBdUM7YUFDbEQsQ0FBQyxDQUFDO1NBQ047UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3pCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1NBQzNCO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksK0JBQStCO1FBQ2xDLHFEQUFxRDtRQUNyRCxJQUFJLElBQUksQ0FBQyxtQ0FBbUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRTtZQUNwRixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7U0FDNUI7UUFFRCxPQUFPLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ2pGLENBQUM7SUFFRDs7T0FFRztJQUNJLHlDQUF5QztRQUM1QyxtREFBbUQ7UUFDbkQsSUFBSSxJQUFJLENBQUMsb0NBQW9DLElBQUksQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLEVBQUU7WUFDckYsT0FBTztnQkFDSCxLQUFLLEVBQUUsSUFBSSxDQUFDLGlCQUFpQjtnQkFDN0IsS0FBSyxFQUFFLElBQUksQ0FBQyxpQkFBaUI7YUFDaEMsQ0FBQztTQUNMO1FBRUQsT0FBTyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsc0JBQXNCLENBQy9ELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQ7OztPQUdHO0lBRUkseUJBQXlCO1FBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLElBQUksQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUU7WUFDN0QsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN2SCxDQUFDO0lBRUQ7O09BRUc7SUFFSyx1QkFBdUI7UUFDM0IsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVEOztPQUVHO0lBQ0sscUJBQXFCO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUU7WUFDOUIsT0FBTztTQUNWO1FBRUQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDeEIsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFFeEIsTUFBTSxZQUFZLEdBQTJCLElBQUksQ0FBQyx5Q0FBeUMsRUFBRSxDQUFDO1lBQzlGLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFDLDJ