@asadi/angular-date-components
Version:
`Angular Date Components` is a comprehensive angular library of date-related components designed to meet the needs of applications that require localization based on various calendar systems. While the package currently includes two powerful components (S
121 lines • 29.3 kB
JavaScript
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, inject, Input, Output, Renderer2, ViewChild } from '@angular/core';
import { TableViewControllerDirective } from '../../directives/table-view-controller.directive';
import { ADC_OPTIONS } from '../../injection-token';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
/**
* A reusable and customizable table component for displaying date-related data.
* The `adc-table` component is designed for use within the Angular Date Components package.
* It supports features like row and column labels, custom cell event builders, and date range selection.
*
* The component allows for displaying a dynamic table with custom rows, columns, and cells.
* It supports both left-to-right (`ltr`) and right-to-left (`rtl`) layouts.
*
* ### Features
* - Dynamically updates the table view when cell data changes.
* - Supports date filtering and custom event builders for handling cell events.
* - Emits an event when a date range is selected.
*
* @example
* ```html
* <adc-table
* [Rows]="tableRows"
* [Columns]="tableColumns"
* [Cells]="tableCells"
* [Title]="'My Schedule'"
* [TitleClass]="'table-title'"
* [ShowRowLabels]="true"
* [ShowColumnLabels]="false"
* [Dir]="'ltr'"
* [DateFilter]="customDateFilter"
* [EventBuilder]="eventBuilderInstance"
* (DateRangeSelect)="onDateRangeSelect($event)">
* </adc-table>
* ```
*
* @example
* ```typescript
* // In your component class
* tableRows: ADCITableRow[] = [...];
* tableColumns: ADCITableColumn[] = [...];
* tableCells: ADCITableCell[] = [...];
*
* onDateRangeSelect(selectedCells: ADCITableCell[]) {
* console.log('Selected cells:', selectedCells);
* }
* ```
*/
export class ADCTableComponent {
constructor() {
this.options = inject(ADC_OPTIONS);
this.renderer = inject(Renderer2);
/**
* An array of rows to display in the table.
*/
this.tableRows = [];
/**
* a boolean which determines if row details should be displayed or not
*/
this.showRow = true;
/**
*
* The title displayed above the table.
*/
this.title = '';
/**
* CSS classes to apply to the title.
*/
this.titleClassList = '';
this.viewReadyEvent = new EventEmitter();
}
ngAfterViewInit() {
if (this.viewCtrl == null)
return;
if (this.eventBuilder) {
if (this.viewCtrl == null)
return;
this.eventBuilder.init(this.renderer, this.viewCtrl, this.options);
}
if (this.selectionManager) {
this.selectionManager.init(this.viewCtrl);
}
}
onViewReady() {
this.viewReadyEvent.emit();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: ADCTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.7", type: ADCTableComponent, isStandalone: true, selector: "adc-table", inputs: { tableRows: ["rows", "tableRows"], showRow: ["showRowDetails", "showRow"], title: "title", titleClassList: ["titleClass", "titleClassList"], eventBuilder: "eventBuilder", selectionManager: "selectionManager" }, outputs: { viewReadyEvent: "viewReady" }, viewQueries: [{ propertyName: "viewCtrl", first: true, predicate: TableViewControllerDirective, descendants: true }], ngImport: i0, template: "\r\n<div [dir]=\"options.direction\">\r\n\r\n <div [classList]=\"titleClassList + ' font-bold text-xl'\" style=\"border-bottom: 1px solid #000; text-align: center;\">\r\n {{title}}\r\n </div>\r\n\r\n <div style=\"max-height: 700px;overflow: scroll;\">\r\n\r\n <div style=\"flex: 1;display: flex;flex-direction: column;\" class=\"adc-table\" tableViewController (viewReady)=\"onViewReady()\">\r\n\r\n <ng-container *ngFor=\"let row of tableRows; let lastRow = last; let rowIndex = index\">\r\n \r\n <div class=\"row\" style=\"position: relative;flex-shrink: 0;\" [attr.sticky]=\"rowIndex == 0\" \r\n [class.sticky]=\"rowIndex == 0\" [class.vertical-stick]=\"rowIndex == 0\" [attr.row-index]=\"rowIndex\">\r\n \r\n <!-- cells - columns -->\r\n <div style=\"display: flex;flex-direction: row;flex-wrap: nowrap;flex: 1;height: 100%;\" cells>\r\n \r\n <ng-container *ngIf=\"showRow\">\r\n \r\n <div style=\"min-width: 100px;display: flex;flex-direction: column;overflow: hidden;\r\n padding: 6px;\" [style.justifyContent]=\"row.verticalAlign\" [style.alignItems]=\"row.horizontalAlign\"\r\n [classList]=\"row.classList + ' column column-border sticky horizontal-stick'\" detail=\"true\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\">\r\n \r\n <span class=\"label\">{{row.prefix}}</span>\r\n <span class=\"label\">{{row.label}}</span>\r\n <span class=\"label\">{{row.suffix}}</span>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n <ng-container *ngFor=\"let column of row.columns; let lastColumn = last; let columnIndex = index\">\r\n <div style=\"min-width: 50px;display: flex;flex-direction: column;overflow: hidden;\r\n white-space: nowrap;text-overflow: ellipsis;padding: 6px;flex: 1;\" [style.justifyContent]=\"column.verticalAlign\" [attr.selectable]=\"column.selectable\"\r\n [classList]=\"column.classList + ' column'\" [attr.columnValue]=\"column.value\" [style.alignItems]=\"column.horizontalAlign\"\r\n [attr.rowValue]=\"row.value\" [attr.rowIndex]=\"rowIndex\" [attr.columnIndex]=\"columnIndex\"\r\n [ngClass]=\"{'column-border': !lastColumn}\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\" detail=\"false\">\r\n \r\n <span class=\"label\">{{column.prefix}}</span>\r\n <span class=\"label\">{{column.label}}</span>\r\n <span class=\"label\">{{column.suffix}}</span>\r\n \r\n </div>\r\n </ng-container>\r\n \r\n </div>\r\n \r\n <!-- events -->\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 1;pointer-events: none;\" events></div>\r\n\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 3;pointer-events: none;\" tooltip></div>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n </div>\r\n\r\n </div>\r\n\r\n</div>\r\n", styles: ["[dir=rtl] .column-border{border-left:1px solid #000}[dir=ltr] .column-border{border-right:1px solid #000}[dir=ltr] .adc-table{transform-origin:left top}[dir=rtl] .adc-table{transform-origin:right top}.adc-table{transition:transform;transition-duration:.2s;transition-timing-function:ease-out;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smooth:always}.row .column:nth-child(2n):not(.today){background-color:#f0f0f0}.row .column:nth-child(odd):not(.today){background-color:#fff}.sticky{position:sticky!important;z-index:9}[dir=ltr] .sticky.horizontal-stick{left:0}[dir=rtl] .sticky.horizontal-stick{right:0}.sticky.vertical-stick{top:0}.today{background-color:#f7ffac}[selectable=true]:not([invalid]):hover{cursor:pointer;box-shadow:inset 0 1px 3px #00000080}[selectable=true][invalid]:hover{cursor:not-allowed}.unavailable{opacity:.5}.holiday{color:red}[dir=rtl]{text-align:right}[dir=ltr]{text-align:left}.label{white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden}[selectable=true][pointed]:not([invalid]):not([selected]){background-color:#c384ff80!important;opacity:1!important}[selectable=true][selected]:not([invalid]){background-color:#c384ff!important;opacity:1!important}[selectable=true][invalid]{background-color:#aaa!important;opacity:1!important}[dir=rtl] .table-event.event-start-day{border-top-right-radius:15px;border-bottom-right-radius:15px}[dir=ltr] .table-event.event-start-day,[dir=rtl] .table-event.event-end-day{border-top-left-radius:15px;border-bottom-left-radius:15px}[dir=ltr] .table-event.event-end-day{border-top-right-radius:15px;border-bottom-right-radius:15px}.table-event{overflow:hidden;position:absolute;display:flex;justify-content:center;align-items:center;font-weight:400;font-size:clamp(10px,14px,16px);line-height:22px;z-index:9;color:#fff;text-wrap:nowrap;pointer-events:fill}.tooltip{position:absolute;background-color:#000c;color:#fff;padding:5px 10px;border-radius:4px;pointer-events:none;white-space:nowrap;z-index:1000;overflow:hidden;max-width:350px;white-space:break-word;text-wrap:wrap;word-break:break-all}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: TableViewControllerDirective, selector: "[tableViewController]", outputs: ["viewReady"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: ADCTableComponent, decorators: [{
type: Component,
args: [{ selector: 'adc-table', standalone: true, imports: [
CommonModule,
TableViewControllerDirective,
], changeDetection: ChangeDetectionStrategy.OnPush, template: "\r\n<div [dir]=\"options.direction\">\r\n\r\n <div [classList]=\"titleClassList + ' font-bold text-xl'\" style=\"border-bottom: 1px solid #000; text-align: center;\">\r\n {{title}}\r\n </div>\r\n\r\n <div style=\"max-height: 700px;overflow: scroll;\">\r\n\r\n <div style=\"flex: 1;display: flex;flex-direction: column;\" class=\"adc-table\" tableViewController (viewReady)=\"onViewReady()\">\r\n\r\n <ng-container *ngFor=\"let row of tableRows; let lastRow = last; let rowIndex = index\">\r\n \r\n <div class=\"row\" style=\"position: relative;flex-shrink: 0;\" [attr.sticky]=\"rowIndex == 0\" \r\n [class.sticky]=\"rowIndex == 0\" [class.vertical-stick]=\"rowIndex == 0\" [attr.row-index]=\"rowIndex\">\r\n \r\n <!-- cells - columns -->\r\n <div style=\"display: flex;flex-direction: row;flex-wrap: nowrap;flex: 1;height: 100%;\" cells>\r\n \r\n <ng-container *ngIf=\"showRow\">\r\n \r\n <div style=\"min-width: 100px;display: flex;flex-direction: column;overflow: hidden;\r\n padding: 6px;\" [style.justifyContent]=\"row.verticalAlign\" [style.alignItems]=\"row.horizontalAlign\"\r\n [classList]=\"row.classList + ' column column-border sticky horizontal-stick'\" detail=\"true\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\">\r\n \r\n <span class=\"label\">{{row.prefix}}</span>\r\n <span class=\"label\">{{row.label}}</span>\r\n <span class=\"label\">{{row.suffix}}</span>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n <ng-container *ngFor=\"let column of row.columns; let lastColumn = last; let columnIndex = index\">\r\n <div style=\"min-width: 50px;display: flex;flex-direction: column;overflow: hidden;\r\n white-space: nowrap;text-overflow: ellipsis;padding: 6px;flex: 1;\" [style.justifyContent]=\"column.verticalAlign\" [attr.selectable]=\"column.selectable\"\r\n [classList]=\"column.classList + ' column'\" [attr.columnValue]=\"column.value\" [style.alignItems]=\"column.horizontalAlign\"\r\n [attr.rowValue]=\"row.value\" [attr.rowIndex]=\"rowIndex\" [attr.columnIndex]=\"columnIndex\"\r\n [ngClass]=\"{'column-border': !lastColumn}\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\" detail=\"false\">\r\n \r\n <span class=\"label\">{{column.prefix}}</span>\r\n <span class=\"label\">{{column.label}}</span>\r\n <span class=\"label\">{{column.suffix}}</span>\r\n \r\n </div>\r\n </ng-container>\r\n \r\n </div>\r\n \r\n <!-- events -->\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 1;pointer-events: none;\" events></div>\r\n\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 3;pointer-events: none;\" tooltip></div>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n </div>\r\n\r\n </div>\r\n\r\n</div>\r\n", styles: ["[dir=rtl] .column-border{border-left:1px solid #000}[dir=ltr] .column-border{border-right:1px solid #000}[dir=ltr] .adc-table{transform-origin:left top}[dir=rtl] .adc-table{transform-origin:right top}.adc-table{transition:transform;transition-duration:.2s;transition-timing-function:ease-out;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smooth:always}.row .column:nth-child(2n):not(.today){background-color:#f0f0f0}.row .column:nth-child(odd):not(.today){background-color:#fff}.sticky{position:sticky!important;z-index:9}[dir=ltr] .sticky.horizontal-stick{left:0}[dir=rtl] .sticky.horizontal-stick{right:0}.sticky.vertical-stick{top:0}.today{background-color:#f7ffac}[selectable=true]:not([invalid]):hover{cursor:pointer;box-shadow:inset 0 1px 3px #00000080}[selectable=true][invalid]:hover{cursor:not-allowed}.unavailable{opacity:.5}.holiday{color:red}[dir=rtl]{text-align:right}[dir=ltr]{text-align:left}.label{white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden}[selectable=true][pointed]:not([invalid]):not([selected]){background-color:#c384ff80!important;opacity:1!important}[selectable=true][selected]:not([invalid]){background-color:#c384ff!important;opacity:1!important}[selectable=true][invalid]{background-color:#aaa!important;opacity:1!important}[dir=rtl] .table-event.event-start-day{border-top-right-radius:15px;border-bottom-right-radius:15px}[dir=ltr] .table-event.event-start-day,[dir=rtl] .table-event.event-end-day{border-top-left-radius:15px;border-bottom-left-radius:15px}[dir=ltr] .table-event.event-end-day{border-top-right-radius:15px;border-bottom-right-radius:15px}.table-event{overflow:hidden;position:absolute;display:flex;justify-content:center;align-items:center;font-weight:400;font-size:clamp(10px,14px,16px);line-height:22px;z-index:9;color:#fff;text-wrap:nowrap;pointer-events:fill}.tooltip{position:absolute;background-color:#000c;color:#fff;padding:5px 10px;border-radius:4px;pointer-events:none;white-space:nowrap;z-index:1000;overflow:hidden;max-width:350px;white-space:break-word;text-wrap:wrap;word-break:break-all}\n"] }]
}], propDecorators: { tableRows: [{
type: Input,
args: ['rows']
}], showRow: [{
type: Input,
args: ['showRowDetails']
}], title: [{
type: Input,
args: ['title']
}], titleClassList: [{
type: Input,
args: ['titleClass']
}], eventBuilder: [{
type: Input,
args: ["eventBuilder"]
}], selectionManager: [{
type: Input,
args: ['selectionManager']
}], viewCtrl: [{
type: ViewChild,
args: [TableViewControllerDirective]
}], viewReadyEvent: [{
type: Output,
args: ['viewReady']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRjLXRhYmxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FzYWRpL2FuZ3VsYXItZGF0ZS1jb21wb25lbnRzL2NvcmUvc3JjL2NvbXBvbmVudHMvYWRjLXRhYmxlL2FkYy10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hc2FkaS9hbmd1bGFyLWRhdGUtY29tcG9uZW50cy9jb3JlL3NyYy9jb21wb25lbnRzL2FkYy10YWJsZS9hZGMtdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdJLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBSXBEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlDRztBQVlILE1BQU0sT0FBTyxpQkFBaUI7SUFYOUI7UUFhVyxZQUFPLEdBQUcsTUFBTSxDQUFjLFdBQVcsQ0FBQyxDQUFDO1FBQzNDLGFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFcEM7O1NBRUM7UUFFSCxjQUFTLEdBQW1CLEVBQUUsQ0FBQztRQUU3Qjs7U0FFQztRQUVILFlBQU8sR0FBWSxJQUFJLENBQUM7UUFFdEI7OztTQUdDO1FBRUgsVUFBSyxHQUFXLEVBQUUsQ0FBQztRQUVqQjs7U0FFQztRQUVILG1CQUFjLEdBQVcsRUFBRSxDQUFDO1FBWTVCLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztLQXlCM0M7SUF0QkMsZUFBZTtRQUViLElBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJO1lBQUUsT0FBTztRQUVqQyxJQUFHLElBQUksQ0FBQyxZQUFZLEVBQ3BCO1lBQ0UsSUFBRyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUk7Z0JBQUUsT0FBTztZQUVqQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3BFO1FBRUQsSUFBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQ3hCO1lBQ0UsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDM0M7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUVULElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDN0IsQ0FBQzs4R0EvRFUsaUJBQWlCO2tHQUFqQixpQkFBaUIscVhBb0NqQiw0QkFBNEIsZ0RDakd6QywwK0dBK0RBLG1uRURUSSxZQUFZLDhWQUNaLDRCQUE0Qjs7MkZBTW5CLGlCQUFpQjtrQkFYN0IsU0FBUzsrQkFDRSxXQUFXLGNBQ1QsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osNEJBQTRCO3FCQUM3QixtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTs4QkFXL0MsU0FBUztzQkFEUixLQUFLO3VCQUFDLE1BQU07Z0JBT2IsT0FBTztzQkFETixLQUFLO3VCQUFDLGdCQUFnQjtnQkFRdkIsS0FBSztzQkFESixLQUFLO3VCQUFDLE9BQU87Z0JBT2QsY0FBYztzQkFEYixLQUFLO3VCQUFDLFlBQVk7Z0JBSW5CLFlBQVk7c0JBRFgsS0FBSzt1QkFBQyxjQUFjO2dCQUlyQixnQkFBZ0I7c0JBRGYsS0FBSzt1QkFBQyxrQkFBa0I7Z0JBSWpCLFFBQVE7c0JBRGYsU0FBUzt1QkFBQyw0QkFBNEI7Z0JBSXZDLGNBQWM7c0JBRGIsTUFBTTt1QkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBpbmplY3QsIElucHV0LCBPdXRwdXQsIFJlbmRlcmVyMiwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFEQ0lUYWJsZVJvdywgQURDSU9wdGlvbnMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBUYWJsZVZpZXdDb250cm9sbGVyRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy90YWJsZS12aWV3LWNvbnRyb2xsZXIuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgQURDX09QVElPTlMgfSBmcm9tICcuLi8uLi9pbmplY3Rpb24tdG9rZW4nO1xyXG5pbXBvcnQgeyBUYWJsZVNlbGVjdGlvbiB9IGZyb20gJy4uLy4uL3RhYmxlLXNlbGVjdGlvbic7XHJcbmltcG9ydCB7IEZsYXRFdmVudEJ1aWxkZXIgfSBmcm9tICcuLi8uLi9mbGF0LWV2ZW50LWJ1aWxkZXInO1xyXG5cclxuLyoqXHJcbiAqIEEgcmV1c2FibGUgYW5kIGN1c3RvbWl6YWJsZSB0YWJsZSBjb21wb25lbnQgZm9yIGRpc3BsYXlpbmcgZGF0ZS1yZWxhdGVkIGRhdGEuXHJcbiAqIFRoZSBgYWRjLXRhYmxlYCBjb21wb25lbnQgaXMgZGVzaWduZWQgZm9yIHVzZSB3aXRoaW4gdGhlIEFuZ3VsYXIgRGF0ZSBDb21wb25lbnRzIHBhY2thZ2UuXHJcbiAqIEl0IHN1cHBvcnRzIGZlYXR1cmVzIGxpa2Ugcm93IGFuZCBjb2x1bW4gbGFiZWxzLCBjdXN0b20gY2VsbCBldmVudCBidWlsZGVycywgYW5kIGRhdGUgcmFuZ2Ugc2VsZWN0aW9uLlxyXG4gKlxyXG4gKiBUaGUgY29tcG9uZW50IGFsbG93cyBmb3IgZGlzcGxheWluZyBhIGR5bmFtaWMgdGFibGUgd2l0aCBjdXN0b20gcm93cywgY29sdW1ucywgYW5kIGNlbGxzLlxyXG4gKiBJdCBzdXBwb3J0cyBib3RoIGxlZnQtdG8tcmlnaHQgKGBsdHJgKSBhbmQgcmlnaHQtdG8tbGVmdCAoYHJ0bGApIGxheW91dHMuXHJcbiAqIFxyXG4gKiAjIyMgRmVhdHVyZXNcclxuICogLSBEeW5hbWljYWxseSB1cGRhdGVzIHRoZSB0YWJsZSB2aWV3IHdoZW4gY2VsbCBkYXRhIGNoYW5nZXMuXHJcbiAqIC0gU3VwcG9ydHMgZGF0ZSBmaWx0ZXJpbmcgYW5kIGN1c3RvbSBldmVudCBidWlsZGVycyBmb3IgaGFuZGxpbmcgY2VsbCBldmVudHMuXHJcbiAqIC0gRW1pdHMgYW4gZXZlbnQgd2hlbiBhIGRhdGUgcmFuZ2UgaXMgc2VsZWN0ZWQuXHJcbiAqXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYGh0bWxcclxuICogPGFkYy10YWJsZVxyXG4gKiAgIFtSb3dzXT1cInRhYmxlUm93c1wiXHJcbiAqICAgW0NvbHVtbnNdPVwidGFibGVDb2x1bW5zXCJcclxuICogICBbQ2VsbHNdPVwidGFibGVDZWxsc1wiXHJcbiAqICAgW1RpdGxlXT1cIidNeSBTY2hlZHVsZSdcIlxyXG4gKiAgIFtUaXRsZUNsYXNzXT1cIid0YWJsZS10aXRsZSdcIlxyXG4gKiAgIFtTaG93Um93TGFiZWxzXT1cInRydWVcIlxyXG4gKiAgIFtTaG93Q29sdW1uTGFiZWxzXT1cImZhbHNlXCJcclxuICogICBbRGlyXT1cIidsdHInXCJcclxuICogICBbRGF0ZUZpbHRlcl09XCJjdXN0b21EYXRlRmlsdGVyXCJcclxuICogICBbRXZlbnRCdWlsZGVyXT1cImV2ZW50QnVpbGRlckluc3RhbmNlXCJcclxuICogICAoRGF0ZVJhbmdlU2VsZWN0KT1cIm9uRGF0ZVJhbmdlU2VsZWN0KCRldmVudClcIj5cclxuICogPC9hZGMtdGFibGU+XHJcbiAqIGBgYFxyXG4gKiBcclxuICogQGV4YW1wbGVcclxuICogYGBgdHlwZXNjcmlwdFxyXG4gKiAvLyBJbiB5b3VyIGNvbXBvbmVudCBjbGFzc1xyXG4gKiB0YWJsZVJvd3M6IEFEQ0lUYWJsZVJvd1tdID0gWy4uLl07XHJcbiAqIHRhYmxlQ29sdW1uczogQURDSVRhYmxlQ29sdW1uW10gPSBbLi4uXTtcclxuICogdGFibGVDZWxsczogQURDSVRhYmxlQ2VsbFtdID0gWy4uLl07XHJcbiAqIFxyXG4gKiBvbkRhdGVSYW5nZVNlbGVjdChzZWxlY3RlZENlbGxzOiBBRENJVGFibGVDZWxsW10pIHtcclxuICogICBjb25zb2xlLmxvZygnU2VsZWN0ZWQgY2VsbHM6Jywgc2VsZWN0ZWRDZWxscyk7XHJcbiAqIH1cclxuICogYGBgXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FkYy10YWJsZScsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBUYWJsZVZpZXdDb250cm9sbGVyRGlyZWN0aXZlLFxyXG4gIF0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2FkYy10YWJsZS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vYWRjLXRhYmxlLmNvbXBvbmVudC5jc3MnXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQURDVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0e1xyXG5cclxuICByZWFkb25seSBvcHRpb25zID0gaW5qZWN0PEFEQ0lPcHRpb25zPihBRENfT1BUSU9OUyk7XHJcbiAgcmVhZG9ubHkgcmVuZGVyZXIgPSBpbmplY3QoUmVuZGVyZXIyKTtcclxuXHJcbiAgICAvKipcclxuICAgKiBBbiBhcnJheSBvZiByb3dzIHRvIGRpc3BsYXkgaW4gdGhlIHRhYmxlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgncm93cycpXHJcbiAgdGFibGVSb3dzOiBBRENJVGFibGVSb3dbXSA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAqIGEgYm9vbGVhbiB3aGljaCBkZXRlcm1pbmVzIGlmIHJvdyBkZXRhaWxzIHNob3VsZCBiZSBkaXNwbGF5ZWQgb3Igbm90XHJcbiAgICovXHJcbiAgQElucHV0KCdzaG93Um93RGV0YWlscycpXHJcbiAgc2hvd1JvdzogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBcclxuICAgKiBUaGUgdGl0bGUgZGlzcGxheWVkIGFib3ZlIHRoZSB0YWJsZS5cclxuICAgKi9cclxuICBASW5wdXQoJ3RpdGxlJylcclxuICB0aXRsZTogc3RyaW5nID0gJyc7XHJcblxyXG4gICAgLyoqXHJcbiAgICogQ1NTIGNsYXNzZXMgdG8gYXBwbHkgdG8gdGhlIHRpdGxlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgndGl0bGVDbGFzcycpXHJcbiAgdGl0bGVDbGFzc0xpc3Q6IHN0cmluZyA9ICcnO1xyXG5cclxuICBASW5wdXQoXCJldmVudEJ1aWxkZXJcIilcclxuICBldmVudEJ1aWxkZXIhOiBGbGF0RXZlbnRCdWlsZGVyO1xyXG5cclxuICBASW5wdXQoJ3NlbGVjdGlvbk1hbmFnZXInKVxyXG4gIHNlbGVjdGlvbk1hbmFnZXIhOiBUYWJsZVNlbGVjdGlvbjtcclxuXHJcbiAgQFZpZXdDaGlsZChUYWJsZVZpZXdDb250cm9sbGVyRGlyZWN0aXZlKVxyXG4gIHByaXZhdGUgdmlld0N0cmwhOiBUYWJsZVZpZXdDb250cm9sbGVyRGlyZWN0aXZlO1xyXG5cclxuICBAT3V0cHV0KCd2aWV3UmVhZHknKVxyXG4gIHZpZXdSZWFkeUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQgXHJcbiAge1xyXG4gICAgaWYodGhpcy52aWV3Q3RybCA9PSBudWxsKSByZXR1cm47XHJcblxyXG4gICAgaWYodGhpcy5ldmVudEJ1aWxkZXIpXHJcbiAgICB7XHJcbiAgICAgIGlmKHRoaXMudmlld0N0cmwgPT0gbnVsbCkgcmV0dXJuO1xyXG4gICAgICBcclxuICAgICAgdGhpcy5ldmVudEJ1aWxkZXIuaW5pdCh0aGlzLnJlbmRlcmVyLCB0aGlzLnZpZXdDdHJsLCB0aGlzLm9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmKHRoaXMuc2VsZWN0aW9uTWFuYWdlcilcclxuICAgIHtcclxuICAgICAgdGhpcy5zZWxlY3Rpb25NYW5hZ2VyLmluaXQodGhpcy52aWV3Q3RybCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvblZpZXdSZWFkeSgpOiB2b2lkXHJcbiAge1xyXG4gICAgdGhpcy52aWV3UmVhZHlFdmVudC5lbWl0KCk7XHJcbiAgfVxyXG5cclxufVxyXG4iLCJcclxuPGRpdiBbZGlyXT1cIm9wdGlvbnMuZGlyZWN0aW9uXCI+XHJcblxyXG4gICAgPGRpdiBbY2xhc3NMaXN0XT1cInRpdGxlQ2xhc3NMaXN0ICsgJyBmb250LWJvbGQgdGV4dC14bCdcIiBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMDAwOyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+XHJcbiAgICAgICAge3t0aXRsZX19XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IHN0eWxlPVwibWF4LWhlaWdodDogNzAwcHg7b3ZlcmZsb3c6IHNjcm9sbDtcIj5cclxuXHJcbiAgICAgICAgPGRpdiBzdHlsZT1cImZsZXg6IDE7ZGlzcGxheTogZmxleDtmbGV4LWRpcmVjdGlvbjogY29sdW1uO1wiIGNsYXNzPVwiYWRjLXRhYmxlXCIgdGFibGVWaWV3Q29udHJvbGxlciAodmlld1JlYWR5KT1cIm9uVmlld1JlYWR5KClcIj5cclxuXHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHJvdyBvZiB0YWJsZVJvd3M7IGxldCBsYXN0Um93ID0gbGFzdDsgbGV0IHJvd0luZGV4ID0gaW5kZXhcIj5cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiIHN0eWxlPVwicG9zaXRpb246IHJlbGF0aXZlO2ZsZXgtc2hyaW5rOiAwO1wiIFthdHRyLnN0aWNreV09XCJyb3dJbmRleCA9PSAwXCIgXHJcbiAgICAgICAgICAgICAgICBbY2xhc3Muc3RpY2t5XT1cInJvd0luZGV4ID09IDBcIiBbY2xhc3MudmVydGljYWwtc3RpY2tdPVwicm93SW5kZXggPT0gMFwiIFthdHRyLnJvdy1pbmRleF09XCJyb3dJbmRleFwiPlxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBjZWxscyAtIGNvbHVtbnMgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7ZmxleC1kaXJlY3Rpb246IHJvdztmbGV4LXdyYXA6IG5vd3JhcDtmbGV4OiAxO2hlaWdodDogMTAwJTtcIiBjZWxscz5cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd1Jvd1wiPlxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwibWluLXdpZHRoOiAxMDBweDtkaXNwbGF5OiBmbGV4O2ZsZXgtZGlyZWN0aW9uOiBjb2x1bW47b3ZlcmZsb3c6IGhpZGRlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWRkaW5nOiA2cHg7XCIgW3N0eWxlLmp1c3RpZnlDb250ZW50XT1cInJvdy52ZXJ0aWNhbEFsaWduXCIgW3N0eWxlLmFsaWduSXRlbXNdPVwicm93Lmhvcml6b250YWxBbGlnblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzTGlzdF09XCJyb3cuY2xhc3NMaXN0ICsgJyBjb2x1bW4gY29sdW1uLWJvcmRlciBzdGlja3kgaG9yaXpvbnRhbC1zdGljaydcIiBkZXRhaWw9XCJ0cnVlXCIgW3N0eWxlLmJvcmRlckJvdHRvbV09XCJsYXN0Um93ID8gJ25vbmUnIDogJzFweCBzb2xpZCAjMDAwJ1wiPlxyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj57e3Jvdy5wcmVmaXh9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+e3tyb3cubGFiZWx9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+e3tyb3cuc3VmZml4fX08L3NwYW4+XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHJvdy5jb2x1bW5zOyBsZXQgbGFzdENvbHVtbiA9IGxhc3Q7IGxldCBjb2x1bW5JbmRleCA9IGluZGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwibWluLXdpZHRoOiA1MHB4O2Rpc3BsYXk6IGZsZXg7ZmxleC1kaXJlY3Rpb246IGNvbHVtbjtvdmVyZmxvdzogaGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDt0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztwYWRkaW5nOiA2cHg7ZmxleDogMTtcIiBbc3R5bGUuanVzdGlmeUNvbnRlbnRdPVwiY29sdW1uLnZlcnRpY2FsQWxpZ25cIiBbYXR0ci5zZWxlY3RhYmxlXT1cImNvbHVtbi5zZWxlY3RhYmxlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc0xpc3RdPVwiY29sdW1uLmNsYXNzTGlzdCArICcgY29sdW1uJ1wiIFthdHRyLmNvbHVtblZhbHVlXT1cImNvbHVtbi52YWx1ZVwiIFtzdHlsZS5hbGlnbkl0ZW1zXT1cImNvbHVtbi5ob3Jpem9udGFsQWxpZ25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIucm93VmFsdWVdPVwicm93LnZhbHVlXCIgW2F0dHIucm93SW5kZXhdPVwicm93SW5kZXhcIiBbYXR0ci5jb2x1bW5JbmRleF09XCJjb2x1bW5JbmRleFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2NvbHVtbi1ib3JkZXInOiAhbGFzdENvbHVtbn1cIiBbc3R5bGUuYm9yZGVyQm90dG9tXT1cImxhc3RSb3cgPyAnbm9uZScgOiAnMXB4IHNvbGlkICMwMDAnXCIgZGV0YWlsPVwiZmFsc2VcIj5cclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+e3tjb2x1bW4ucHJlZml4fX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPnt7Y29sdW1uLmxhYmVsfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPnt7Y29sdW1uLnN1ZmZpeH19PC9zcGFuPlxyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICA8IS0tIGV2ZW50cyAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlO2hlaWdodDogMTAwJTt3aWR0aDogMTAwJTtsZWZ0OiAwO3RvcDogMDt6LWluZGV4OiAxO3BvaW50ZXItZXZlbnRzOiBub25lO1wiIGV2ZW50cz48L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTtoZWlnaHQ6IDEwMCU7d2lkdGg6IDEwMCU7bGVmdDogMDt0b3A6IDA7ei1pbmRleDogMztwb2ludGVyLWV2ZW50czogbm9uZTtcIiB0b29sdGlwPjwvZGl2PlxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgIFxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIFxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgIDwvZGl2PlxyXG5cclxuPC9kaXY+XHJcbiJdfQ==